[MNG-7920] Fix usage of packaging BOM fails in maven-install-plugin (#1305)

Signed-off-by: crazyhzm <crazyhzm@apache.org>
This commit is contained in:
huazhongming 2023-12-05 17:23:26 +08:00 committed by GitHub
parent 23bca281fc
commit 4af662f7b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 132 additions and 21 deletions

View File

@ -99,6 +99,7 @@ public class DefaultGraphBuilder implements GraphBuilder {
if (result == null) {
final List<MavenProject> projects = getProjectsForMavenReactor(session);
validateProjects(projects, session.getRequest());
processPackagingAttribute(projects, session.getRequest());
enrichRequestFromResumptionData(projects, session.getRequest());
result = reactorDependencyGraph(session, projects);
}
@ -390,4 +391,17 @@ public class DefaultGraphBuilder implements GraphBuilder {
}
}
}
private void processPackagingAttribute(List<MavenProject> projects, MavenExecutionRequest request)
throws MavenExecutionException {
List<MavenProject> projectsInRequestScope = getProjectsInRequestScope(request, projects);
for (MavenProject p : projectsInRequestScope) {
if ("bom".equals(p.getPackaging())) {
LOGGER.info(
"The packaging attribute of the '{}' project is configured as 'bom' and changed to 'pom'",
p.getName());
p.setPackaging("pom");
}
}
}
}

View File

@ -29,6 +29,8 @@ import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import org.apache.maven.api.model.Dependency;
import org.apache.maven.api.model.DependencyManagement;
import org.apache.maven.api.model.DistributionManagement;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.model.ModelBase;
@ -70,9 +72,12 @@ import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.RequestTrace;
import org.eclipse.aether.impl.RemoteRepositoryManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Named
class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultConsumerPomBuilder.class);
private static final String BOM_PACKAGING = "bom";
@ -88,7 +93,8 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
throws ModelBuildingException, ComponentLookupException {
Model model = project.getModel().getDelegate();
String packaging = model.getPackaging();
if (POM_PACKAGING.equals(packaging)) {
String originalPackaging = project.getOriginalModel().getPackaging();
if (POM_PACKAGING.equals(packaging) && !BOM_PACKAGING.equals(originalPackaging)) {
return buildPom(session, project, src);
} else {
return buildNonPom(session, project, src);
@ -99,14 +105,14 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
throws ModelBuildingException, ComponentLookupException {
ModelBuildingResult result = buildModel(session, project, src);
Model model = result.getRawModel().getDelegate();
return transform(model);
return transform(model, project);
}
protected Model buildNonPom(RepositorySystemSession session, MavenProject project, Path src)
throws ModelBuildingException, ComponentLookupException {
ModelBuildingResult result = buildModel(session, project, src);
Model model = result.getEffectiveModel().getDelegate();
return transform(model);
return transform(model, project);
}
private ModelBuildingResult buildModel(RepositorySystemSession session, MavenProject project, Path src)
@ -171,7 +177,7 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
return container.lookup(clazz);
}
static Model transform(Model model) {
static Model transform(Model model, MavenProject project) {
String packaging = model.getPackaging();
if (POM_PACKAGING.equals(packaging)) {
// raw to consumer transform
@ -182,9 +188,34 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
if (!model.isPreserveModelVersion()) {
model = model.withPreserveModelVersion(false);
String version = new MavenModelVersion().getModelVersion(model);
model = model.withModelVersion(version);
String modelVersion = new MavenModelVersion().getModelVersion(model);
model = model.withModelVersion(modelVersion);
}
} else if (BOM_PACKAGING.equals(packaging)) {
DependencyManagement dependencyManagement =
project.getOriginalModel().getDependencyManagement().getDelegate();
List<Dependency> dependencies = new ArrayList<>();
String version = model.getVersion();
dependencyManagement
.getDependencies()
.forEach((dependency) -> dependencies.add(dependency.withVersion(version)));
Model.Builder builder = prune(
Model.newBuilder(model, true)
.preserveModelVersion(false)
.root(false)
.parent(null)
.dependencyManagement(dependencyManagement.withDependencies(dependencies))
.build(null),
model);
builder.packaging(POM_PACKAGING);
builder.profiles(model.getProfiles().stream()
.map(p -> prune(Profile.newBuilder(p, true), p).build())
.collect(Collectors.toList()));
model = builder.build();
String modelVersion = new MavenModelVersion().getModelVersion(model);
model = model.withModelVersion(modelVersion);
} else {
Model.Builder builder = prune(
Model.newBuilder(model, true)
@ -193,16 +224,12 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
.parent(null)
.build(null),
model);
boolean isBom = BOM_PACKAGING.equals(packaging);
if (isBom) {
builder.packaging(POM_PACKAGING);
}
builder.profiles(model.getProfiles().stream()
.map(p -> prune(Profile.newBuilder(p, true), p).build())
.collect(Collectors.toList()));
model = builder.build();
String version = new MavenModelVersion().getModelVersion(model);
model = model.withModelVersion(version);
String modelVersion = new MavenModelVersion().getModelVersion(model);
model = model.withModelVersion(modelVersion);
}
return model;
}

View File

@ -40,6 +40,7 @@ import org.apache.maven.model.locator.DefaultModelLocator;
import org.apache.maven.model.locator.ModelLocator;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingResult;
import org.apache.maven.project.collector.DefaultProjectsSelector;
@ -48,6 +49,7 @@ import org.apache.maven.project.collector.PomlessCollectionStrategy;
import org.apache.maven.project.collector.ProjectsSelector;
import org.apache.maven.project.collector.RequestPomCollectionStrategy;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@ -79,6 +81,7 @@ class DefaultGraphBuilderTest {
module-c
module-c-1
module-c-2 (depends on module-b)
module-d (packaging is bom)
*/
private static final String GROUP_ID = "unittest";
private static final String PARENT_MODULE = "module-parent";
@ -86,6 +89,7 @@ class DefaultGraphBuilderTest {
private static final String MODULE_A = "module-a";
private static final String MODULE_B = "module-b";
private static final String MODULE_C = "module-c";
private static final String MODULE_D = "module-d";
private static final String MODULE_C_1 = "module-c-1";
private static final String MODULE_C_2 = "module-c-2";
@ -329,6 +333,46 @@ class DefaultGraphBuilderTest {
}
}
@Test
void testProcessPackagingAttribute() throws ProjectBuildingException {
graphBuilder = new DefaultGraphBuilder(
mock(BuildResumptionDataRepository.class),
pomlessCollectionStrategy,
multiModuleCollectionStrategy,
requestPomCollectionStrategy);
// Create projects
MavenProject projectParent = getMavenProject(PARENT_MODULE);
MavenProject projectModuleD = getMavenProject(MODULE_D, projectParent, "bom");
projectParent.setCollectedProjects(singletonList(projectModuleD));
// Set up needed mocks
when(session.getRequest()).thenReturn(mavenExecutionRequest);
when(session.getProjects()).thenReturn(null); // needed, otherwise it will be an empty list by default
when(mavenExecutionRequest.getProjectBuildingRequest()).thenReturn(mock(ProjectBuildingRequest.class));
List<ProjectBuildingResult> projectBuildingResults =
createProjectBuildingResultMocks(Stream.of(projectParent, projectModuleD)
.collect(Collectors.toMap(MavenProject::getArtifactId, identity()))
.values());
when(projectBuilder.build(anyList(), anyBoolean(), any(ProjectBuildingRequest.class)))
.thenReturn(projectBuildingResults);
ProjectActivation projectActivation = new ProjectActivation();
when(mavenExecutionRequest.getProjectActivation()).thenReturn(projectActivation);
when(mavenExecutionRequest.getPom()).thenReturn(new File(PARENT_MODULE, "pom.xml"));
Result<ProjectDependencyGraph> result = graphBuilder.build(session);
assertThat(result.hasErrors())
.withFailMessage("Expected result not to have errors")
.isFalse();
List<MavenProject> actualReactorProjects = result.get().getSortedProjects();
assertEquals(2, actualReactorProjects.size());
assertEquals("pom", actualReactorProjects.get(1).getPackaging());
}
@BeforeEach
void before() throws Exception {
graphBuilder = new DefaultGraphBuilder(
@ -397,6 +441,16 @@ class DefaultGraphBuilderTest {
return mavenProject;
}
private MavenProject getMavenProject(String artifactId, MavenProject parentProject, String packaging) {
MavenProject project = getMavenProject(artifactId);
Parent parent = new Parent();
parent.setGroupId(parentProject.getGroupId());
parent.setArtifactId(parentProject.getArtifactId());
project.getModel().setParent(parent);
project.setPackaging(packaging);
return project;
}
private Dependency toDependency(MavenProject mavenProject) {
Dependency dependency = new Dependency();
dependency.setGroupId(mavenProject.getGroupId());

View File

@ -56,9 +56,10 @@ class ConsumerPomArtifactTransformerTest {
try (InputStream expected = Files.newInputStream(beforePomFile)) {
Model model = new Model(new MavenStaxReader().read(expected));
MavenProject project = new MavenProject(model);
project.setOriginalModel(model);
DefaultConsumerPomArtifactTransformer t = new DefaultConsumerPomArtifactTransformer((s, p, f) -> {
try (InputStream is = Files.newInputStream(f)) {
return DefaultConsumerPomBuilder.transform(new MavenStaxReader().read(is));
return DefaultConsumerPomBuilder.transform(new MavenStaxReader().read(is), project);
}
});

View File

@ -20,6 +20,8 @@ package org.apache.maven.internal.transformation.impl;
import javax.inject.Inject;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
@ -28,6 +30,7 @@ import org.apache.maven.api.model.Model;
import org.apache.maven.artifact.repository.MavenArtifactRepository;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.internal.transformation.AbstractRepositoryTestCase;
import org.apache.maven.model.v4.MavenStaxReader;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.junit.jupiter.api.Test;
@ -42,11 +45,17 @@ public class ConsumerPomBuilderTest extends AbstractRepositoryTestCase {
@Test
void testTrivialConsumer() throws Exception {
MavenProject project = new MavenProject();
project.setRootDirectory(Paths.get("src/test/resources/consumer/trivial"));
project.setRemoteArtifactRepositories(Collections.singletonList(new MavenArtifactRepository(
"central", "http://repo.maven.apache.org/", new DefaultRepositoryLayout(), null, null)));
MavenProject project;
Path file = Paths.get("src/test/resources/consumer/trivial/child/pom.xml");
try (InputStream inputStream = Files.newInputStream(file)) {
org.apache.maven.model.Model model =
new org.apache.maven.model.Model(new MavenStaxReader().read(inputStream));
project = new MavenProject(model);
project.setRootDirectory(Paths.get("src/test/resources/consumer/trivial"));
project.setOriginalModel(model);
project.setRemoteArtifactRepositories(Collections.singletonList(new MavenArtifactRepository(
"central", "http://repo.maven.apache.org/", new DefaultRepositoryLayout(), null, null)));
}
Model model = builder.build(session, project, file);
assertNotNull(model);
@ -54,12 +63,18 @@ public class ConsumerPomBuilderTest extends AbstractRepositoryTestCase {
@Test
void testSimpleConsumer() throws Exception {
MavenProject project = new MavenProject();
project.setRootDirectory(Paths.get("src/test/resources/consumer/simple"));
project.setRemoteArtifactRepositories(Collections.singletonList(new MavenArtifactRepository(
"central", "http://repo.maven.apache.org/", new DefaultRepositoryLayout(), null, null)));
MavenProject project;
Path file = Paths.get("src/test/resources/consumer/simple/simple-parent/simple-weather/pom.xml");
((DefaultRepositorySystemSession) session).setUserProperty("changelist", "MNG6957");
try (InputStream inputStream = Files.newInputStream(file)) {
org.apache.maven.model.Model model =
new org.apache.maven.model.Model(new MavenStaxReader().read(inputStream));
project = new MavenProject(model);
project.setRootDirectory(Paths.get("src/test/resources/consumer/simple"));
project.setRemoteArtifactRepositories(Collections.singletonList(new MavenArtifactRepository(
"central", "http://repo.maven.apache.org/", new DefaultRepositoryLayout(), null, null)));
project.setOriginalModel(model);
}
Model model = builder.build(session, project, file);
assertNotNull(model);