Convert paths for MSYS2 and jvm.config placeholders in bin/mvn - #12546
Conversation
gnodet
left a comment
There was a problem hiding this comment.
First review — well-crafted PR! The core changes (MSYS* detection, native basedir split, JLINE_NATIVE_PATH, cygpath safety guard) are all correct and elegant.
Three minor observations:
-
Debug
echowith Windows paths (line 182) — The debug line references$MAVEN_PROJECTBASEDIR_NATIVEbut still usesecho. On dash/Almquist shells,echointerprets backslash sequences, so a Windows path likeC:\foo\barcould corrupt\f/\b. Consider usingprintffor consistency with the PR's own rationale for the echo→printf changes elsewhere:printf '[DEBUG] Parser arguments: %s %s %s\n' "$MAVEN_HOME/bin/JvmConfigParser.java" "$1" "$MAVEN_PROJECTBASEDIR_NATIVE" >&2 -
Same issue on line 198 —
echo "[DEBUG] JvmConfigParser output: $parser_output"now carries Windows paths in$parser_output. Same backslash risk:printf '[DEBUG] JvmConfigParser output: %s\n' "$parser_output" >&2 -
Test not wired into CI —
test-mvn-path-conversion.shis standalone. Future changes could regress path handling without anyone running it. Consider hooking it into the build or adding a note about integration.
Overall the approach is solid — the ordering of operations (converting basedir upfront for JvmConfigParser while keeping POSIX form for shell file access) is well thought out, and the test coverage across CYGWIN/MINGW/MSYS variants is comprehensive.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
The launcher already converted POSIX paths to their native Windows form for Cygwin and MinGW (apacheGH-7958), but a few paths still reached the JVM in a mangled or mixed form: * uname(1) reports MSYS_NT-* for the MSYS2 shell, which did not match the MINGW* pattern, so no conversion happened at all there. The MSYS2 argument conversion then rewrote the POSIX path into the mixed form D:/a/... instead of D:\a\... * ${MAVEN_PROJECTBASEDIR} placeholders in .mvn/jvm.config were expanded with the POSIX path, since JvmConfigParser was invoked before the conversion took place. The base directory is now converted upfront and both representations are kept: the POSIX one to locate jvm.config from the shell, the native one for everything handed over to the JVM. * -Dlibrary.jline.path was built by appending /lib/jline-native to the already converted MAVEN_HOME, producing C:\maven/lib/jline-native. It is now converted on its own. Values holding a path are printed with printf rather than echo, including the debug logging: several POSIX shells (dash and the other Almquist derivatives commonly installed as /bin/sh) expand backslash escapes in echo, so C:\tmp\build was emitted with a tab in place of \t. The conversion is also guarded, so a missing cygpath(1) warns and falls back to POSIX paths rather than passing empty paths to the JVM. A shell test covering all of the above is added and wired into the build through exec-maven-plugin, so mvn verify runs it. It stubs uname, cygpath and java and runs the launcher with a PATH holding nothing but those stubs, so the Windows-only code paths are exercised identically on every platform; keeping the ambient PATH would let the genuine cygpath(1) of an actual Cygwin/MSYS2 installation be picked up and the missing-cygpath fallback would never be exercised there. Related to apacheGH-12537
0db12ba to
033146e
Compare
|
Thanks for the review, @gnodet — all three points addressed in the force-push to 1 & 2 — You were right, and it was a real inconsistency: the PR argued that I went slightly wider than the two lines flagged, since the same flaw applied elsewhere in the script. Every statement that interpolates a path now uses
Three 3 — Test wired into the build Rather than just documenting it, the test now runs under Test coverage Added an assertion on the debug output that reproduces the exact problem you raised — it fails when those statements are reverted to Also fixed a bug in the test harness itself that I'd missed: it appended the ambient Now 29 assertions, verified green under One note on scope: this targets |
gnodet
left a comment
There was a problem hiding this comment.
All three concerns from the previous review are addressed in the new commit:
- ✅ Debug echo with
$MAVEN_PROJECTBASEDIR_NATIVEnow usesprintf - ✅ Debug echo with
$parser_outputnow usesprintf - ✅ Test is now wired into the build via
exec-maven-pluginin a unix-only profile
The architecture is sound — POSIX form for shell file access, Windows-converted form for the JVM. The cygpath safety guard and test coverage (Linux, CYGWIN, MINGW32, MINGW64, MSYS_NT, missing-cygpath fallback, dash/Almquist shell escape handling) are thorough.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
|
The macOS CI failures (all 22 assertion failures in Root cause: On macOS, Fix: Normalize work_dir=`mktemp -d "${TMPDIR:-/tmp}/mvn-path-conversion.XXXXXX"`
work_dir=`cd "$work_dir" && pwd`I've opened #12563 with this one-line fix applied on top of this PR's commit. |
On macOS the $TMPDIR variable ends with a trailing slash, so
mktemp -d "${TMPDIR}/mvn-path-conversion.XXXXXX" produces a path
containing a double slash (e.g. .../T//mvn-path-conversion.XNBzZw).
The pwd(1) calls inside the mvn launcher collapse the double slash,
causing all 22 path assertions to fail on macOS CI runners.
Resolve the work directory through cd/pwd right after creation so
the test's reference paths stay in sync with the launcher output.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The macOS failures were a bug in my test harness (double slash from mktemp when TMPDIR has a trailing slash), not the launcher — which is why only macOS was affected while Linux and Windows passed. @gnodet has fixed it in #12563, which includes my commit 033146e plus the normalisation. Happy to close this in favour of that PR, or to push the one-line fix here if you'd prefer to keep this one — whichever is easier for you. |
gnodet
left a comment
There was a problem hiding this comment.
New commit (afcb7db) looks good — normalizes the temp dir path through cd/pwd after mktemp to avoid the double-slash issue on macOS where $TMPDIR ends with a trailing slash. Clean fix. Prior APPROVE still stands.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
|
@gnodet Please assign appropriate label to PR according to the type of change. |
…vn (#12567) Backport of #12546 to the 3.10.x branch. Adapted for the different script location (src/bin/mvn vs src/assembly/maven/bin/mvn) and the simpler jvm.config handling (no JvmConfigParser on this branch). Key changes: - Detect MSYS2 (MSYS_NT-*) alongside MinGW in uname matching - Guard against missing cygpath(1) — warn and fall back to POSIX paths - Convert all paths (MAVEN_HOME, CLASSWORLDS_JAR, MAVEN_PROJECTBASEDIR, jline-native) for both Cygwin and MinGW/MSYS2, not just Cygwin - Convert jline-native path separately to avoid mixed separators - Use printf instead of echo for values holding paths (avoid backslash expansion in dash/ash) - Add shell test covering Cygwin, MinGW, MSYS2, and missing-cygpath fallback, wired into the build via exec-maven-plugin Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
#12568) Backport of #12546 to the 3.9.x branch. Adapted for the different script location (src/bin/mvn vs src/assembly/maven/bin/mvn), the simpler jvm.config handling (no JvmConfigParser on this branch), and jansi-native instead of jline-native. Key changes: - Detect MSYS2 (MSYS_NT-*) alongside MinGW in uname matching - Guard against missing cygpath(1) — warn and fall back to POSIX paths - Convert all paths (MAVEN_HOME, CLASSWORLDS_JAR, MAVEN_PROJECTBASEDIR, jansi-native) for both Cygwin and MinGW/MSYS2, not just Cygwin - Convert jansi-native path separately to avoid mixed separators - Use printf instead of echo for values holding paths (avoid backslash expansion in dash/ash) - Add shell test covering Cygwin, MinGW, MSYS2, and missing-cygpath fallback, wired into the build via exec-maven-plugin Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The launcher already converted POSIX paths to their native Windows form for Cygwin and MinGW (GH-7958), but a few paths still reached the JVM in a mangled or mixed form:
uname(1) reports MSYS_NT-* for the MSYS2 shell, which did not match the MINGW* pattern, so no conversion happened at all there. The MSYS2 argument conversion then rewrote the POSIX path into the mixed form D:/a/... instead of D:\a...
${MAVEN_PROJECTBASEDIR} placeholders in .mvn/jvm.config were expanded with the POSIX path, since JvmConfigParser was invoked before the conversion took place. The base directory is now converted upfront and both representations are kept: the POSIX one to locate jvm.config from the shell, the native one for everything handed over to the JVM.
-Dlibrary.jline.path was built by appending /lib/jline-native to the already converted MAVEN_HOME, producing C:\maven/lib/jline-native. It is now converted on its own.
Additionally, the output of JvmConfigParser and of the base directory lookup is printed with printf instead of echo. Several POSIX shells (dash and other Almquist derivatives commonly installed as /bin/sh) expand backslash escapes in echo, which corrupts Windows paths, and the conversion is guarded so a missing cygpath(1) warns and falls back to POSIX paths rather than passing empty paths to the JVM.
A shell test covering all of the above is added; it stubs uname, cygpath and java so the Windows-only code paths can be exercised on any platform, and it can be run on any platform or wired into CI.
Fixes GH-12537
Following this checklist to help us incorporate your
contribution quickly and easily:
Note that commits might be squashed by a maintainer on merge.
This may not always be possible but is a best-practice.
mvn verifyto make sure basic checks pass.A more thorough check will be performed on your pull request automatically.
If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.
To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.