Amélioration de la gestion des dépendances circulaires

This commit is contained in:
2025-02-04 19:27:56 +01:00
parent 0af4eb8f1b
commit 0941b5e09e
19 changed files with 125 additions and 36 deletions

View File

@@ -1,26 +1,80 @@
package fr.monlouyan.bakefile;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
public class DependencyResolver {
private boolean debug;
private Map<String, Rule> ruleMap;
public DependencyResolver(boolean debug) {
this.debug = debug;
}
public List<Rule> resolve(List<Rule> allRules, List<String> requestedRules) {
List<Rule> rulesToBuild = new ArrayList<>();
ruleMap = new HashMap<>();
Set<String> builtRules = new HashSet<>(); // Éviter d'ajouter des règles déjà vérifiées
for (Rule rule : allRules) {
if (requestedRules.isEmpty() || requestedRules.contains(rule.getName()) || rule.isPhony()) {
if (debug){
System.out.println("Rule " + rule.getName() + " is requested");
}
rulesToBuild.add(rule);
ruleMap.put(rule.getName(), rule);
}
Set<String> visited = new HashSet<>();
Set<String> stack = new HashSet<>();
for (String ruleName : requestedRules.isEmpty() ? ruleMap.keySet() : requestedRules) {
if (ruleMap.containsKey(ruleName)) {
detectCycle(ruleName, visited, stack);
collectDependencies(ruleName, rulesToBuild, builtRules);
} else if (debug) {
System.out.println("Warning: Rule '" + ruleName + "' not found.");
}
}
return rulesToBuild;
}
}
/**
* Détection des cycles avec DFS
*/
private void detectCycle(String ruleName, Set<String> visited, Set<String> stack) {
if (stack.contains(ruleName)) {
throw new RuntimeException("Dependency cycle detected involving rule: " + ruleName);
}
if (!visited.contains(ruleName)) {
visited.add(ruleName);
stack.add(ruleName);
Rule rule = ruleMap.get(ruleName);
if (rule != null) {
for (String dependency : rule.getDependencies()) {
if (ruleMap.containsKey(dependency)) {
detectCycle(dependency, visited, stack);
}
}
}
stack.remove(ruleName);
}
}
/**
* Collecte récursive des règles à construire en évitant les doublons
*/
private void collectDependencies(String ruleName, List<Rule> rulesToBuild, Set<String> builtRules) {
if (builtRules.contains(ruleName)) {
return; // Évite d'ajouter une règle plusieurs fois
}
Rule rule = ruleMap.get(ruleName);
if (rule != null) {
for (String dependency : rule.getDependencies()) {
if (ruleMap.containsKey(dependency)) {
collectDependencies(dependency, rulesToBuild, builtRules);
}
}
rulesToBuild.add(rule);
builtRules.add(ruleName);
}
}
}