diff --git a/pom.xml b/pom.xml index ca7b8764..ba7ae25e 100644 --- a/pom.xml +++ b/pom.xml @@ -63,8 +63,9 @@ - 3.0 - 7 + 3.2.5 + 1.7.32 + 8 2020-04-07T21:04:00Z @@ -73,13 +74,22 @@ org.apache.maven maven-plugin-api ${mavenVersion} + provided org.apache.maven maven-artifact ${mavenVersion} + provided + + + org.apache.maven + maven-core + ${mavenVersion} + provided + org.apache.maven.shared maven-artifact-transfer @@ -96,13 +106,13 @@ junit junit - 4.13.1 + 4.13.2 test org.apache.maven.plugin-testing maven-plugin-testing-harness - 2.1 + 3.3.0 test @@ -120,13 +130,31 @@ org.slf4j slf4j-api - 1.7.30 + ${slf4jVersion} provided org.slf4j slf4j-nop - 1.7.30 + ${slf4jVersion} + test + + + org.eclipse.aether + aether-api + 1.1.0 + test + + + org.eclipse.aether + aether-util + 1.1.0 + test + + + org.eclipse.aether + aether-impl + 1.1.0 test @@ -150,6 +178,7 @@ org.apache.maven.plugins maven-invoker-plugin + 3.2.2 ${project.build.directory}/it true 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 b01c1141..e4f098a5 100644 --- a/src/main/java/org/apache/maven/plugins/install/InstallMojo.java +++ b/src/main/java/org/apache/maven/plugins/install/InstallMojo.java @@ -20,19 +20,21 @@ */ import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.Map; +import java.util.concurrent.ConcurrentMap; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; -import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException; import org.apache.maven.shared.transfer.project.NoFileAssignedException; import org.apache.maven.shared.transfer.project.install.ProjectInstaller; @@ -48,24 +50,22 @@ public class InstallMojo extends AbstractInstallMojo { + private static final String INSTALL_REQUESTS_KEY = InstallMojo.class.getName() + ".installRequests"; - /** - * When building with multiple threads, reaching the last project doesn't have to mean that all projects are ready - * to be installed - */ - private static final AtomicInteger READYPROJECTSCOUNTER = new AtomicInteger(); - - private static final List INSTALLREQUESTS = - Collections.synchronizedList( new ArrayList() ); + private static final MavenProject SENTINEL = new MavenProject(); - /** - */ @Parameter( defaultValue = "${project}", readonly = true, required = true ) private MavenProject project; @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true ) private List reactorProjects; + @Parameter( defaultValue = "${session}", required = true, readonly = true ) + private MavenSession session; + + @Parameter( defaultValue = "${plugin}", required = true, readonly = true ) + private PluginDescriptor pluginDescriptor; + /** * Whether every project should be installed during its own install-phase or at the end of the multimodule build. If * set to {@code true} and the build fails, none of the reactor projects is installed. @@ -91,53 +91,60 @@ public class InstallMojo public void execute() throws MojoExecutionException, MojoFailureException { + + final String projectKey = project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion(); + final ConcurrentMap pluginContext = + (ConcurrentMap) session.getPluginContext( pluginDescriptor, reactorProjects.get( 0 ) ); + final Map installRequests = (Map) pluginContext.computeIfAbsent( + INSTALL_REQUESTS_KEY, + k -> Collections.synchronizedMap( new LinkedHashMap() ) + ); + boolean addedInstallRequest = false; if ( skip ) { + installRequests.put( projectKey, SENTINEL ); getLog().info( "Skipping artifact installation" ); } else { - // CHECKSTYLE_OFF: LineLength - ProjectInstallerRequest projectInstallerRequest = - new ProjectInstallerRequest().setProject( project ); - // CHECKSTYLE_ON: LineLength - if ( !installAtEnd ) { - installProject( session.getProjectBuildingRequest(), projectInstallerRequest ); + installProject( project ); } else { - INSTALLREQUESTS.add( projectInstallerRequest ); + installRequests.put( projectKey, project ); addedInstallRequest = true; } } - boolean projectsReady = READYPROJECTSCOUNTER.incrementAndGet() == reactorProjects.size(); - if ( projectsReady ) + if ( installRequests.size() == reactorProjects.size() ) { - synchronized ( INSTALLREQUESTS ) + for ( Map.Entry projectEntry : installRequests.entrySet() ) { - while ( !INSTALLREQUESTS.isEmpty() ) + if ( projectEntry.getValue() == SENTINEL ) + { + getLog().info( "Project " + projectKey + " skipped install" ); + } + else { - installProject( session.getProjectBuildingRequest(), INSTALLREQUESTS.remove( 0 ) ); + installProject( projectEntry.getValue() ); } } } else if ( addedInstallRequest ) { - getLog().info( "Installing " + project.getGroupId() + ":" + project.getArtifactId() + ":" - + project.getVersion() + " at end" ); + getLog().info( "Installing " + projectKey + " at end" ); } } - private void installProject( ProjectBuildingRequest pbr, ProjectInstallerRequest pir ) + private void installProject( MavenProject pir ) throws MojoFailureException, MojoExecutionException { try { - installer.install( session.getProjectBuildingRequest(), pir ); + installer.install( session.getProjectBuildingRequest(), new ProjectInstallerRequest().setProject( pir ) ); } catch ( IOException e ) { diff --git a/src/test/java/org/apache/maven/plugins/install/InstallFileMojoTest.java b/src/test/java/org/apache/maven/plugins/install/InstallFileMojoTest.java index 8b3b070b..d04b1b14 100644 --- a/src/test/java/org/apache/maven/plugins/install/InstallFileMojoTest.java +++ b/src/test/java/org/apache/maven/plugins/install/InstallFileMojoTest.java @@ -21,18 +21,20 @@ import java.io.File; import java.io.Reader; +import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.plugin.testing.AbstractMojoTestCase; -import org.apache.maven.plugins.install.InstallFileMojo; import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.shared.utils.ReaderFactory; import org.apache.maven.shared.utils.io.FileUtils; -import org.sonatype.aether.impl.internal.EnhancedLocalRepositoryManager; -import org.sonatype.aether.util.DefaultRepositorySystemSession; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.NoLocalRepositoryManagerException; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -215,7 +217,9 @@ public void testInstallFileWithPomAsPackaging() InstallFileMojo mojo = (InstallFileMojo) lookupMojo( "install-file", testPom ); assertNotNull( mojo ); - + + setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() ); + setVariableValueToObject( mojo, "session", createMavenSession() ); assignValuesForParameter( mojo ); @@ -243,7 +247,9 @@ public void testInstallFile() InstallFileMojo mojo = (InstallFileMojo) lookupMojo( "install-file", testPom ); assertNotNull( mojo ); - + + setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() ); + setVariableValueToObject( mojo, "session", createMavenSession() ); assignValuesForParameter( mojo ); @@ -281,11 +287,11 @@ private String dotToSlashReplacer( String parameter ) return parameter.replace( '.', '/' ); } - private MavenSession createMavenSession() + private MavenSession createMavenSession() throws NoLocalRepositoryManagerException { MavenSession session = mock( MavenSession.class ); DefaultRepositorySystemSession repositorySession = new DefaultRepositorySystemSession(); - repositorySession.setLocalRepositoryManager( new EnhancedLocalRepositoryManager( new File( LOCAL_REPO ) ) ); + repositorySession.setLocalRepositoryManager( new EnhancedLocalRepositoryManagerFactory().newInstance( repositorySession, new LocalRepository( LOCAL_REPO )) ); ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(); buildingRequest.setRepositorySession( repositorySession ); when( session.getProjectBuildingRequest() ).thenReturn( buildingRequest ); 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 63ac6fa9..5d0ed3c7 100644 --- a/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java +++ b/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java @@ -19,17 +19,20 @@ * under the License. */ +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.File; import java.util.Collections; import java.util.List; +import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.testing.AbstractMojoTestCase; import org.apache.maven.plugins.install.stubs.AttachedArtifactStub0; import org.apache.maven.plugins.install.stubs.InstallArtifactStub; @@ -38,8 +41,10 @@ import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.shared.transfer.repository.RepositoryManager; import org.apache.maven.shared.utils.io.FileUtils; -import org.sonatype.aether.impl.internal.EnhancedLocalRepositoryManager; -import org.sonatype.aether.util.DefaultRepositorySystemSession; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.NoLocalRepositoryManagerException; /** * @author Allan Ramirez @@ -85,7 +90,8 @@ public void testBasicInstall() MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" ); updateMavenProject( project ); - + + setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() ); setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) ); setVariableValueToObject( mojo, "session", createMavenSession() ); @@ -118,6 +124,7 @@ public void testBasicInstallWithAttachedArtifacts() MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" ); updateMavenProject( project ); + setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() ); setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) ); setVariableValueToObject( mojo, "session", createMavenSession() ); @@ -160,6 +167,7 @@ public void testUpdateReleaseParamSetToTrue() MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" ); updateMavenProject( project ); + setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() ); setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) ); setVariableValueToObject( mojo, "session", createMavenSession() ); @@ -186,6 +194,7 @@ public void testInstallIfArtifactFileIsNull() MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" ); updateMavenProject( project ); + setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() ); setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) ); setVariableValueToObject( mojo, "session", createMavenSession() ); @@ -222,6 +231,7 @@ public void testInstallIfPackagingIsPom() MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" ); updateMavenProject( project ); + setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() ); setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) ); setVariableValueToObject( mojo, "session", createMavenSession() ); @@ -258,6 +268,7 @@ public void testBasicInstallAndCreate() MavenSession mavenSession = createMavenSession(); updateMavenProject( project ); + setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() ); setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) ); setVariableValueToObject( mojo, "session", mavenSession ); @@ -314,6 +325,7 @@ public void testSkip() MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" ); updateMavenProject( project ); + setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() ); setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) ); setVariableValueToObject( mojo, "session", createMavenSession() ); @@ -343,14 +355,15 @@ private String dotToSlashReplacer( String parameter ) return parameter.replace( '.', '/' ); } - private MavenSession createMavenSession() + private MavenSession createMavenSession() throws NoLocalRepositoryManagerException { MavenSession session = mock( MavenSession.class ); DefaultRepositorySystemSession repositorySession = new DefaultRepositorySystemSession(); - repositorySession.setLocalRepositoryManager( new EnhancedLocalRepositoryManager( new File( LOCAL_REPO ) ) ); + repositorySession.setLocalRepositoryManager( new EnhancedLocalRepositoryManagerFactory().newInstance( repositorySession, new LocalRepository( LOCAL_REPO )) ); ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(); buildingRequest.setRepositorySession( repositorySession ); when( session.getProjectBuildingRequest() ).thenReturn( buildingRequest ); + when( session.getPluginContext(any(PluginDescriptor.class), any(MavenProject.class))).thenReturn( new ConcurrentHashMap<>() ); return session; }