You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by cs...@apache.org on 2021/10/07 07:25:27 UTC

[maven-install-plugin] 01/02: Install At End feature (no extension)

This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a commit to branch install-at-end
in repository https://gitbox.apache.org/repos/asf/maven-install-plugin.git

commit 06d10f9f0a5041e0dc667320b032e3963df91717
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Thu Oct 7 09:21:44 2021 +0200

    Install At End feature (no extension)
    
    This PR makes installAtEnd work as expected even
    if maven-install-plugin is not used as extension.
    
    How it works: it uses mojo Context to store "markers":
    * presence of marker means project was "processed"
    * value of marker tells what should be done (true = install, false = skipped)
    
    UTs adjusted to provide plugin context (was null before).
---
 pom.xml                                            | 41 ++++++++++--
 .../apache/maven/plugins/install/InstallMojo.java  | 72 ++++++++++++----------
 .../maven/plugins/install/InstallFileMojoTest.java | 20 +++---
 .../maven/plugins/install/InstallMojoTest.java     | 24 ++++++--
 4 files changed, 108 insertions(+), 49 deletions(-)

diff --git a/pom.xml b/pom.xml
index ca7b876..ba7ae25 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,8 +63,9 @@
   </distributionManagement>
 
   <properties>
-    <mavenVersion>3.0</mavenVersion>
-    <javaVersion>7</javaVersion>
+    <mavenVersion>3.2.5</mavenVersion>
+    <slf4jVersion>1.7.32</slf4jVersion>
+    <javaVersion>8</javaVersion>
     <project.build.outputTimestamp>2020-04-07T21:04:00Z</project.build.outputTimestamp>
   </properties>
 
@@ -73,13 +74,22 @@
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-plugin-api</artifactId>
       <version>${mavenVersion}</version>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-artifact</artifactId>
       <version>${mavenVersion}</version>
+      <scope>provided</scope>
     </dependency>
 
+    <!-- This is here to override 3.0 coming with maven-artifact-transfer -->
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-core</artifactId>
+      <version>${mavenVersion}</version>
+      <scope>provided</scope>
+    </dependency>
     <dependency>
       <groupId>org.apache.maven.shared</groupId>
       <artifactId>maven-artifact-transfer</artifactId>
@@ -96,13 +106,13 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.13.1</version>
+      <version>4.13.2</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.maven.plugin-testing</groupId>
       <artifactId>maven-plugin-testing-harness</artifactId>
-      <version>2.1</version>
+      <version>3.3.0</version>
       <scope>test</scope>
     </dependency>
     <dependency> <!-- used by maven-plugin-testing-harness, don't give it compile scope! -->
@@ -120,13 +130,31 @@
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
-      <version>1.7.30</version>
+      <version>${slf4jVersion}</version>
       <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-nop</artifactId>
-      <version>1.7.30</version>
+      <version>${slf4jVersion}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.aether</groupId>
+      <artifactId>aether-api</artifactId>
+      <version>1.1.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.aether</groupId>
+      <artifactId>aether-util</artifactId>
+      <version>1.1.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.aether</groupId>
+      <artifactId>aether-impl</artifactId>
+      <version>1.1.0</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
@@ -150,6 +178,7 @@
             <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-invoker-plugin</artifactId>
+              <version>3.2.2</version>
               <configuration>
                 <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
                 <cloneClean>true</cloneClean>
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 b01c114..080bafa 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,18 @@ package org.apache.maven.plugins.install;
  */
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.Map;
 
+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 +47,20 @@ import org.apache.maven.shared.transfer.project.install.ProjectInstallerRequest;
 public class InstallMojo
     extends AbstractInstallMojo
 {
+    private static final String INSTALL_PROCESSED_MARKER = InstallMojo.class.getName() + ".processed";
 
-    /**
-     * 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<ProjectInstallerRequest> INSTALLREQUESTS =
-        Collections.synchronizedList( new ArrayList<ProjectInstallerRequest>() );
-
-    /**
-     */
     @Parameter( defaultValue = "${project}", readonly = true, required = true )
     private MavenProject project;
 
     @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
     private List<MavenProject> 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 +86,68 @@ public class InstallMojo
     public void execute()
         throws MojoExecutionException, MojoFailureException
     {
+
+        final String projectKey = project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion();
         boolean addedInstallRequest = false;
         if ( skip )
         {
+            getPluginContext().put( INSTALL_PROCESSED_MARKER, Boolean.FALSE );
             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 );
+                getPluginContext().put( INSTALL_PROCESSED_MARKER, Boolean.TRUE );
                 addedInstallRequest = true;
             }
         }
 
-        boolean projectsReady = READYPROJECTSCOUNTER.incrementAndGet() == reactorProjects.size();
-        if ( projectsReady )
+        if ( allProjectsMarked() )
         {
-            synchronized ( INSTALLREQUESTS )
+            for ( MavenProject reactorProject : reactorProjects )
             {
-                while ( !INSTALLREQUESTS.isEmpty() )
+                Map<String, Object> pluginContext = session.getPluginContext( pluginDescriptor, reactorProject );
+                Boolean install = (Boolean) pluginContext.get( INSTALL_PROCESSED_MARKER );
+                if ( !install )
                 {
-                    installProject( session.getProjectBuildingRequest(), INSTALLREQUESTS.remove( 0 ) );
+                    getLog().info( "Project " + projectKey + " skipped install" );
+                }
+                else
+                {
+                    installProject( reactorProject );
                 }
             }
         }
         else if ( addedInstallRequest )
         {
-            getLog().info( "Installing " + project.getGroupId() + ":" + project.getArtifactId() + ":"
-                + project.getVersion() + " at end" );
+            getLog().info( "Installing " + projectKey + " at end" );
+        }
+    }
+
+    private boolean allProjectsMarked()
+    {
+        for ( MavenProject reactorProject : reactorProjects )
+        {
+            Map<String, Object> pluginContext = session.getPluginContext( pluginDescriptor, reactorProject );
+            if ( !pluginContext.containsKey( INSTALL_PROCESSED_MARKER ) )
+            {
+                return false;
+            }
         }
+        return true;
     }
 
-    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 8b3b070..d04b1b1 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 @@ package org.apache.maven.plugins.install;
 
 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 class InstallFileMojoTest
         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 class InstallFileMojoTest
         InstallFileMojo mojo = (InstallFileMojo) lookupMojo( "install-file", testPom );
 
         assertNotNull( mojo );
-        
+
+        setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
+
         setVariableValueToObject( mojo, "session", createMavenSession() );
 
         assignValuesForParameter( mojo );
@@ -281,11 +287,11 @@ public class InstallFileMojoTest
         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 63ac6fa..6abd82b 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 @@ package org.apache.maven.plugins.install;
  * 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.MavenProject;
 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 <a href="mailto:aramirez@apache.org">Allan Ramirez</a>
@@ -85,7 +90,8 @@ public class InstallMojoTest
 
         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 class InstallMojoTest
         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 class InstallMojoTest
         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 class InstallMojoTest
         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 class InstallMojoTest
         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 class InstallMojoTest
         MavenSession mavenSession = createMavenSession();
         updateMavenProject( project );
 
+        setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() );
         setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
         setVariableValueToObject( mojo, "session", mavenSession );
 
@@ -314,6 +325,8 @@ public class InstallMojoTest
         MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
         updateMavenProject( project );
 
+        setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
+        setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() );
         setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
         setVariableValueToObject( mojo, "session", createMavenSession() );
 
@@ -343,14 +356,15 @@ public class InstallMojoTest
         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;
     }