package fr.monlouyan.bakefile; import java.io.File; import java.util.List; import java.util.Date; public class Rule { private String name; private List dependencies; private List commands; private boolean isPhony; public Rule(String name, List dependencies, List commands, boolean isPhony) { this.name = name; this.dependencies = dependencies; this.commands = commands; this.isPhony = isPhony; } public String getName() { return name; } public List getDependencies() { return dependencies; } public List getCommands() { return commands; } public boolean isPhony() { return isPhony; } public boolean isEmpty() { return dependencies.isEmpty() && commands.isEmpty(); } public boolean needsUpdate() { if (BakeCLI.isDebug()){ System.out.println("Debug : Checking if rule " + name + " needs update"); } // Les règles phony sont toujours mises à jour if (isPhony) { if (BakeCLI.isDebug()) { System.out.println("Debug : Rule " + name + " is phony, always needs update"); } return true; } // Skip targets with tilde in path (home directory) to match make behavior if (name.startsWith("~")) { if (BakeCLI.isDebug()) { System.out.println("Debug : Skipping home directory path: " + name); } return false; } // Vérifier d'abord toutes les dépendances avant d'exécuter quoi que ce soit for (String dependency : dependencies) { // Skip dependencies with tilde in path if (dependency.startsWith("~")) { continue; } File depFile = new File(dependency); boolean hasRule = BakeEngine.hasRule(dependency); if (!depFile.exists() && !dependency.isEmpty() && !hasRule) { System.out.println("bake: *** No rule to make target `" + dependency + "', needed by `" + name + "'. Stop."); System.exit(1); } } // Si le fichier cible n'existe pas et qu'il y a des commandes, il doit être mis à jour File targetFile = new File(name); if (!targetFile.exists() && !commands.isEmpty()) { if (BakeCLI.isDebug()) { System.out.println("Debug : Target file " + name + " does not exist and has commands, needs update"); } return true; } // Si la règle n'a pas de commandes, on vérifie seulement si une dépendance doit être mise à jour if (commands.isEmpty()) { for (String dependency : dependencies) { // Skip dependencies with tilde in path if (dependency.startsWith("~")) { continue; } Rule depRule = BakeEngine.getRule(dependency); if (depRule != null && depRule.needsUpdate()) { if (BakeCLI.isDebug()) { System.out.println("Debug : Dependency rule " + dependency + " needs update"); } return true; } } return false; } // Pour les règles avec des commandes, on vérifie aussi les timestamps if (BakeCLI.isDebug()){ System.out.println("Debug : Checking if target file " + name + " exist and is up to date"); } long targetTimestamp = targetFile.exists() ? TimestampManager.getTimestamp(targetFile) : 0; if (BakeCLI.isDebug()) { System.out.println("Debug : Target file '" + name + "' last modified at " + TimestampManager.formatTimestamp(targetTimestamp)); } long currentTime = System.currentTimeMillis(); for (String dependency : dependencies) { // Skip dependencies with tilde in path if (dependency.startsWith("~")) { continue; } File depFile = new File(dependency); if (!depFile.exists()) { continue; } long depTimestamp = TimestampManager.getTimestamp(depFile); // Vérifier si le timestamp de la dépendance est dans le futur if (depTimestamp > currentTime) { // Avertissement similaire à make System.out.println("bake: Warning: File '" + dependency + "' has modification time " + ((depTimestamp - currentTime) / 1000) + " s in the future"); if (BakeCLI.isDebug()) { System.out.println("Debug : Dependency " + dependency + " has a timestamp in the future, needs update"); } return true; } if (BakeCLI.isDebug()) { System.out.println("Debug : Dependency '" + dependency + "' last modified at " + TimestampManager.formatTimestamp(depTimestamp)); } // Si la dépendance est une règle et qu'elle a besoin d'être mise à jour Rule depRule = BakeEngine.getRule(dependency); if (depRule != null && depRule.needsUpdate()) { if (BakeCLI.isDebug()) { System.out.println("Debug : Dependency rule " + dependency + " needs update"); } return true; } // Vérifier les timestamps seulement si le fichier existe if (depTimestamp > targetTimestamp) { if (BakeCLI.isDebug()) { System.out.println("Debug : Dependency " + dependency + " is newer than target file " + name + ", needs update"); } return true; } } return false; } }