Skip to content

Commit 6fed665

Browse files
authored
Add command line information to Verifier log files for easier IT reproduction (#11366)
When running integration tests, the Verifier dumps output to a log file (usually log.txt). This change adds the full command line used for execution at the beginning of the log file to make it easy to reproduce the test outside the IT environment. The command line information includes: - Full path to Maven executable with all arguments - Environment variables (MAVEN_OPTS, MAVEN_SKIP_RC, custom env vars) - JVM system properties - Working directory - Execution mode (EMBEDDED, FORKED, AUTO) The information is prepended to the log file after Maven execution completes, ensuring it appears at the top without being overwritten by Maven's logging. Example output: # Command line used for this execution: /opt/maven/bin/mvn -l log.txt --errors --batch-mode validate # MAVEN_OPTS=-Duser.home=/path/to/user.home # Working directory: /path/to/test/project # Execution mode: AUTO * Skip command line info in log files when quiet logging is enabled The MavenITmng4387QuietLoggingTest was failing because it expects empty log files when using the -q (quiet) flag, but the command line information was still being added to the log file. This change adds detection for quiet logging (-q or --quiet flags) and skips adding the command line information when quiet logging is enabled, respecting the intent of quiet logging to minimize output. Changes: - Added isQuietLogging() method to detect -q/--quiet flags - Modified execute() to skip command line info when quiet logging is enabled - Maintains full functionality for normal logging while respecting quiet mode
1 parent 36c4d10 commit 6fed665

File tree

1 file changed

+104
-0
lines changed
  • its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it

1 file changed

+104
-0
lines changed

its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,32 @@ public void execute() throws VerificationException {
270270
stdout = new ByteArrayOutputStream();
271271
stderr = new ByteArrayOutputStream();
272272
ExecutorRequest request = builder.stdOut(stdout).stdErr(stderr).build();
273+
274+
// Store the command line to prepend to log file after execution
275+
// Skip adding command line info if quiet logging is enabled (respects -q flag)
276+
String commandLineHeader = null;
277+
if (logFileName != null && !isQuietLogging(args)) {
278+
try {
279+
commandLineHeader = formatCommandLine(request, mode);
280+
} catch (Exception e) {
281+
// Don't fail the execution if we can't format the command line, just log it
282+
System.err.println("Warning: Could not format command line: " + e.getMessage());
283+
}
284+
}
285+
273286
int ret = executorHelper.execute(mode, request);
287+
288+
// After execution, prepend the command line to the log file
289+
if (commandLineHeader != null && Files.exists(logFile)) {
290+
try {
291+
String existingContent = Files.readString(logFile, StandardCharsets.UTF_8);
292+
String newContent = commandLineHeader + existingContent;
293+
Files.writeString(logFile, newContent, StandardCharsets.UTF_8);
294+
} catch (IOException e) {
295+
// Don't fail the execution if we can't write the command line, just log it
296+
System.err.println("Warning: Could not prepend command line to log file: " + e.getMessage());
297+
}
298+
}
274299
if (ret > 0) {
275300
String dump;
276301
try {
@@ -418,6 +443,85 @@ private String getLogContents(Path logFile) {
418443
}
419444
}
420445

446+
/**
447+
* Formats the command line that would be executed for the given ExecutorRequest and mode.
448+
* This provides a human-readable representation of the Maven command for debugging purposes.
449+
*/
450+
private String formatCommandLine(ExecutorRequest request, ExecutorHelper.Mode mode) {
451+
StringBuilder cmdLine = new StringBuilder();
452+
453+
cmdLine.append("# Command line: ");
454+
// Add the Maven executable path
455+
Path mavenExecutable = request.installationDirectory()
456+
.resolve("bin")
457+
.resolve(System.getProperty("os.name").toLowerCase().contains("windows")
458+
? request.command() + ".cmd"
459+
: request.command());
460+
cmdLine.append(mavenExecutable.toString());
461+
462+
// Add MAVEN_ARGS if they would be used (only for forked mode)
463+
if (mode == ExecutorHelper.Mode.FORKED || mode == ExecutorHelper.Mode.AUTO) {
464+
String mavenArgsEnv = System.getenv("MAVEN_ARGS");
465+
if (mavenArgsEnv != null && !mavenArgsEnv.isEmpty()) {
466+
cmdLine.append(" ").append(mavenArgsEnv);
467+
}
468+
}
469+
470+
// Add the arguments
471+
for (String arg : request.arguments()) {
472+
cmdLine.append(" ");
473+
// Quote arguments that contain spaces
474+
if (arg.contains(" ")) {
475+
cmdLine.append("\"").append(arg).append("\"");
476+
} else {
477+
cmdLine.append(arg);
478+
}
479+
}
480+
481+
// Add environment variables that would be set
482+
if (request.environmentVariables().isPresent() && !request.environmentVariables().get().isEmpty()) {
483+
cmdLine.append("\n# Environment variables:");
484+
for (Map.Entry<String, String> entry : request.environmentVariables().get().entrySet()) {
485+
cmdLine.append("\n# ").append(entry.getKey()).append("=").append(entry.getValue());
486+
}
487+
}
488+
489+
// Add JVM arguments that would be set via MAVEN_OPTS
490+
List<String> jvmArgs = new ArrayList<>();
491+
if (!request.userHomeDirectory().equals(ExecutorRequest.getCanonicalPath(Paths.get(System.getProperty("user.home"))))) {
492+
jvmArgs.add("-Duser.home=" + request.userHomeDirectory().toString());
493+
}
494+
if (request.jvmArguments().isPresent()) {
495+
jvmArgs.addAll(request.jvmArguments().get());
496+
}
497+
if (request.jvmSystemProperties().isPresent()) {
498+
jvmArgs.addAll(request.jvmSystemProperties().get().entrySet().stream()
499+
.map(e -> "-D" + e.getKey() + "=" + e.getValue())
500+
.toList());
501+
}
502+
503+
if (!jvmArgs.isEmpty()) {
504+
cmdLine.append("\n# MAVEN_OPTS=").append(String.join(" ", jvmArgs));
505+
}
506+
507+
if (request.skipMavenRc()) {
508+
cmdLine.append("\n# MAVEN_SKIP_RC=true");
509+
}
510+
511+
cmdLine.append("\n# Working directory: ").append(request.cwd().toString());
512+
cmdLine.append("\n# Execution mode: ").append(mode.toString());
513+
514+
cmdLine.append("\n");
515+
return cmdLine.toString();
516+
}
517+
518+
/**
519+
* Checks if quiet logging is enabled by looking for the -q or --quiet flag in the arguments.
520+
*/
521+
private boolean isQuietLogging(List<String> args) {
522+
return args.contains("-q") || args.contains("--quiet");
523+
}
524+
421525
public String getLogFileName() {
422526
return logFileName;
423527
}

0 commit comments

Comments
 (0)