Correction bug

This commit is contained in:
Moncef STITI 2025-03-16 17:00:22 +01:00
parent 072dc2a119
commit c4397daad8
2 changed files with 276 additions and 226 deletions

@ -58,7 +58,7 @@ public class BakefileParser {
* Regex pour détecter les références de variables. * Regex pour détecter les références de variables.
* Format : "${VAR}" ou "$(VAR)" * Format : "${VAR}" ou "$(VAR)"
*/ */
private static final Pattern VARIABLE_REFERENCE = Pattern.compile("\\$\\{(\\w+)\\}|\\$\\((\\w+)\\)"); public static final Pattern VARIABLE_REFERENCE = Pattern.compile("\\$\\{(\\w+)\\}|\\$\\((\\w+)\\)");
/** /**
* Première cible trouvée dans le fichier Bakefile. * Première cible trouvée dans le fichier Bakefile.
@ -68,7 +68,7 @@ public class BakefileParser {
/** /**
* Stocke les variables définies dans le Bakefile. * Stocke les variables définies dans le Bakefile.
*/ */
private Map<String, String> variables = new HashMap<>(); private static Map<String, String> variables = new HashMap<>();
/** /**
* Constructeur de la classe BakefileParser. * Constructeur de la classe BakefileParser.
@ -151,10 +151,13 @@ public class BakefileParser {
while (matcher.find()) { while (matcher.find()) {
String varName = matcher.group(1) != null ? matcher.group(1) : matcher.group(2); String varName = matcher.group(1) != null ? matcher.group(1) : matcher.group(2);
// Modification ici: remplacer par la valeur de la variable ou par une chaîne vide si elle n'existe pas
// Vérifier si la variable existe
String replacement = ""; String replacement = "";
if (variables.containsKey(varName)) { if (variables.containsKey(varName)) {
replacement = variables.get(varName); String varValue = variables.get(varName);
// Ne pas remplacer récursivement ici pour éviter les boucles infinies
replacement = varValue;
} else if (BakeCLI.isDebug()) { } else if (BakeCLI.isDebug()) {
System.out.println("Debug: Variable '" + varName + "' not defined, replacing with empty string"); System.out.println("Debug: Variable '" + varName + "' not defined, replacing with empty string");
} }
@ -179,17 +182,6 @@ public class BakefileParser {
return result.trim(); return result.trim();
} }
/**
* Remplacer les variables dans une liste de chaînes.
* @param items Liste de chaînes à traiter
* @return Liste de chaînes avec les variables remplacées
*/
private List<String> replaceVariablesInList(List<String> items) {
return items.stream()
.map(this::replaceVariables)
.collect(Collectors.toList());
}
/** /**
* Découper les dépendances en une liste de chaînes. * Découper les dépendances en une liste de chaînes.
* @param depStr Chaîne de dépendances * @param depStr Chaîne de dépendances
@ -304,7 +296,6 @@ public List<Rule> parse() {
} }
// Évaluer les variables référencées dans la valeur // Évaluer les variables référencées dans la valeur
varValue = replaceVariables(varValue);
variables.put(varName, varValue); variables.put(varName, varValue);
if (BakeCLI.isDebug()) { if (BakeCLI.isDebug()) {
@ -323,8 +314,8 @@ public List<Rule> parse() {
String resolvedTarget = replaceVariables(target.trim()); String resolvedTarget = replaceVariables(target.trim());
rules.add(new Rule( rules.add(new Rule(
resolvedTarget, resolvedTarget,
replaceVariablesInList(dependencies), dependencies,
replaceVariablesInList(commands), commands,
displayCommands, displayCommands,
phonyTargets.contains(resolvedTarget) phonyTargets.contains(resolvedTarget)
)); ));
@ -388,8 +379,7 @@ public List<Rule> parse() {
Matcher cmdMatcher = COMMAND_PATTERN.matcher(line); Matcher cmdMatcher = COMMAND_PATTERN.matcher(line);
if (cmdMatcher.matches()) { if (cmdMatcher.matches()) {
String cmdPart = cmdMatcher.group(1); String cmdPart = cmdMatcher.group(1);
String cmdWithVars = replaceVariables(cmdPart); displayLine = "\t" + cmdPart; // <= Garder les références aux variables
displayLine = "\t" + cmdWithVars;
} }
} }
List<String> singleLineDisplay = new ArrayList<>(); List<String> singleLineDisplay = new ArrayList<>();
@ -407,8 +397,8 @@ public List<Rule> parse() {
String resolvedTarget = replaceVariables(target.trim()); String resolvedTarget = replaceVariables(target.trim());
rules.add(new Rule( rules.add(new Rule(
resolvedTarget, resolvedTarget,
replaceVariablesInList(dependencies), dependencies,
replaceVariablesInList(commands), commands,
displayCommands, displayCommands,
phonyTargets.contains(resolvedTarget) phonyTargets.contains(resolvedTarget)
)); ));
@ -437,6 +427,56 @@ public List<Rule> parse() {
return rules; return rules;
} }
/**
* Remplacer les variables dans une chaîne (version statique pour l'évaluation tardive).
* @param input Chaîne à traiter
* @return Chaîne avec les variables remplacées
*/
public static String expandVariables(String input) {
if (input == null) return null;
String result = input;
Set<String> processedVars = new HashSet<>();
boolean changed;
do {
changed = false;
Matcher matcher = VARIABLE_REFERENCE.matcher(result);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String varName = matcher.group(1) != null ? matcher.group(1) : matcher.group(2);
// Vérifier si la variable existe
String replacement = "";
if (variables.containsKey(varName)) {
String varValue = variables.get(varName);
// Ne pas remplacer récursivement ici pour éviter les boucles infinies
replacement = varValue;
} else if (BakeCLI.isDebug()) {
System.out.println("Debug: Variable '" + varName + "' not defined, replacing with empty string");
}
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
changed = true;
processedVars.add(varName);
}
matcher.appendTail(sb);
result = sb.toString();
// 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();
}
/** /**
* Récupérer la première cible * Récupérer la première cible
* @return String la première cible * @return String la première cible

@ -114,6 +114,8 @@ public class CommandExecutor {
if (ruleNeedsUpdate) { if (ruleNeedsUpdate) {
try { try {
if(!isCircular && !silent){ if(!isCircular && !silent){
String displayCommand = BakefileParser.expandVariables(command);
// Afficher les lignes formatées avec traitement spécial pour les continuations // Afficher les lignes formatées avec traitement spécial pour les continuations
if (displayLines != null && !displayLines.isEmpty()) { if (displayLines != null && !displayLines.isEmpty()) {
boolean isFirstLine = true; boolean isFirstLine = true;
@ -121,26 +123,34 @@ public class CommandExecutor {
for (String line : displayLines) { for (String line : displayLines) {
if (isFirstLine) { if (isFirstLine) {
// Pour la première ligne, toujours supprimer l'indentation // Pour la première ligne, toujours supprimer l'indentation
String expandedLine = line;
if (line.startsWith("\t")) { if (line.startsWith("\t")) {
System.out.println(line.substring(1)); String content = line.substring(1);
expandedLine = "\t" + BakefileParser.expandVariables(content);
System.out.println(expandedLine.substring(1));
} else { } else {
System.out.println(line); expandedLine = BakefileParser.expandVariables(line);
System.out.println(expandedLine);
} }
isFirstLine = false; isFirstLine = false;
} else { } else {
// Pour les lignes suivantes d'une continuation, conserver l'indentation // Pour les lignes suivantes d'une continuation, conserver l'indentation
System.out.println(line); String expandedLine = BakefileParser.expandVariables(line);
System.out.println(expandedLine);
} }
} }
} else { } else {
// Cas d'une commande simple (une seule ligne) // Cas d'une commande simple (une seule ligne)
if (command.startsWith("\t")) { if (displayCommand.startsWith("\t")) {
System.out.println(command.substring(1)); System.out.println(displayCommand.substring(1));
} else { } else {
System.out.println(command); System.out.println(displayCommand);
} }
} }
} }
actualCommand = BakefileParser.expandVariables(actualCommand);
if (debug) System.out.println("Debug: Executing " + actualCommand); if (debug) System.out.println("Debug: Executing " + actualCommand);
ProcessBuilder pb = new ProcessBuilder("sh", "-c", actualCommand); ProcessBuilder pb = new ProcessBuilder("sh", "-c", actualCommand);
pb.inheritIO(); pb.inheritIO();