Retour à une version plus stable
This commit is contained in:
parent
b40f095571
commit
4b1558e529
src/fr/monlouyan/bakefile
@ -59,4 +59,4 @@ public class BakeCLI {
|
|||||||
* @return La liste des arguments
|
* @return La liste des arguments
|
||||||
*/
|
*/
|
||||||
public static List<String> getTargets(){ return targets; }
|
public static List<String> getTargets(){ return targets; }
|
||||||
}
|
}
|
@ -3,7 +3,6 @@ package fr.monlouyan.bakefile;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moteur principal de l'application Bake.
|
* Moteur principal de l'application Bake.
|
||||||
@ -86,12 +85,4 @@ public class BakeEngine {
|
|||||||
executor.execute(rule);
|
executor.execute(rule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Récupère les noms de toutes les règles.
|
|
||||||
* @return Un ensemble contenant les noms de toutes les règles
|
|
||||||
*/
|
|
||||||
public static Set<String> getAllRuleNames() {
|
|
||||||
return ruleMap.keySet();
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -26,10 +26,9 @@ public class BakefileParser {
|
|||||||
/**
|
/**
|
||||||
* Regex pour détecter les targets et leurs dépendances.
|
* Regex pour détecter les targets et leurs dépendances.
|
||||||
* Format : "nom1 nom2 nom3 : dépendance1 dépendance2"
|
* Format : "nom1 nom2 nom3 : dépendance1 dépendance2"
|
||||||
* La nouvelle regex assure que la ligne ne commence pas par une tabulation
|
* La nouvelle regex gère plusieurs cibles séparées par des espaces
|
||||||
* et vérifie que le premier caractère non-espace n'est pas un symbole de commentaire
|
|
||||||
*/
|
*/
|
||||||
private static final Pattern TARGET_PATTERN = Pattern.compile("^([^\\t:#][^:#]+?)\\s*:\\s*([^#]*?)\\s*(?:#.*)?$");
|
private static final Pattern TARGET_PATTERN = Pattern.compile("^([^:#]+?)\\s*:\\s*([^#]*?)\\s*(?:#.*)?$");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regex pour détecter les lignes de commande associées à une target.
|
* Regex pour détecter les lignes de commande associées à une target.
|
||||||
@ -87,71 +86,68 @@ public class BakefileParser {
|
|||||||
* @return La ligne combinée
|
* @return La ligne combinée
|
||||||
*/
|
*/
|
||||||
private String handleContinuationLines(List<String> lines, int startIndex) {
|
private String handleContinuationLines(List<String> lines, int startIndex) {
|
||||||
StringBuilder combinedLine = new StringBuilder();
|
StringBuilder combinedLine = new StringBuilder();
|
||||||
int i = startIndex;
|
int i = startIndex;
|
||||||
|
|
||||||
while (i < lines.size()) {
|
while (i < lines.size()) {
|
||||||
String line = lines.get(i);
|
String line = lines.get(i);
|
||||||
Matcher contMatcher = CONTINUATION_PATTERN.matcher(line);
|
Matcher contMatcher = CONTINUATION_PATTERN.matcher(line);
|
||||||
|
|
||||||
if (contMatcher.matches()) {
|
if (contMatcher.matches()) {
|
||||||
// Ajouter la ligne sans le backslash mais conserver le contenu entier
|
// Ajouter la ligne sans le backslash
|
||||||
// Ne pas ajouter d'espace après certains opérateurs comme &&
|
combinedLine.append(contMatcher.group(1).trim()).append(" ");
|
||||||
String content = contMatcher.group(1);
|
i++;
|
||||||
combinedLine.append(content);
|
} else {
|
||||||
|
// Ajouter la dernière ligne et sortir
|
||||||
// Si la ligne ne se termine pas déjà par un opérateur tel que &&, ajouter un espace
|
combinedLine.append(line.trim());
|
||||||
if (!content.trim().endsWith("&&") && !content.trim().endsWith("|") &&
|
break;
|
||||||
!content.trim().endsWith(";")) {
|
}
|
||||||
combinedLine.append(" ");
|
}
|
||||||
} else {
|
|
||||||
// Si elle se termine par &&, |, ou ;, ajouter juste un espace après
|
return combinedLine.toString();
|
||||||
combinedLine.append(" ");
|
}
|
||||||
}
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
// Ajouter la dernière ligne et sortir
|
|
||||||
combinedLine.append(line.trim());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return combinedLine.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remplacer les variables dans une chaîne.
|
* Remplacer les variables dans une chaîne.
|
||||||
* Cette méthode remplace toutes les références de variables (${VAR} ou $(VAR))
|
|
||||||
* par leur valeur. Si une variable n'est pas définie, elle est remplacée par une chaîne vide.
|
|
||||||
*
|
|
||||||
* @param input Chaîne à traiter
|
* @param input Chaîne à traiter
|
||||||
* @return Chaîne avec les variables remplacées
|
* @return Chaîne avec les variables remplacées
|
||||||
*/
|
*/
|
||||||
private String replaceVariables(String input) {
|
private String replaceVariables(String input) {
|
||||||
if (input == null) return null;
|
if (input == null) return null;
|
||||||
|
|
||||||
String result = input;
|
String result = input;
|
||||||
|
Set<String> processedVars = new HashSet<>();
|
||||||
// Détecter et remplacer toutes les occurrences de variables
|
boolean changed;
|
||||||
Matcher matcher = VARIABLE_REFERENCE.matcher(result);
|
|
||||||
StringBuffer sb = new StringBuffer();
|
do {
|
||||||
|
changed = false;
|
||||||
while (matcher.find()) {
|
Matcher matcher = VARIABLE_REFERENCE.matcher(result);
|
||||||
String varName = matcher.group(1) != null ? matcher.group(1) : matcher.group(2);
|
StringBuffer sb = new StringBuffer();
|
||||||
// Remplacer par la valeur de la variable si elle existe, sinon par une chaîne vide
|
|
||||||
String replacement = variables.containsKey(varName) ? variables.get(varName) : "";
|
while (matcher.find()) {
|
||||||
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
|
String varName = matcher.group(1) != null ? matcher.group(1) : matcher.group(2);
|
||||||
}
|
if (!processedVars.contains(varName) && variables.containsKey(varName)) {
|
||||||
matcher.appendTail(sb);
|
String replacement = variables.get(varName);
|
||||||
result = sb.toString();
|
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
|
||||||
|
changed = true;
|
||||||
// Vérifier les références imbriquées de variables et continuer à remplacer si nécessaire
|
processedVars.add(varName);
|
||||||
if (VARIABLE_REFERENCE.matcher(result).find()) {
|
}
|
||||||
result = replaceVariables(result); // Appel récursif pour gérer les variables imbriquées
|
}
|
||||||
}
|
matcher.appendTail(sb);
|
||||||
|
result = sb.toString();
|
||||||
return result.trim();
|
|
||||||
}
|
// Si aucun changement n'a été fait dans ce passage, arrêter
|
||||||
|
if (!changed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Réinitialiser processedVars pour le prochain passage si nécessaire
|
||||||
|
processedVars.clear();
|
||||||
|
|
||||||
|
} while (changed);
|
||||||
|
|
||||||
|
return result.trim();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remplacer les variables dans une liste de chaînes.
|
* Remplacer les variables dans une liste de chaînes.
|
||||||
@ -205,10 +201,9 @@ public class BakefileParser {
|
|||||||
public List<Rule> parse() {
|
public List<Rule> parse() {
|
||||||
List<Rule> rules = new ArrayList<>();
|
List<Rule> rules = new ArrayList<>();
|
||||||
Set<String> phonyTargets = new HashSet<>();
|
Set<String> phonyTargets = new HashSet<>();
|
||||||
List<String> allTargetNames = new ArrayList<>(); // Pour suivre l'ordre des cibles
|
|
||||||
|
|
||||||
if (!Files.exists(Paths.get(filename))) {
|
if (!Files.exists(Paths.get(filename))) {
|
||||||
System.out.println("*** No targets specified and no bakefile found. Stop.");
|
System.out.println("*** No targets specified and no makefile found. Stop.");
|
||||||
System.exit(2);
|
System.exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,18 +213,6 @@ public class BakefileParser {
|
|||||||
List<String> dependencies = new ArrayList<>();
|
List<String> dependencies = new ArrayList<>();
|
||||||
List<String> commands = new ArrayList<>();
|
List<String> commands = new ArrayList<>();
|
||||||
|
|
||||||
// Première passe : collecter toutes les cibles PHONY
|
|
||||||
for (String line : lines) {
|
|
||||||
if (line.trim().isEmpty()) continue;
|
|
||||||
|
|
||||||
Matcher phonyMatcher = PHONY_PATTERN.matcher(line);
|
|
||||||
if (phonyMatcher.matches()) {
|
|
||||||
String[] phonies = phonyMatcher.group(1).trim().split("\\s+");
|
|
||||||
Collections.addAll(phonyTargets, phonies);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deuxième passe : analyser les règles en tenant compte des PHONY
|
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
String line = lines.get(i);
|
String line = lines.get(i);
|
||||||
|
|
||||||
@ -260,7 +243,8 @@ public class BakefileParser {
|
|||||||
Matcher phonyMatcher = PHONY_PATTERN.matcher(line);
|
Matcher phonyMatcher = PHONY_PATTERN.matcher(line);
|
||||||
|
|
||||||
if (phonyMatcher.matches()) {
|
if (phonyMatcher.matches()) {
|
||||||
// Déjà traité dans la première passe
|
String[] phonies = phonyMatcher.group(1).trim().split("\\s+");
|
||||||
|
Collections.addAll(phonyTargets, phonies);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,8 +267,9 @@ public class BakefileParser {
|
|||||||
phonyTargets.contains(resolvedTarget)
|
phonyTargets.contains(resolvedTarget)
|
||||||
));
|
));
|
||||||
|
|
||||||
// Enregistrer le nom de la cible pour suivre l'ordre
|
if (firstTarget == null && !phonyTargets.contains(resolvedTarget)) {
|
||||||
allTargetNames.add(resolvedTarget);
|
firstTarget = resolvedTarget;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,32 +294,15 @@ public class BakefileParser {
|
|||||||
phonyTargets.contains(resolvedTarget)
|
phonyTargets.contains(resolvedTarget)
|
||||||
));
|
));
|
||||||
|
|
||||||
// Enregistrer le nom de la cible pour suivre l'ordre
|
if (firstTarget == null && !phonyTargets.contains(resolvedTarget)) {
|
||||||
allTargetNames.add(resolvedTarget);
|
firstTarget = resolvedTarget;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Définir la première cible (similaire à Make)
|
|
||||||
// Make prend la première cible non-PHONY, ou la première cible si toutes sont PHONY
|
|
||||||
if (!allTargetNames.isEmpty()) {
|
|
||||||
// Chercher d'abord une cible non-PHONY dans l'ordre d'apparition
|
|
||||||
for (String targetName : allTargetNames) {
|
|
||||||
if (!phonyTargets.contains(targetName)) {
|
|
||||||
firstTarget = targetName;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si toutes les cibles sont PHONY, prendre simplement la première
|
|
||||||
if (firstTarget == null) {
|
|
||||||
firstTarget = allTargetNames.get(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,14 +79,6 @@ public class DependencyResolver {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignorer les options de compilation qui pourraient avoir été mal interprétées comme des règles
|
|
||||||
if (ruleName.startsWith("-") || ruleName.contains(":")) {
|
|
||||||
if (debug) {
|
|
||||||
System.out.println("Debug: Skipping compiler option: " + ruleName);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Rule rule = ruleMap.get(ruleName);
|
Rule rule = ruleMap.get(ruleName);
|
||||||
if (rule != null) {
|
if (rule != null) {
|
||||||
rulesToBuild.add(rule);
|
rulesToBuild.add(rule);
|
||||||
@ -116,12 +108,6 @@ public class DependencyResolver {
|
|||||||
if (dep.startsWith("~")) {
|
if (dep.startsWith("~")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignorer les options de compilation qui pourraient avoir un ':' dedans
|
|
||||||
if (dep.startsWith("-") || dep.contains(":")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
topologicalSort(dep, processed, buildOrder);
|
topologicalSort(dep, processed, buildOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,11 +148,6 @@ public class DependencyResolver {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignorer les options de compilation qui pourraient avoir un ':' dedans
|
|
||||||
if (dependency.startsWith("-") || dependency.contains(":")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ruleMap.containsKey(dependency)) {
|
if (ruleMap.containsKey(dependency)) {
|
||||||
detectCycle(dependency, visited, stack, ruleName);
|
detectCycle(dependency, visited, stack, ruleName);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package fr.monlouyan.bakefile;
|
package fr.monlouyan.bakefile;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,171 +73,129 @@ public class Rule {
|
|||||||
* Vérifie si la règle doit être mise à jour.
|
* Vérifie si la règle doit être mise à jour.
|
||||||
* @return true si la règle doit être mise à jour, false sinon
|
* @return true si la règle doit être mise à jour, false sinon
|
||||||
*/
|
*/
|
||||||
public boolean needsUpdate() {
|
public boolean needsUpdate() {
|
||||||
if (BakeCLI.isDebug()){
|
if (BakeCLI.isDebug()){
|
||||||
System.out.println("Debug : Checking if rule " + name + " needs update");
|
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(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Les règles phony sont toujours mises à jour
|
// Si le fichier cible n'existe pas et qu'il y a des commandes, il doit être mis à jour
|
||||||
if (isPhony) {
|
File targetFile = new File(name);
|
||||||
if (BakeCLI.isDebug()) {
|
if (!targetFile.exists() && !commands.isEmpty()) {
|
||||||
System.out.println("Debug : Rule " + name + " is phony, always needs update");
|
if (BakeCLI.isDebug()) {
|
||||||
}
|
System.out.println("Debug : Target file " + name + " does not exist and has commands, needs update");
|
||||||
return true;
|
}
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
// Skip targets with tilde in path (home directory) to match make behavior
|
|
||||||
if (name.startsWith("~")) {
|
// Si la règle n'a pas de commandes, on vérifie seulement si une dépendance doit être mise à jour
|
||||||
if (BakeCLI.isDebug()) {
|
if (commands.isEmpty()) {
|
||||||
System.out.println("Debug : Skipping home directory path: " + name);
|
for (String dependency : dependencies) {
|
||||||
}
|
// Skip dependencies with tilde in path
|
||||||
return false;
|
if (dependency.startsWith("~")) {
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
// Si le fichier cible n'existe pas et qu'il y a des commandes, il doit être mis à jour
|
|
||||||
File targetFile = new File(name);
|
Rule depRule = BakeEngine.getRule(dependency);
|
||||||
if (!targetFile.exists() && !commands.isEmpty()) {
|
if (depRule != null && depRule.needsUpdate()) {
|
||||||
if (BakeCLI.isDebug()) {
|
if (BakeCLI.isDebug()) {
|
||||||
System.out.println("Debug : Target file " + name + " does not exist and has commands, needs update");
|
System.out.println("Debug : Dependency rule " + dependency + " needs update");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Vérifier d'abord toutes les dépendances avant d'exécuter quoi que ce soit
|
return false;
|
||||||
for (String dependency : dependencies) {
|
}
|
||||||
// Skip dependencies with tilde in path
|
|
||||||
if (dependency.startsWith("~")) {
|
// Pour les règles avec des commandes, on vérifie aussi les timestamps
|
||||||
continue;
|
if (BakeCLI.isDebug()){
|
||||||
}
|
System.out.println("Debug : Checking if target file " + name + " exist and is up to date");
|
||||||
|
}
|
||||||
// Ignorer les options de compilation qui pourraient avoir un ':' dedans
|
|
||||||
if (dependency.startsWith("-") || dependency.contains(":")) {
|
long targetTimestamp = targetFile.exists() ? TimestampManager.getTimestamp(targetFile) : 0;
|
||||||
continue;
|
|
||||||
}
|
if (BakeCLI.isDebug()) {
|
||||||
|
System.out.println("Debug : Target file '" + name + "' last modified at " + TimestampManager.formatTimestamp(targetTimestamp));
|
||||||
File depFile = new File(dependency);
|
}
|
||||||
boolean hasRule = BakeEngine.hasRule(dependency);
|
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
if (!depFile.exists() && !dependency.isEmpty() && !hasRule) {
|
|
||||||
// Vérifier si on est en situation de dépendance circulaire déjà traitée
|
for (String dependency : dependencies) {
|
||||||
boolean isPartOfCircularDependency = false;
|
// Skip dependencies with tilde in path
|
||||||
|
if (dependency.startsWith("~")) {
|
||||||
// Vérifier si cette dépendance est impliquée dans une relation circulaire
|
continue;
|
||||||
for (Rule rule : getAllRules()) {
|
}
|
||||||
if (rule.getName().equals(dependency) && rule.getDependencies().contains(name)) {
|
|
||||||
if (BakeCLI.isDebug()) {
|
File depFile = new File(dependency);
|
||||||
System.out.println("Debug: Found circular dependency between " + name + " and " + dependency);
|
if (!depFile.exists()) {
|
||||||
}
|
continue;
|
||||||
isPartOfCircularDependency = true;
|
}
|
||||||
break;
|
|
||||||
}
|
long depTimestamp = TimestampManager.getTimestamp(depFile);
|
||||||
}
|
|
||||||
|
// Vérifier si le timestamp de la dépendance est dans le futur
|
||||||
if (isPartOfCircularDependency) {
|
if (depTimestamp > currentTime) {
|
||||||
if (BakeCLI.isDebug()) {
|
// Avertissement similaire à make
|
||||||
System.out.println("Debug: Ignoring circular dependency: " + dependency);
|
System.out.println("bake: Warning: File '" + dependency + "' has modification time "
|
||||||
}
|
+ ((depTimestamp - currentTime) / 1000) + " s in the future");
|
||||||
continue;
|
if (BakeCLI.isDebug()) {
|
||||||
}
|
System.out.println("Debug : Dependency " + dependency + " has a timestamp in the future, needs update");
|
||||||
|
}
|
||||||
System.out.println("bake: *** No rule to make target `" + dependency + "', needed by `" + name + "'. Stop.");
|
return true;
|
||||||
System.exit(2);
|
}
|
||||||
}
|
|
||||||
}
|
if (BakeCLI.isDebug()) {
|
||||||
|
System.out.println("Debug : Dependency '" + dependency + "' last modified at " + TimestampManager.formatTimestamp(depTimestamp));
|
||||||
// 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) {
|
// Si la dépendance est une règle et qu'elle a besoin d'être mise à jour
|
||||||
// Skip dependencies with tilde in path or compiler options
|
Rule depRule = BakeEngine.getRule(dependency);
|
||||||
if (dependency.startsWith("~") || dependency.startsWith("-") || dependency.contains(":")) {
|
if (depRule != null && depRule.needsUpdate()) {
|
||||||
continue;
|
if (BakeCLI.isDebug()) {
|
||||||
}
|
System.out.println("Debug : Dependency rule " + dependency + " needs update");
|
||||||
|
}
|
||||||
Rule depRule = BakeEngine.getRule(dependency);
|
return true;
|
||||||
if (depRule != null && depRule.needsUpdate()) {
|
}
|
||||||
if (BakeCLI.isDebug()) {
|
|
||||||
System.out.println("Debug : Dependency rule " + dependency + " needs update");
|
// Vérifier les timestamps seulement si le fichier existe
|
||||||
}
|
if (depTimestamp > targetTimestamp) {
|
||||||
return true;
|
if (BakeCLI.isDebug()) {
|
||||||
}
|
System.out.println("Debug : Dependency " + dependency + " is newer than target file " + name + ", needs update");
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Pour les règles avec des commandes, on vérifie aussi les timestamps
|
|
||||||
if (BakeCLI.isDebug()){
|
return false;
|
||||||
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 or compiler options
|
|
||||||
if (dependency.startsWith("~") || dependency.startsWith("-") || dependency.contains(":")) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Permet de récupérer la liste de toutes les règles
|
|
||||||
* @return La liste de toutes les règles
|
|
||||||
*/
|
|
||||||
private List<Rule> getAllRules() {
|
|
||||||
List<Rule> allRules = new ArrayList<>();
|
|
||||||
for (String ruleName : BakeEngine.getAllRuleNames()) {
|
|
||||||
Rule rule = BakeEngine.getRule(ruleName);
|
|
||||||
if (rule != null) {
|
|
||||||
allRules.add(rule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return allRules;
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user