diff --git a/src/main/java/org/apache/maven/plugins/install/InstallMojo.java b/src/main/java/org/apache/maven/plugins/install/InstallMojo.java index 1eda589..fb4cd54 100644 --- a/src/main/java/org/apache/maven/plugins/install/InstallMojo.java +++ b/src/main/java/org/apache/maven/plugins/install/InstallMojo.java @@ -29,6 +29,7 @@ import org.apache.maven.api.ProducedArtifact; import org.apache.maven.api.Project; import org.apache.maven.api.Session; +import org.apache.maven.api.SourceRoot; import org.apache.maven.api.di.Inject; import org.apache.maven.api.model.Plugin; import org.apache.maven.api.plugin.Log; @@ -249,6 +250,7 @@ private ArtifactInstallerRequest processProject(Project project) { ProjectManager projectManager = getProjectManager(); Collection installables = projectManager.getAllArtifacts(project); Collection attachedArtifacts = projectManager.getAttachedArtifacts(project); + List toInstall = new ArrayList<>(installables); getArtifactManager().setPath(project.getPomArtifact(), project.getPomPath()); @@ -258,19 +260,19 @@ private ArtifactInstallerRequest processProject(Project project) { if (attachedArtifacts.isEmpty()) { throw new MojoException( "The packaging for this project did not assign a file to the build artifact"); + } else if (usesModuleSourceHierarchy(project, projectManager)) { + getLog().info("Module source hierarchy: no main artifact produced;" + + " installing POM and per-module artifacts only."); + toInstall.remove(installable); + } else if (allowIncompleteProjects) { + getLog().warn("The packaging plugin for this project did not assign" + + " a main file to the project but it has attachments." + + " Change packaging to 'pom'." + + " Incomplete projects like this will fail in future Maven versions!"); + toInstall.remove(installable); } else { - if (allowIncompleteProjects) { - getLog().warn(""); - getLog().warn("The packaging plugin for this project did not assign"); - getLog().warn( - "a main file to the project but it has attachments. Change packaging to 'pom'."); - getLog().warn(""); - getLog().warn("Incomplete projects like this will fail in future Maven versions!"); - getLog().warn(""); - } else { - throw new MojoException("The packaging plugin for this project did not assign " - + "a main file to the project but it has attachments. Change packaging to 'pom'."); - } + throw new MojoException("The packaging plugin for this project did not assign " + + "a main file to the project but it has attachments. Change packaging to 'pom'."); } } else { throw new MojoException("The packaging for this project did not assign " @@ -279,13 +281,19 @@ private ArtifactInstallerRequest processProject(Project project) { } } - return ArtifactInstallerRequest.build(session, installables); + return ArtifactInstallerRequest.build(session, toInstall); } private boolean isValidPath(Artifact a) { return getArtifactManager().getPath(a).filter(Files::isRegularFile).isPresent(); } + private static boolean usesModuleSourceHierarchy(Project project, ProjectManager projectManager) { + return projectManager.getSourceRoots(project).stream() + .filter(SourceRoot::enabled) + .anyMatch(sr -> sr.module().isPresent()); + } + void setSkip(boolean skip) { this.skip = skip; } diff --git a/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java b/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java index df6a474..231ff6e 100644 --- a/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java +++ b/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java @@ -27,12 +27,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import org.apache.maven.api.Artifact; import org.apache.maven.api.MojoExecution; import org.apache.maven.api.ProducedArtifact; import org.apache.maven.api.Project; +import org.apache.maven.api.SourceRoot; import org.apache.maven.api.di.Inject; import org.apache.maven.api.di.Named; import org.apache.maven.api.di.Priority; @@ -154,6 +156,35 @@ void basicInstallWithAttachedArtifacts(InstallMojo mojo) throws Exception { artifacts.stream().map(Artifact::key).toList()); } + @Test + @InjectMojo(goal = "install") + @MojoParameter(name = "installAtEnd", value = "false") + void moduleSourceHierarchySkipsMainArtifact(InstallMojo mojo) throws Exception { + assertNotNull(mojo); + Project project = (Project) getVariableValueFromObject(mojo, "project"); + + SourceRoot moduleRoot = mock(SourceRoot.class); + when(moduleRoot.enabled()).thenReturn(true); + when(moduleRoot.module()).thenReturn(Optional.of("org.example.module")); + when(projectManager.getSourceRoots(project)).thenReturn(List.of(moduleRoot)); + + projectManager.attachArtifact( + project, + new ProducedArtifactStub("org.apache.maven.test", "org.example.module", "", "1.0-SNAPSHOT", "jar"), + Paths.get(getBasedir(), "target/test-classes/unit/attached-artifact-test-1.0-SNAPSHOT.jar")); + artifactManager.setPath(project.getMainArtifact().get(), Paths.get(getBasedir(), "target/test-classes/unit")); + + ArtifactInstallerRequest request = execute(mojo); + + assertNotNull(request); + Collection artifacts = request.getArtifacts(); + assertEquals( + Arrays.asList( + "org.apache.maven.test:maven-install-test:pom:1.0-SNAPSHOT", + "org.apache.maven.test:org.example.module:jar:1.0-SNAPSHOT"), + artifacts.stream().map(Artifact::key).toList()); + } + @Test @InjectMojo(goal = "install") void installIfArtifactFileIsNull(InstallMojo mojo) throws Exception {