Fix #12507: preserve unresolved ${...} in CLI -D values (Maven 3 semantics)#12523
Conversation
MavenITgh12507CliParamNestedInterpolationTest shows that ${user.dir}
and ${project.build.directory} inside a -D-supplied plugin parameter
value are replaced with the empty string at CLI parse time
(BaseParser.populateUserProperties interpolates user-specified
properties with defaultsToEmpty=true against a paths-only callback),
while Maven 3 resolves such expressions at mojo configuration time.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
BaseParser.populateUserProperties interpolated user-specified
properties with defaultsToEmpty=true against a paths-only callback,
silently replacing every expression it could not resolve (system
properties, project.* references) with the empty string. Pass
defaultsToEmpty=false so unresolved placeholders stay literal and are
evaluated later with full session/project context by the plugin
parameter expression evaluator -- restoring Maven 3 semantics for
values like -DaltDeploymentRepository=id::file://${project.build.directory}/x.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The previous assertion expected unknown ${...} in CLI -D values to be
emptied, but that was an unintended side effect of #2480 (which only
meant to add session.topDirectory interpolation). Maven 3 leaves
unknown placeholders literal — update the assertion to match.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Thanks @gnodet — the direction reads right to me. Treating the gh-11978 empty-for-unknown expectation as the anomaly (rather than scoping the parse-time interpolation) restores Maven 3's literal-for-unknown behaviour uniformly, which is what the cross-version repro showed 3.9.16 and 3.10.0-rc-1 both do. Preserving unresolved CI is green here including the ITs. I've gone ahead and set the |
|
Correction on my milestone note above: since this PR targets |
…#12524) * Add failing IT for #12507 (CLI ${...} param wipe) MavenITgh12507CliParamNestedInterpolationTest shows that ${user.dir} and ${project.build.directory} inside a -D-supplied plugin parameter value are replaced with the empty string at CLI parse time (BaseParser.populateUserProperties interpolates user-specified properties with defaultsToEmpty=true against a paths-only callback), while Maven 3 resolves such expressions at mojo configuration time. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix #12507: dont wipe unresolved ${...} in -D values BaseParser.populateUserProperties interpolated user-specified properties with defaultsToEmpty=true against a paths-only callback, silently replacing every expression it could not resolve (system properties, project.* references) with the empty string. Pass defaultsToEmpty=false so unresolved placeholders stay literal and are evaluated later with full session/project context by the plugin parameter expression evaluator -- restoring Maven 3 semantics for values like -DaltDeploymentRepository=id::file://${project.build.directory}/x. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Update gh-11978 IT to expect Maven 3 semantics for unknown placeholders The previous assertion expected unknown ${...} in CLI -D values to be emptied, but that was an unintended side effect of #2480 (which only meant to add session.topDirectory interpolation). Maven 3 leaves unknown placeholders literal — update the assertion to match. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Port gh-12507 IT to the 4.0.x test-harness API The IT was written against master's newer test harness (Path-based Verifier, no-arg AbstractMavenIntegrationTestCase). On maven-4.0.x that API is File/String-based and requires a version-range super() call, so the cherry-picked test did not compile. - Add version gate super("[4.0.0-rc-6,)") — the fix ships in rc-6; the built 4.0.0-SNAPSHOT satisfies the range so the body runs. - extractResources now returns File: use leading "/" + getAbsoluteFile().toPath(). - newVerifier(String) instead of newVerifier(Path). Verified locally against the 4.0.x dist: gh-12507 2/2 + gh-11978 1/1, all run (not skipped). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Gerd Aschemann <ascheman@apache.org> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Guillaume Nodet <gnodet@gmail.com>
Summary
Fixes #12507. Supersedes #12515 (adds the missing test update that unblocks CI).
BaseParser.populateUserProperties()interpolates user-specified-Dvalues at CLI parse time against a callback that only knowssession.topDirectory/session.rootDirectory. Every other expression —${project.build.directory},${user.dir}, etc. — was silently replaced with""because theInterpolator.interpolate(Map, UnaryOperator)convenience overload defaults todefaultsToEmpty=true.This broke common CI patterns like
-DaltDeploymentRepository=id::file://${project.build.directory}/deploy(URL becomesfile:///deploy→ wrong path, no error).Root cause
PR #2480 added early interpolation of
-Dvalues to support${session.topDirectory}, but thedefaultsToEmpty=trueAPI default was not appropriate for this call site — it wiped all expressions the early callback couldn't resolve. Maven 3 left them literal for later evaluation at mojo configuration time.Changes
BaseParser.java: PassdefaultsToEmpty=falseso unresolved placeholders stay literal for later evaluation by the plugin parameter expression evaluator. The${session.topDirectory}/${session.rootDirectory}support from User properties are not interpolated for paths #2480 is unaffected.MavenITgh11978PlaceholderInCliArgTest: Update assertion to expect Maven 3 semantics — unknown${...}preserved as literal, not emptied. The emptying was an unintended side effect of User properties are not interpolated for paths #2480, not a deliberate behavior. The test's primary purpose (launcher doesn't crash on${...}) is unchanged.MavenITgh12507CliParamNestedInterpolationTest: Two cases (${user.dir}and${project.build.directory}in CLI-supplied plugin parameters) — red on current master, green with the fix.Credits
Original fix and IT by @ascheman in #12515. This PR adds the
MavenITgh11978PlaceholderInCliArgTestupdate and rebases onto current master to unblock CI.🤖 Generated with Claude Code