package fr.monlouyan.bakefile; import java.util.*; public class DependencyResolver { private boolean debug; private Map ruleMap; private boolean isCircular; public DependencyResolver(boolean debug) { this.debug = debug; this.isCircular = false; } public List resolve(List allRules, List requestedRules) { List rulesToBuild = new ArrayList<>(); ruleMap = new HashMap<>(); // Construire la map des règles for (Rule rule : allRules) { ruleMap.put(rule.getName(), rule); } // Premier passage : détection et suppression des cycles Set visited = new HashSet<>(); Set stack = new HashSet<>(); List targetRules = requestedRules.isEmpty() ? Collections.singletonList(BakefileParser.getFirstTarget()) : requestedRules; for (String ruleName : targetRules) { if (ruleMap.containsKey(ruleName)) { detectCycle(ruleName, visited, stack, ruleName); } else if (debug) { System.out.println("Warning: Rule '" + ruleName + "' not found."); } } // Deuxième passage : collecte des dépendances dans l'ordre Set processed = new HashSet<>(); List buildOrder = new ArrayList<>(); for (String ruleName : targetRules) { topologicalSort(ruleName, processed, buildOrder); } // Construire la liste finale des règles dans l'ordre for (String ruleName : buildOrder) { Rule rule = ruleMap.get(ruleName); if (rule != null) { rulesToBuild.add(rule); } } return rulesToBuild; } private void topologicalSort(String ruleName, Set processed, List buildOrder) { if (!ruleMap.containsKey(ruleName) || processed.contains(ruleName)) { return; } processed.add(ruleName); Rule rule = ruleMap.get(ruleName); // D'abord traiter les dépendances for (String dep : rule.getDependencies()) { topologicalSort(dep, processed, buildOrder); } // Puis ajouter la règle courante buildOrder.add(ruleName); } // La méthode detectCycle reste inchangée private void detectCycle(String ruleName, Set visited, Set stack, String parent) { if (stack.contains(ruleName)) { if (parent != null) { System.out.println("bake: Circular " + parent + " <- " + ruleName + " dependency dropped."); this.isCircular = true; Rule parentRule = ruleMap.get(parent); if (parentRule != null) { parentRule.getDependencies().remove(ruleName); } } return; } if (!visited.contains(ruleName)) { visited.add(ruleName); stack.add(ruleName); Rule rule = ruleMap.get(ruleName); if (rule != null) { List dependenciesCopy = new ArrayList<>(rule.getDependencies()); for (String dependency : dependenciesCopy) { if (ruleMap.containsKey(dependency)) { detectCycle(dependency, visited, stack, ruleName); } } } stack.remove(ruleName); } } public boolean isCircular() { return isCircular; } }