[MNG-8190] Restrict build pom feature to 4.1.0 model version (#1707)

This commit is contained in:
Guillaume Nodet 2024-09-11 18:31:06 +02:00 committed by GitHub
parent e6d038ac07
commit f137c13877
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 71 additions and 64 deletions

View File

@ -273,5 +273,13 @@ public final class Constants {
@Config(type = "java.lang.Integer", defaultValue = "cores/2 + 1")
public static final String MAVEN_PROJECT_BUILDER_PARALLELISM = "maven.projectBuilder.parallelism";
/**
* User property for enabling/disabling the consumer POM feature.
*
* @since 4.0.0
*/
@Config(type = "java.lang.Boolean", defaultValue = "true")
public static final String MAVEN_CONSUMER_POM = "maven.consumer.pom";
private Constants() {}
}

View File

@ -21,6 +21,7 @@
import java.util.Map;
import java.util.Properties;
import org.apache.maven.api.Constants;
import org.apache.maven.api.Session;
import org.apache.maven.api.annotations.Nullable;
@ -32,32 +33,27 @@
*/
public final class Features {
/**
* Name of the Maven user property to enable or disable the build/consumer POM feature.
*/
public static final String BUILDCONSUMER = "maven.buildconsumer";
private Features() {}
/**
* Check if the build/consumer POM feature is active.
* Check if the consumer POM feature is active.
*/
public static boolean buildConsumer(@Nullable Properties userProperties) {
return doGet(userProperties, BUILDCONSUMER, true);
public static boolean consumerPom(@Nullable Properties userProperties) {
return doGet(userProperties, Constants.MAVEN_CONSUMER_POM, true);
}
/**
* Check if the build/consumer POM feature is active.
* Check if the consumer POM feature is active.
*/
public static boolean buildConsumer(@Nullable Map<String, String> userProperties) {
return doGet(userProperties, BUILDCONSUMER, true);
public static boolean consumerPom(@Nullable Map<String, String> userProperties) {
return doGet(userProperties, Constants.MAVEN_CONSUMER_POM, true);
}
/**
* Check if the build/consumer POM feature is active.
* Check if the consumer POM feature is active.
*/
public static boolean buildConsumer(@Nullable Session session) {
return buildConsumer(session != null ? session.getUserProperties() : null);
public static boolean consumerPom(@Nullable Session session) {
return consumerPom(session != null ? session.getUserProperties() : null);
}
private static boolean doGet(Properties userProperties, String key, boolean def) {

View File

@ -47,7 +47,6 @@
import org.apache.maven.api.di.Inject;
import org.apache.maven.api.di.Named;
import org.apache.maven.api.di.Singleton;
import org.apache.maven.api.feature.Features;
import org.apache.maven.api.model.Activation;
import org.apache.maven.api.model.ActivationFile;
import org.apache.maven.api.model.Build;
@ -302,7 +301,8 @@ private Model readEffectiveModel(
problems.setRootModel(inputModel);
ModelData resultData = new ModelData(request.getSource(), inputModel);
String superModelVersion = inputModel.getModelVersion() != null ? inputModel.getModelVersion() : "4.0.0";
String superModelVersion =
inputModel.getModelVersion() != null ? inputModel.getModelVersion() : MODEL_VERSION_4_0_0;
if (!VALID_MODEL_VERSIONS.contains(superModelVersion)) {
// Maven 3.x is always using 4.0.0 version to load the supermodel, so
// do the same when loading a dependency. The model validator will also
@ -790,7 +790,7 @@ private ModelData doReadRawModel(
ModelSource modelSource, ModelBuilderRequest request, DefaultModelProblemCollector problems)
throws ModelBuilderException {
Model rawModel = readFileModel(request, problems);
if (Features.buildConsumer(request.getUserProperties()) && modelSource.getPath() != null) {
if (!MODEL_VERSION_4_0_0.equals(rawModel.getModelVersion()) && modelSource.getPath() != null) {
Path pomFile = modelSource.getPath();
try {

View File

@ -80,7 +80,7 @@ public void injectTransformedArtifacts(RepositorySystemSession session, MavenPro
// If there is no build POM there is no reason to inject artifacts for the consumer POM.
return;
}
if (Features.buildConsumer(session.getUserProperties())) {
if (Features.consumerPom(session.getUserProperties())) {
Path buildDir =
project.getBuild() != null ? Paths.get(project.getBuild().getDirectory()) : null;
if (buildDir != null) {
@ -133,14 +133,14 @@ private void doDeleteFiles() {
}
public InstallRequest remapInstallArtifacts(RepositorySystemSession session, InstallRequest request) {
if (Features.buildConsumer(session.getUserProperties()) && consumerPomPresent(request.getArtifacts())) {
if (Features.consumerPom(session.getUserProperties()) && consumerPomPresent(request.getArtifacts())) {
request.setArtifacts(replacePom(request.getArtifacts()));
}
return request;
}
public DeployRequest remapDeployArtifacts(RepositorySystemSession session, DeployRequest request) {
if (Features.buildConsumer(session.getUserProperties()) && consumerPomPresent(request.getArtifacts())) {
if (Features.consumerPom(session.getUserProperties()) && consumerPomPresent(request.getArtifacts())) {
request.setArtifacts(replacePom(request.getArtifacts()));
}
return request;

View File

@ -60,7 +60,6 @@
import org.apache.maven.api.Constants;
import org.apache.maven.api.Session;
import org.apache.maven.api.SessionData;
import org.apache.maven.api.feature.Features;
import org.apache.maven.api.model.Build;
import org.apache.maven.api.model.Dependency;
import org.apache.maven.api.model.DependencyManagement;
@ -541,11 +540,9 @@ List<ProjectBuildingResult> doBuild(List<File> pomFiles, boolean recursive) {
// Phase 2: get effective models from the reactor
List<ProjectBuildingResult> results = build(projectIndex, interimResults);
if (Features.buildConsumer(request.getUserProperties())) {
request.getRepositorySession()
.getData()
.set(ModelTransformerContext.KEY, transformerContextBuilder.build());
}
request.getRepositorySession()
.getData()
.set(ModelTransformerContext.KEY, transformerContextBuilder.build());
return results;
} finally {

View File

@ -152,6 +152,7 @@ public void visitEnd() {
: "java.lang.String")) {
case "java.lang.String" -> "String";
case "java.lang.Integer" -> "Integer";
case "java.lang.Boolean" -> "Boolean";
default -> throw new IllegalStateException();
};
discoveredKeys.put(

View File

@ -43,7 +43,6 @@
import java.util.stream.Stream;
import org.apache.maven.api.VersionRange;
import org.apache.maven.api.feature.Features;
import org.apache.maven.api.model.ActivationFile;
import org.apache.maven.api.model.Exclusion;
import org.apache.maven.api.model.InputSource;
@ -97,6 +96,7 @@
import org.codehaus.plexus.interpolation.StringSearchInterpolator;
import org.eclipse.sisu.Nullable;
import static org.apache.maven.api.services.ModelBuilder.MODEL_VERSION_4_0_0;
import static org.apache.maven.model.building.Result.error;
import static org.apache.maven.model.building.Result.newResult;
@ -774,12 +774,13 @@ private Model readEffectiveModel(
problems.setRootModel(inputModel);
ModelData resultData = new ModelData(request.getModelSource(), inputModel);
String superModelVersion = inputModel.getModelVersion() != null ? inputModel.getModelVersion() : "4.0.0";
String superModelVersion =
inputModel.getModelVersion() != null ? inputModel.getModelVersion() : MODEL_VERSION_4_0_0;
if (!DefaultModelValidator.VALID_MODEL_VERSIONS.contains(superModelVersion)) {
// Maven 3.x is always using 4.0.0 version to load the supermodel, so
// do the same when loading a dependency. The model validator will also
// check that field later.
superModelVersion = "4.0.0";
superModelVersion = MODEL_VERSION_4_0_0;
}
ModelData superData = new ModelData(null, getSuperModel(superModelVersion));
@ -1251,19 +1252,22 @@ private ModelData doReadRawModel(
ModelSource modelSource, ModelBuildingRequest request, DefaultModelProblemCollector problems)
throws ModelBuildingException {
Model rawModel;
if (Features.buildConsumer(request.getUserProperties()) && modelSource instanceof FileModelSource) {
if (modelSource instanceof FileModelSource) {
rawModel = readFileModel(request, problems);
File pomFile = ((FileModelSource) modelSource).getFile();
try {
if (request.getTransformerContextBuilder() != null) {
TransformerContext context =
request.getTransformerContextBuilder().initialize(request, problems);
transformer.transform(pomFile.toPath(), context, rawModel);
if (!MODEL_VERSION_4_0_0.equals(rawModel.getModelVersion())) {
File pomFile = ((FileModelSource) modelSource).getFile();
try {
if (request.getTransformerContextBuilder() != null) {
TransformerContext context =
request.getTransformerContextBuilder().initialize(request, problems);
transformer.transform(pomFile.toPath(), context, rawModel);
}
} catch (TransformerException e) {
problems.add(
new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V40).setException(e));
}
} catch (TransformerException e) {
problems.add(
new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V40).setException(e));
}
} else if (request.getFileModel() == null) {
rawModel = readFileModel(request, problems);

View File

@ -26,29 +26,30 @@ under the License.
| No | Key | Type | Description | Default Value | Since | Source |
| --- | --- | --- | --- | --- | --- | --- |
| 1. | `maven.build.timestamp.format` | `String` | Build timestamp format. | `yyyy-MM-dd'T'HH:mm:ssXXX` | 3.0.0 | Model properties |
| 2. | `maven.ext.class.path` | `String` | Extensions class path. | - | | User properties |
| 3. | `maven.home` | `String` | Maven home. | - | 3.0.0 | User properties |
| 4. | `maven.installation.conf` | `String` | Maven installation configuration directory. | `${maven.home}/conf` | 4.0.0 | User properties |
| 5. | `maven.installation.extensions` | `String` | Maven installation extensions. | `${maven.installation.conf}/extensions.xml` | 4.0.0 | User properties |
| 6. | `maven.installation.settings` | `String` | Maven installation settings. | `${maven.installation.conf}/settings.xml` | 4.0.0 | User properties |
| 7. | `maven.installation.toolchains` | `String` | Maven installation toolchains. | `${maven.installation.conf}/toolchains.xml` | 4.0.0 | User properties |
| 8. | `maven.plugin.validation` | `String` | Plugin validation level. | `inline` | 3.9.2 | User properties |
| 9. | `maven.plugin.validation.excludes` | `String` | Plugin validation exclusions. | - | 3.9.6 | User properties |
| 10. | `maven.project.conf` | `String` | Maven project configuration directory. | `${session.rootDirectory}/.mvn` | 4.0.0 | User properties |
| 11. | `maven.project.extensions` | `String` | Maven project extensions. | `${maven.project.conf}/extensions.xml` | 4.0.0 | User properties |
| 12. | `maven.project.settings` | `String` | Maven project settings. | `${maven.project.conf}/settings.xml` | 4.0.0 | User properties |
| 13. | `maven.projectBuilder.parallelism` | `Integer` | ProjectBuilder parallelism. | `cores/2 + 1` | 4.0.0 | User properties |
| 14. | `maven.relocations.entries` | `String` | User controlled relocations. This property is a comma separated list of entries with the syntax <code>GAV&gt;GAV</code>. The first <code>GAV</code> can contain <code>\*</code> for any elem (so <code>\*:\*:\*</code> would mean ALL, something you don't want). The second <code>GAV</code> is either fully specified, or also can contain <code>\*</code>, then it behaves as "ordinary relocation": the coordinate is preserved from relocated artifact. Finally, if right hand <code>GAV</code> is absent (line looks like <code>GAV&gt;</code>), the left hand matching <code>GAV</code> is banned fully (from resolving). <br/> Note: the <code>&gt;</code> means project level, while <code>&gt;&gt;</code> means global (whole session level, so even plugins will get relocated artifacts) relocation. <br/> For example, <pre>maven.relocations.entries = org.foo:\*:\*>, \\<br/> org.here:\*:\*>org.there:\*:\*, \\<br/> javax.inject:javax.inject:1>>jakarta.inject:jakarta.inject:1.0.5</pre> means: 3 entries, ban <code>org.foo group</code> (exactly, so <code>org.foo.bar</code> is allowed), relocate <code>org.here</code> to <code>org.there</code> and finally globally relocate (see <code>&gt;&gt;</code> above) <code>javax.inject:javax.inject:1</code> to <code>jakarta.inject:jakarta.inject:1.0.5</code>. | - | 4.0.0 | User properties |
| 15. | `maven.repo.central` | `String` | Maven central repository URL. The property will have the value of the <code>MAVEN_REPO_CENTRAL</code> environment variable if it is defined. | `https://repo.maven.apache.org/maven2` | 4.0.0 | User properties |
| 16. | `maven.repo.local` | `String` | Maven local repository. | `${maven.user.conf}/repository` | 3.0.0 | User properties |
| 17. | `maven.repo.local.recordReverseTree` | `String` | User property for reverse dependency tree. If enabled, Maven will record ".tracking" directory into local repository with "reverse dependency tree", essentially explaining WHY given artifact is present in local repository. Default: <code>false</code>, will not record anything. | `false` | 3.9.0 | User properties |
| 18. | `maven.repo.local.tail` | `String` | User property for chained LRM: list of "tail" local repository paths (separated by comma), to be used with {@code org.eclipse.aether.util.repository.ChainedLocalRepositoryManager} . Default value: <code>null</code>, no chained LRM is used. | - | 3.9.0 | User properties |
| 19. | `maven.resolver.dependencyManagerTransitivity` | `String` | User property for selecting dependency manager behaviour regarding transitive dependencies and dependency management entries in their POMs. Maven 3 targeted full backward compatibility with Maven2, hence it ignored dependency management entries in transitive dependency POMs. Maven 4 enables "transitivity" by default, hence unlike Maven2, obeys dependency management entries deep in dependency graph as well. <br/> Default: <code>"true"</code>. | `true` | 4.0.0 | User properties |
| 20. | `maven.resolver.transport` | `String` | Resolver transport to use. Can be <code>default</code>, <code>wagon</code>, <code>apache</code>, <code>jdk</code> or <code>auto</code>. | `default` | 4.0.0 | User properties |
| 21. | `maven.style.color` | `String` | Maven output color mode. Allowed values are <code>auto</code>, <code>always</code>, <code>never</code>. | `auto` | 4.0.0 | User properties |
| 22. | `maven.user.conf` | `String` | Maven user configuration directory. | `${user.home}/.m2` | 4.0.0 | User properties |
| 23. | `maven.user.extensions` | `String` | Maven user extensions. | `${maven.user.conf}/extensions.xml` | 4.0.0 | User properties |
| 24. | `maven.user.settings` | `String` | Maven user settings. | `${maven.user.conf}/settings.xml` | 4.0.0 | User properties |
| 25. | `maven.user.toolchains` | `String` | Maven user toolchains. | `${maven.user.home}/toolchains.xml` | 4.0.0 | User properties |
| 26. | `maven.versionFilters` | `String` | User property for version filters expression, a semicolon separated list of filters to apply. By default, no version filter is applied (like in Maven 3). <br/> Supported filters: <ul> <li>"h" or "h(num)" - highest version or top list of highest ones filter</li> <li>"l" or "l(num)" - lowest version or bottom list of lowest ones filter</li> <li>"s" - contextual snapshot filter</li> <li>"e(G:A:V)" - predicate filter (leaves out G:A:V from range, if hit, V can be range)</li> </ul> Example filter expression: <code>"h(5);s;e(org.foo:bar:1)</code> will cause: ranges are filtered for "top 5" (instead full range), snapshots are banned if root project is not a snapshot, and if range for <code>org.foo:bar</code> is being processed, version 1 is omitted. | - | 4.0.0 | User properties |
| 2. | `maven.consumer.pom` | `Boolean` | User property for enabling/disabling the consumer POM feature. | `true` | 4.0.0 | User properties |
| 3. | `maven.ext.class.path` | `String` | Extensions class path. | - | | User properties |
| 4. | `maven.home` | `String` | Maven home. | - | 3.0.0 | User properties |
| 5. | `maven.installation.conf` | `String` | Maven installation configuration directory. | `${maven.home}/conf` | 4.0.0 | User properties |
| 6. | `maven.installation.extensions` | `String` | Maven installation extensions. | `${maven.installation.conf}/extensions.xml` | 4.0.0 | User properties |
| 7. | `maven.installation.settings` | `String` | Maven installation settings. | `${maven.installation.conf}/settings.xml` | 4.0.0 | User properties |
| 8. | `maven.installation.toolchains` | `String` | Maven installation toolchains. | `${maven.installation.conf}/toolchains.xml` | 4.0.0 | User properties |
| 9. | `maven.plugin.validation` | `String` | Plugin validation level. | `inline` | 3.9.2 | User properties |
| 10. | `maven.plugin.validation.excludes` | `String` | Plugin validation exclusions. | - | 3.9.6 | User properties |
| 11. | `maven.project.conf` | `String` | Maven project configuration directory. | `${session.rootDirectory}/.mvn` | 4.0.0 | User properties |
| 12. | `maven.project.extensions` | `String` | Maven project extensions. | `${maven.project.conf}/extensions.xml` | 4.0.0 | User properties |
| 13. | `maven.project.settings` | `String` | Maven project settings. | `${maven.project.conf}/settings.xml` | 4.0.0 | User properties |
| 14. | `maven.projectBuilder.parallelism` | `Integer` | ProjectBuilder parallelism. | `cores/2 + 1` | 4.0.0 | User properties |
| 15. | `maven.relocations.entries` | `String` | User controlled relocations. This property is a comma separated list of entries with the syntax <code>GAV&gt;GAV</code>. The first <code>GAV</code> can contain <code>\*</code> for any elem (so <code>\*:\*:\*</code> would mean ALL, something you don't want). The second <code>GAV</code> is either fully specified, or also can contain <code>\*</code>, then it behaves as "ordinary relocation": the coordinate is preserved from relocated artifact. Finally, if right hand <code>GAV</code> is absent (line looks like <code>GAV&gt;</code>), the left hand matching <code>GAV</code> is banned fully (from resolving). <br/> Note: the <code>&gt;</code> means project level, while <code>&gt;&gt;</code> means global (whole session level, so even plugins will get relocated artifacts) relocation. <br/> For example, <pre>maven.relocations.entries = org.foo:\*:\*>, \\<br/> org.here:\*:\*>org.there:\*:\*, \\<br/> javax.inject:javax.inject:1>>jakarta.inject:jakarta.inject:1.0.5</pre> means: 3 entries, ban <code>org.foo group</code> (exactly, so <code>org.foo.bar</code> is allowed), relocate <code>org.here</code> to <code>org.there</code> and finally globally relocate (see <code>&gt;&gt;</code> above) <code>javax.inject:javax.inject:1</code> to <code>jakarta.inject:jakarta.inject:1.0.5</code>. | - | 4.0.0 | User properties |
| 16. | `maven.repo.central` | `String` | Maven central repository URL. The property will have the value of the <code>MAVEN_REPO_CENTRAL</code> environment variable if it is defined. | `https://repo.maven.apache.org/maven2` | 4.0.0 | User properties |
| 17. | `maven.repo.local` | `String` | Maven local repository. | `${maven.user.conf}/repository` | 3.0.0 | User properties |
| 18. | `maven.repo.local.recordReverseTree` | `String` | User property for reverse dependency tree. If enabled, Maven will record ".tracking" directory into local repository with "reverse dependency tree", essentially explaining WHY given artifact is present in local repository. Default: <code>false</code>, will not record anything. | `false` | 3.9.0 | User properties |
| 19. | `maven.repo.local.tail` | `String` | User property for chained LRM: list of "tail" local repository paths (separated by comma), to be used with {@code org.eclipse.aether.util.repository.ChainedLocalRepositoryManager} . Default value: <code>null</code>, no chained LRM is used. | - | 3.9.0 | User properties |
| 20. | `maven.resolver.dependencyManagerTransitivity` | `String` | User property for selecting dependency manager behaviour regarding transitive dependencies and dependency management entries in their POMs. Maven 3 targeted full backward compatibility with Maven2, hence it ignored dependency management entries in transitive dependency POMs. Maven 4 enables "transitivity" by default, hence unlike Maven2, obeys dependency management entries deep in dependency graph as well. <br/> Default: <code>"true"</code>. | `true` | 4.0.0 | User properties |
| 21. | `maven.resolver.transport` | `String` | Resolver transport to use. Can be <code>default</code>, <code>wagon</code>, <code>apache</code>, <code>jdk</code> or <code>auto</code>. | `default` | 4.0.0 | User properties |
| 22. | `maven.style.color` | `String` | Maven output color mode. Allowed values are <code>auto</code>, <code>always</code>, <code>never</code>. | `auto` | 4.0.0 | User properties |
| 23. | `maven.user.conf` | `String` | Maven user configuration directory. | `${user.home}/.m2` | 4.0.0 | User properties |
| 24. | `maven.user.extensions` | `String` | Maven user extensions. | `${maven.user.conf}/extensions.xml` | 4.0.0 | User properties |
| 25. | `maven.user.settings` | `String` | Maven user settings. | `${maven.user.conf}/settings.xml` | 4.0.0 | User properties |
| 26. | `maven.user.toolchains` | `String` | Maven user toolchains. | `${maven.user.home}/toolchains.xml` | 4.0.0 | User properties |
| 27. | `maven.versionFilters` | `String` | User property for version filters expression, a semicolon separated list of filters to apply. By default, no version filter is applied (like in Maven 3). <br/> Supported filters: <ul> <li>"h" or "h(num)" - highest version or top list of highest ones filter</li> <li>"l" or "l(num)" - lowest version or bottom list of lowest ones filter</li> <li>"s" - contextual snapshot filter</li> <li>"e(G:A:V)" - predicate filter (leaves out G:A:V from range, if hit, V can be range)</li> </ul> Example filter expression: <code>"h(5);s;e(org.foo:bar:1)</code> will cause: ranges are filtered for "top 5" (instead full range), snapshots are banned if root project is not a snapshot, and if range for <code>org.foo:bar</code> is being processed, version 1 is omitted. | - | 4.0.0 | User properties |