gnodet-bot commented on code in PR #13542:
URL: https://github.com/apache/maven/pull/13542#discussion_r4286117974
##########
api/maven-api-core/src/main/java/org/apache/maven/api/Session.java:
##########
@@ -46,6 +46,16 @@
@ThreadSafe
public interface Session extends ProtoSession {
+ /**
+ * Returns the environment context of this build: the flags, properties,
and
+ * platform settings that were active when the session started.
+ *
+ * @return the build environment, never {@code null}
+ * @since 4.1.0
+ */
+ @Nonnull
Review Comment:
⛔ **Breaking API change:** `buildEnvironment()` is added as a non-default
method to the `Session` interface. Any class outside this repository that
implements `Session` (e.g. test stubs, plugin test frameworks, embedders) will
fail to compile or throw `AbstractMethodError` at runtime.
Either add a `default` implementation (even one that throws
`UnsupportedOperationException` with a clear message) or, better, align with
the pattern used elsewhere in the v4 API where new capabilities are added via
narrower, more focused interfaces:
```suggestion
@Nonnull
default BuildEnvironment buildEnvironment() {
throw new UnsupportedOperationException(
"buildEnvironment() is not supported by this Session
implementation");
}
```
##########
impl/maven-core/src/main/java/org/apache/maven/internal/build/DefaultBuildEnvironment.java:
##########
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.internal.build;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.apache.maven.api.BuildEnvironment;
+import org.apache.maven.execution.MavenSession;
+
+/**
+ * Internal immutable implementation of {@link BuildEnvironment}.
+ *
+ * @param goals requested goals/phases
+ * @param userProperties user properties with sensitive values redacted
+ * @param systemInfo curated system properties for reproducibility
+ * @param localRepository local repository path
+ * @param activeProfiles explicitly activated profiles
+ * @param selectedProjects projects selected via {@code -pl}
+ * @param resumeFrom resume-from selector, or {@code null}
+ * @param reactorFailureBehavior reactor failure behavior
+ * @param offline whether offline mode was active
+ * @param updateSnapshots whether snapshot updates were forced
+ * @param noTransferProgress whether transfer progress was suppressed
+ * @param batchMode whether batch mode was active
+ * @param threads degree of concurrency
+ */
+public record DefaultBuildEnvironment(
+ List<String> goals,
+ Map<String, String> userProperties,
+ Map<String, String> systemInfo,
+ String localRepository,
+ List<String> activeProfiles,
+ List<String> selectedProjects,
+ String resumeFrom,
+ String reactorFailureBehavior,
+ boolean offline,
+ boolean updateSnapshots,
+ boolean noTransferProgress,
+ boolean batchMode,
+ int threads)
+ implements BuildEnvironment {
+
+ private static final Set<String> SENSITIVE_KEY_FRAGMENTS =
+ Set.of("password", "passwd", "secret", "token", "apikey",
"api_key", "credential", "passphrase");
+
+ @Override
+ public List<String> goals() {
+ return List.copyOf(goals);
+ }
+
+ @Override
+ public Map<String, String> userProperties() {
+ return Map.copyOf(userProperties);
+ }
+
+ @Override
+ public Map<String, String> systemInfo() {
+ return Map.copyOf(systemInfo);
+ }
+
+ @Override
+ public List<String> activeProfiles() {
+ return List.copyOf(activeProfiles);
+ }
+
+ @Override
+ public List<String> selectedProjects() {
+ return List.copyOf(selectedProjects);
+ }
Review Comment:
⚠️ **Partially redundant defensive copies in accessors:** For a `record`,
Java already generates accessor methods that return the component value
directly. These `@Override` methods wrap the return in
`List.copyOf()`/`Map.copyOf()` to enforce immutability — which is correct — but
the `from()` factory already passes immutable copies for `goals`,
`activeProfiles`, and `selectedProjects` (`List.copyOf(...)`).
For `userProperties`, the factory builds a mutable `LinkedHashMap` and
passes it directly, so `Map.copyOf()` in the accessor is necessary there. But
for `systemInfo`, the factory builds a `TreeMap` (mutable) so that copy is also
necessary.
The cleaner fix is to make the record components themselves unmodifiable at
construction time and drop the accessor overrides entirely, letting the record
use its auto-generated accessors:
```java
// In from(): ensure all collections passed to the constructor are already
immutable
return new DefaultBuildEnvironment(
goals, // already List.copyOf
Map.copyOf(userProps), // make immutable here
Map.copyOf(sysInfo), // make immutable here
localRepo,
activeProfiles, // already List.copyOf
selectedProjects, // already List.copyOf
...);
// Then remove the @Override accessor methods — the record provides them for
free.
```
This also removes the per-call allocation overhead.
##########
impl/maven-testing/src/main/java/org/apache/maven/testing/plugin/stubs/SessionStub.java:
##########
@@ -107,6 +108,11 @@ public Settings getSettings() {
return settings;
}
+ @Override
+ public BuildEnvironment buildEnvironment() {
Review Comment:
⛔ **`@Nonnull` contract violation:** `Session.buildEnvironment()` is
annotated `@Nonnull`, but this stub returns `null`. Any code that calls
`session.buildEnvironment()` in a test using this stub and relies on the
non-null contract (which is the whole point of `@Nonnull`) will NPE.
```suggestion
return BuildEnvironment.empty(); // or a minimal stub implementation
```
If there is no `empty()` factory yet, a reasonable stub:
```java
return new DefaultBuildEnvironment(
List.of(), Map.of(), Map.of(), "", List.of(), List.of(),
null, "FAIL_FAST", false, false, false, false, 1);
```
##########
impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java:
##########
@@ -172,6 +175,19 @@ public int getDegreeOfConcurrency() {
return getMavenSession().getRequest().getDegreeOfConcurrency();
}
+ @Nonnull
+ @Override
+ public BuildEnvironment buildEnvironment() {
+ if (buildEnvironment == null) {
+ synchronized (this) {
Review Comment:
⚠️ **`synchronized(this)` anti-pattern in DCL:** Using the instance itself
as the monitor allows external code to also lock on `this`, which can introduce
deadlocks in unexpected ways. Standard practice is a private final lock object:
```suggestion
synchronized (buildEnvironmentLock) {
```
(And add `private final Object buildEnvironmentLock = new Object();` as a
field alongside `private volatile BuildEnvironment buildEnvironment;`.)
##########
api/maven-api-core/src/main/java/org/apache/maven/api/BuildEnvironment.java:
##########
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Immutable;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * Describes the invocation context of a Maven build: the flags, properties,
and
+ * environment settings that were active when the build started.
+ *
+ * <p>An instance is available via {@link Session#buildEnvironment()} during
the build,
+ * and is also recorded in the structured build report for post-mortem
analysis and
+ * reproducibility.
+ *
+ * <h2>What is captured</h2>
+ * <ul>
+ * <li>Goals and lifecycle phases requested ({@link #goals()})</li>
+ * <li>User properties passed via {@code -Dkey=value} ({@link
#userProperties()}),
+ * with sensitive keys redacted — see {@link #userProperties()} for the
denylist</li>
+ * <li>A curated subset of system properties relevant to reproducibility
+ * ({@link #systemInfo()}): OS name/arch/version, Java vendor and VM
name/version,
+ * Maven home, and available processors</li>
+ * <li>Local repository path ({@link #localRepository()})</li>
+ * <li>Explicitly activated or deactivated profiles ({@link
#activeProfiles()})</li>
+ * <li>Selected projects ({@link #selectedProjects()}) and resume-from
+ * ({@link #resumeFrom()})</li>
+ * <li>Reactor failure behavior ({@link #reactorFailureBehavior()})</li>
+ * <li>Offline mode ({@link #offline()}) and snapshot update policy
+ * ({@link #updateSnapshots()})</li>
+ * <li>Degree of concurrency ({@link #threads()})</li>
+ * <li>Transfer-progress suppression ({@link #noTransferProgress()}) and
batch mode ({@link #batchMode()})</li>
+ * </ul>
+ *
+ * <h2>What is not yet captured</h2>
+ * <p>The following information is not currently available through the Maven 4
API
+ * and therefore cannot be recorded here. It may be added in future versions as
+ * the API evolves:
+ * <ul>
+ * <li><b>Raw command-line arguments</b> ({@code args[]}): the CLI bootstrap
layer
+ * does not surface these through {@code MavenExecutionRequest} or the
session</li>
+ * <li><b>Implicitly activated profiles</b>: profiles activated by OS, JDK,
or
+ * property conditions rather than by explicit {@code -P} flag; computing
+ * these requires per-project activation and is not available at session
level</li>
+ * </ul>
+ *
+ * @since 4.1.0
+ * @see Session#buildEnvironment()
+ */
+@Experimental
+@Immutable
+public interface BuildEnvironment {
+
+ /**
+ * The goals or lifecycle phases that were requested on the command line.
+ *
+ * @return the requested goals/phases, never {@code null}
+ */
+ @Nonnull
+ List<String> goals();
+
+ /**
+ * User properties passed via {@code -Dkey=value} on the command line or
via
+ * {@code --define}.
+ *
+ * <p>Sensitive keys are redacted and replaced with {@code "***"}. A key is
+ * considered sensitive if its lower-case form contains any of:
+ * {@code password}, {@code passwd}, {@code secret}, {@code token},
+ * {@code apikey}, {@code api_key}, {@code credential}, {@code passphrase}.
+ *
+ * @return the user properties, never {@code null}; values of sensitive
keys
+ * are replaced with {@code "***"}
+ */
+ @Nonnull
+ Map<String, String> userProperties();
+
+ /**
+ * A curated subset of system properties capturing platform and JVM
identity,
+ * relevant for build reproducibility analysis.
+ *
+ * <p>The following keys are included when present:
+ * {@code os.name}, {@code os.arch}, {@code os.version},
+ * {@code java.vendor}, {@code java.vm.name}, {@code java.vm.version},
+ * {@code maven.home}, {@code user.home}, {@code user.name},
+ * and {@code available.processors} (from {@code Runtime.getRuntime()}).
Review Comment:
💡 **Privacy/PII note missing:** The Javadoc explicitly lists `user.home` and
`user.name` as captured keys. These are personally identifiable on developer
machines (home directory reveals the OS username). This is worth calling out:
```suggestion
* {@code maven.home}, {@code user.home}, {@code user.name},
* and {@code available.processors} (from {@code Runtime.getRuntime()}).
*
* <p><b>Privacy note:</b> {@code user.home} and {@code user.name}
reflect the OS
* user identity and may be considered personally identifiable
information (PII)
* in shared build environments, CI logs, or published build reports.
```
##########
api/maven-api-core/src/main/java/org/apache/maven/api/BuildEnvironment.java:
##########
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Immutable;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * Describes the invocation context of a Maven build: the flags, properties,
and
+ * environment settings that were active when the build started.
+ *
+ * <p>An instance is available via {@link Session#buildEnvironment()} during
the build,
+ * and is also recorded in the structured build report for post-mortem
analysis and
+ * reproducibility.
+ *
+ * <h2>What is captured</h2>
+ * <ul>
+ * <li>Goals and lifecycle phases requested ({@link #goals()})</li>
+ * <li>User properties passed via {@code -Dkey=value} ({@link
#userProperties()}),
+ * with sensitive keys redacted — see {@link #userProperties()} for the
denylist</li>
+ * <li>A curated subset of system properties relevant to reproducibility
+ * ({@link #systemInfo()}): OS name/arch/version, Java vendor and VM
name/version,
+ * Maven home, and available processors</li>
+ * <li>Local repository path ({@link #localRepository()})</li>
+ * <li>Explicitly activated or deactivated profiles ({@link
#activeProfiles()})</li>
+ * <li>Selected projects ({@link #selectedProjects()}) and resume-from
+ * ({@link #resumeFrom()})</li>
+ * <li>Reactor failure behavior ({@link #reactorFailureBehavior()})</li>
+ * <li>Offline mode ({@link #offline()}) and snapshot update policy
+ * ({@link #updateSnapshots()})</li>
+ * <li>Degree of concurrency ({@link #threads()})</li>
+ * <li>Transfer-progress suppression ({@link #noTransferProgress()}) and
batch mode ({@link #batchMode()})</li>
+ * </ul>
+ *
+ * <h2>What is not yet captured</h2>
+ * <p>The following information is not currently available through the Maven 4
API
+ * and therefore cannot be recorded here. It may be added in future versions as
+ * the API evolves:
+ * <ul>
+ * <li><b>Raw command-line arguments</b> ({@code args[]}): the CLI bootstrap
layer
+ * does not surface these through {@code MavenExecutionRequest} or the
session</li>
+ * <li><b>Implicitly activated profiles</b>: profiles activated by OS, JDK,
or
+ * property conditions rather than by explicit {@code -P} flag; computing
+ * these requires per-project activation and is not available at session
level</li>
+ * </ul>
+ *
+ * @since 4.1.0
+ * @see Session#buildEnvironment()
+ */
+@Experimental
+@Immutable
+public interface BuildEnvironment {
+
+ /**
+ * The goals or lifecycle phases that were requested on the command line.
+ *
+ * @return the requested goals/phases, never {@code null}
+ */
+ @Nonnull
+ List<String> goals();
+
+ /**
+ * User properties passed via {@code -Dkey=value} on the command line or
via
+ * {@code --define}.
+ *
+ * <p>Sensitive keys are redacted and replaced with {@code "***"}. A key is
+ * considered sensitive if its lower-case form contains any of:
+ * {@code password}, {@code passwd}, {@code secret}, {@code token},
+ * {@code apikey}, {@code api_key}, {@code credential}, {@code passphrase}.
+ *
+ * @return the user properties, never {@code null}; values of sensitive
keys
+ * are replaced with {@code "***"}
+ */
+ @Nonnull
+ Map<String, String> userProperties();
+
+ /**
+ * A curated subset of system properties capturing platform and JVM
identity,
+ * relevant for build reproducibility analysis.
+ *
+ * <p>The following keys are included when present:
+ * {@code os.name}, {@code os.arch}, {@code os.version},
+ * {@code java.vendor}, {@code java.vm.name}, {@code java.vm.version},
+ * {@code maven.home}, {@code user.home}, {@code user.name},
+ * and {@code available.processors} (from {@code Runtime.getRuntime()}).
+ *
+ * <p>The full {@code System.getProperties()} map is intentionally not
captured:
+ * it is large, mostly irrelevant, and may contain sensitive values.
+ *
+ * @return the curated system info map, never {@code null}
+ */
+ @Nonnull
+ Map<String, String> systemInfo();
+
+ /**
+ * The path to the local repository used for this build.
+ *
+ * @return the local repository path string, never {@code null}
+ */
+ @Nonnull
+ String localRepository();
Review Comment:
⚠️ **API design — `String` vs `Path`:** The Maven 4 API consistently uses
`java.nio.file.Path` for filesystem paths (see `Project`, `Session`, etc.).
Returning a `String` here:
- Loses type safety (callers must parse/construct paths manually)
- Is inconsistent with the rest of the v4 API surface
Consider:
```suggestion
@Nonnull
Path localRepository();
```
(With the appropriate `import java.nio.file.Path;`.)
##########
api/maven-api-core/src/main/java/org/apache/maven/api/BuildEnvironment.java:
##########
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Immutable;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * Describes the invocation context of a Maven build: the flags, properties,
and
+ * environment settings that were active when the build started.
+ *
+ * <p>An instance is available via {@link Session#buildEnvironment()} during
the build,
+ * and is also recorded in the structured build report for post-mortem
analysis and
+ * reproducibility.
+ *
+ * <h2>What is captured</h2>
+ * <ul>
+ * <li>Goals and lifecycle phases requested ({@link #goals()})</li>
+ * <li>User properties passed via {@code -Dkey=value} ({@link
#userProperties()}),
+ * with sensitive keys redacted — see {@link #userProperties()} for the
denylist</li>
+ * <li>A curated subset of system properties relevant to reproducibility
+ * ({@link #systemInfo()}): OS name/arch/version, Java vendor and VM
name/version,
+ * Maven home, and available processors</li>
+ * <li>Local repository path ({@link #localRepository()})</li>
+ * <li>Explicitly activated or deactivated profiles ({@link
#activeProfiles()})</li>
+ * <li>Selected projects ({@link #selectedProjects()}) and resume-from
+ * ({@link #resumeFrom()})</li>
+ * <li>Reactor failure behavior ({@link #reactorFailureBehavior()})</li>
+ * <li>Offline mode ({@link #offline()}) and snapshot update policy
+ * ({@link #updateSnapshots()})</li>
+ * <li>Degree of concurrency ({@link #threads()})</li>
+ * <li>Transfer-progress suppression ({@link #noTransferProgress()}) and
batch mode ({@link #batchMode()})</li>
+ * </ul>
+ *
+ * <h2>What is not yet captured</h2>
+ * <p>The following information is not currently available through the Maven 4
API
+ * and therefore cannot be recorded here. It may be added in future versions as
+ * the API evolves:
+ * <ul>
+ * <li><b>Raw command-line arguments</b> ({@code args[]}): the CLI bootstrap
layer
+ * does not surface these through {@code MavenExecutionRequest} or the
session</li>
+ * <li><b>Implicitly activated profiles</b>: profiles activated by OS, JDK,
or
+ * property conditions rather than by explicit {@code -P} flag; computing
+ * these requires per-project activation and is not available at session
level</li>
+ * </ul>
+ *
+ * @since 4.1.0
+ * @see Session#buildEnvironment()
+ */
+@Experimental
+@Immutable
+public interface BuildEnvironment {
+
+ /**
+ * The goals or lifecycle phases that were requested on the command line.
+ *
+ * @return the requested goals/phases, never {@code null}
+ */
+ @Nonnull
+ List<String> goals();
+
+ /**
+ * User properties passed via {@code -Dkey=value} on the command line or
via
+ * {@code --define}.
+ *
+ * <p>Sensitive keys are redacted and replaced with {@code "***"}. A key is
+ * considered sensitive if its lower-case form contains any of:
+ * {@code password}, {@code passwd}, {@code secret}, {@code token},
+ * {@code apikey}, {@code api_key}, {@code credential}, {@code passphrase}.
+ *
+ * @return the user properties, never {@code null}; values of sensitive
keys
+ * are replaced with {@code "***"}
+ */
+ @Nonnull
+ Map<String, String> userProperties();
+
+ /**
+ * A curated subset of system properties capturing platform and JVM
identity,
+ * relevant for build reproducibility analysis.
+ *
+ * <p>The following keys are included when present:
+ * {@code os.name}, {@code os.arch}, {@code os.version},
+ * {@code java.vendor}, {@code java.vm.name}, {@code java.vm.version},
+ * {@code maven.home}, {@code user.home}, {@code user.name},
+ * and {@code available.processors} (from {@code Runtime.getRuntime()}).
+ *
+ * <p>The full {@code System.getProperties()} map is intentionally not
captured:
+ * it is large, mostly irrelevant, and may contain sensitive values.
+ *
+ * @return the curated system info map, never {@code null}
+ */
+ @Nonnull
+ Map<String, String> systemInfo();
+
+ /**
+ * The path to the local repository used for this build.
+ *
+ * @return the local repository path string, never {@code null}
+ */
+ @Nonnull
+ String localRepository();
+
+ /**
+ * Profiles explicitly activated ({@code -P profileId}) or deactivated
+ * ({@code -P !profileId}) on the command line.
+ *
+ * <p>This list reflects only explicit {@code -P} selections. Profiles
activated
+ * implicitly by OS, JDK, or property conditions are not included here —
see
+ * the class-level javadoc for details.
+ *
+ * @return the explicitly selected profiles, never {@code null}; may be
empty
+ */
+ @Nonnull
+ List<String> activeProfiles();
+
+ /**
+ * Projects explicitly selected via {@code -pl} / {@code --projects}.
+ *
+ * @return the selected project selectors (e.g. {@code ":my-module"}),
+ * never {@code null}; empty for a full reactor build
+ */
+ @Nonnull
+ List<String> selectedProjects();
+
+ /**
+ * The project to resume from, as specified via {@code -rf} / {@code
--resume-from}.
+ *
+ * @return the resume-from selector, or {@code null} if not specified
+ */
+ String resumeFrom();
+
+ /**
+ * The reactor failure behavior, corresponding to the {@code -ff} / {@code
-fae} /
+ * {@code -fn} flags.
+ *
+ * <p>Possible values (matching {@code MavenExecutionRequest} constants):
+ * <ul>
+ * <li>{@code "FAIL_FAST"} — stop at first failure ({@code -ff},
default)</li>
+ * <li>{@code "FAIL_AT_END"} — build all, report failures at end ({@code
-fae})</li>
+ * <li>{@code "FAIL_NEVER"} — always exit with success ({@code -fn})</li>
+ * </ul>
+ *
+ * @return the failure behavior string, never {@code null}
+ */
+ @Nonnull
+ String reactorFailureBehavior();
Review Comment:
💡 **API design — `String` constants vs enum:** `reactorFailureBehavior()`
returns one of three string constants (`FAIL_FAST`, `FAIL_AT_END`,
`FAIL_NEVER`) that mirror `MavenExecutionRequest` v3 constants. For a v4 public
API, an enum would be more type-safe, discoverable (IDE completion), and would
prevent callers from having to match arbitrary strings:
```java
public enum ReactorFailureBehavior {
FAIL_FAST, FAIL_AT_END, FAIL_NEVER
}
```
Then `reactorFailureBehavior()` returns `ReactorFailureBehavior`. This is
worth discussing at the API design level before this merges.
##########
impl/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java:
##########
@@ -279,6 +279,11 @@ public interface MavenExecutionRequest {
boolean isInteractiveMode();
+ // Transfer progress
+ MavenExecutionRequest setNoTransferProgress(boolean noTransferProgress);
+
+ boolean isNoTransferProgress();
Review Comment:
💡 **Interface compat note:**
`setNoTransferProgress()`/`isNoTransferProgress()` are added as non-default
methods to `MavenExecutionRequest`. While this interface lives in
`impl/maven-core` (not the public API module), external tools like Gradle's
Maven resolver bridge, Tycho, and plugin testing frameworks do implement it.
This is a binary-incompatible change for them.
If backward compat matters, add `default` implementations here (e.g.
`default boolean isNoTransferProgress() { return false; }`).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]