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 2022/07/03 18:18:42 UTC

[maven-deploy-plugin] branch master updated: [MDEPLOY-193] Deploy At End feature (no extension) (#20)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 89c28fb  [MDEPLOY-193] Deploy At End feature (no extension) (#20)
89c28fb is described below

commit 89c28fb8d095b7c76115124d868579a5d4529d0b
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Sun Jul 3 20:18:39 2022 +0200

    [MDEPLOY-193] Deploy At End feature (no extension) (#20)
    
    This PR makes deployAtEnd work as expected even
    if maven-deploy-plugin is not used as extension.
    
    How it works: it uses mojo Context to store "state markers" (and params):
    * presence of marker means project was "processed"
    * value of state marker tells what should be done
    * if needed, other params are stored as well
    
    UTs adjusted to provide plugin context (was null before).
---
 src/it/deploy-at-end-fail/verify.groovy            |   2 +-
 src/it/deploy-at-end-pass/verify.groovy            |   2 +-
 .../apache/maven/plugins/deploy/DeployMojo.java    | 147 +++++++++++++++------
 .../maven/plugins/deploy/DeployMojoTest.java       |  22 ++-
 4 files changed, 127 insertions(+), 46 deletions(-)

diff --git a/src/it/deploy-at-end-fail/verify.groovy b/src/it/deploy-at-end-fail/verify.groovy
index 03398e8..27d678a 100644
--- a/src/it/deploy-at-end-fail/verify.groovy
+++ b/src/it/deploy-at-end-fail/verify.groovy
@@ -22,5 +22,5 @@ assert !( new File( basedir, "module1/target/repo/org/apache/maven/its/deploy/da
 
 File buildLog = new File( basedir, 'build.log' )
 assert buildLog.exists()
-assert buildLog.text.contains( "[INFO] Deploying org.apache.maven.its.deploy.dae.fail:dae:1.0 at end" )
+assert buildLog.text.contains( "[INFO] Deferring deploy for org.apache.maven.its.deploy.dae.fail:dae:1.0 at end" )
 
diff --git a/src/it/deploy-at-end-pass/verify.groovy b/src/it/deploy-at-end-pass/verify.groovy
index d776935..634808a 100644
--- a/src/it/deploy-at-end-pass/verify.groovy
+++ b/src/it/deploy-at-end-pass/verify.groovy
@@ -22,5 +22,5 @@ assert new File( basedir, "module1/target/repo/org/apache/maven/its/deploy/dae/p
 
 File buildLog = new File( basedir, 'build.log' )
 assert buildLog.exists()
-assert buildLog.text.contains( "[INFO] Deploying org.apache.maven.its.deploy.dae.pass:dae:1.0 at end" )
+assert buildLog.text.contains( "[INFO] Deferring deploy for org.apache.maven.its.deploy.dae.pass:dae:1.0 at end" )
 
diff --git a/src/main/java/org/apache/maven/plugins/deploy/DeployMojo.java b/src/main/java/org/apache/maven/plugins/deploy/DeployMojo.java
index 4aaa971..bec6b38 100644
--- a/src/main/java/org/apache/maven/plugins/deploy/DeployMojo.java
+++ b/src/main/java/org/apache/maven/plugins/deploy/DeployMojo.java
@@ -19,10 +19,8 @@ package org.apache.maven.plugins.deploy;
  * under the License.
  */
 
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -30,6 +28,7 @@ import org.apache.maven.artifact.ArtifactUtils;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 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;
@@ -55,23 +54,15 @@ public class DeployMojo
 
     private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+?)::(.+)" );
 
-    /**
-     * When building with multiple threads, reaching the last project doesn't have to mean that all projects are ready
-     * to be deployed
-     */
-    private static final AtomicInteger READYPROJECTSCOUNTER = new AtomicInteger();
-
-    private static final List<ProjectDeployerRequest> DEPLOYREQUESTS =
-        Collections.synchronizedList( new ArrayList<ProjectDeployerRequest>() );
-
-    /**
-     */
     @Parameter( defaultValue = "${project}", readonly = true, required = true )
     private MavenProject project;
 
     @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
     private List<MavenProject> reactorProjects;
 
+    @Parameter( defaultValue = "${plugin}", required = true, readonly = true )
+    private PluginDescriptor pluginDescriptor;
+
     /**
      * Whether every project should be deployed during its own deploy-phase or at the end of the multimodule build. If
      * set to {@code true} and the build fails, none of the reactor projects is deployed.
@@ -143,63 +134,139 @@ public class DeployMojo
     @Component
     private ProjectDeployer projectDeployer;
 
+    private enum State
+    {
+        SKIPPED, DEPLOYED, TO_BE_DEPLOYED
+    }
+
+    private static final String DEPLOY_PROCESSED_MARKER = DeployMojo.class.getName() + ".processed";
+
+    private static final String DEPLOY_ALT_RELEASE_DEPLOYMENT_REPOSITORY =
+        DeployMojo.class.getName() + ".altReleaseDeploymentRepository";
+
+    private static final String DEPLOY_ALT_SNAPSHOT_DEPLOYMENT_REPOSITORY =
+        DeployMojo.class.getName() + ".altSnapshotDeploymentRepository";
+
+    private static final String DEPLOY_ALT_DEPLOYMENT_REPOSITORY =
+        DeployMojo.class.getName() + ".altDeploymentRepository";
+
+    private void putState( State state )
+    {
+        getPluginContext().put( DEPLOY_PROCESSED_MARKER, state.name() );
+    }
+
+    private void putPluginContextValue( String key, String value )
+    {
+        if ( value != null )
+        {
+            getPluginContext().put( key, value );
+        }
+    }
+
+    private String getPluginContextValue( Map<String, Object> pluginContext, String key )
+    {
+        return (String) pluginContext.get( key );
+    }
+
+    private State getState( Map<String, Object> pluginContext )
+    {
+        return State.valueOf( getPluginContextValue( pluginContext, DEPLOY_PROCESSED_MARKER ) );
+    }
+
+    private boolean hasState( MavenProject project )
+    {
+        Map<String, Object> pluginContext = getSession().getPluginContext( pluginDescriptor, project );
+        return pluginContext.containsKey( DEPLOY_PROCESSED_MARKER );
+    }
+
     public void execute()
         throws MojoExecutionException, MojoFailureException
     {
-        boolean addedDeployRequest = false;
         if ( Boolean.parseBoolean( skip )
             || ( "releases".equals( skip ) && !ArtifactUtils.isSnapshot( project.getVersion() ) )
             || ( "snapshots".equals( skip ) && ArtifactUtils.isSnapshot( project.getVersion() ) )
         )
         {
             getLog().info( "Skipping artifact deployment" );
+            putState( State.SKIPPED );
         }
         else
         {
             failIfOffline();
 
-            // CHECKSTYLE_OFF: LineLength
-            // @formatter:off
-            ProjectDeployerRequest pdr = new ProjectDeployerRequest()
-                .setProject( project )
-                .setRetryFailedDeploymentCount( getRetryFailedDeploymentCount() )
-                .setAltReleaseDeploymentRepository( altReleaseDeploymentRepository )
-                .setAltSnapshotDeploymentRepository( altSnapshotDeploymentRepository )
-                .setAltDeploymentRepository( altDeploymentRepository );
-            // @formatter:on
-            // CHECKSTYLE_ON: LineLength
-
-            ArtifactRepository repo = getDeploymentRepository( pdr );
-
             if ( !deployAtEnd )
             {
+                // CHECKSTYLE_OFF: LineLength
+                // @formatter:off
+                ProjectDeployerRequest pdr = new ProjectDeployerRequest()
+                        .setProject( project )
+                        .setRetryFailedDeploymentCount( getRetryFailedDeploymentCount() )
+                        .setAltReleaseDeploymentRepository( altReleaseDeploymentRepository )
+                        .setAltSnapshotDeploymentRepository( altSnapshotDeploymentRepository )
+                        .setAltDeploymentRepository( altDeploymentRepository );
+                // @formatter:on
+                // CHECKSTYLE_ON: LineLength
+
+                ArtifactRepository repo = getDeploymentRepository( pdr );
+
                 deployProject( getSession().getProjectBuildingRequest(), pdr, repo );
+                putState( State.DEPLOYED );
             }
             else
             {
-                DEPLOYREQUESTS.add( pdr );
-                addedDeployRequest = true;
+                putState( State.TO_BE_DEPLOYED );
+                putPluginContextValue( DEPLOY_ALT_RELEASE_DEPLOYMENT_REPOSITORY, altReleaseDeploymentRepository );
+                putPluginContextValue( DEPLOY_ALT_SNAPSHOT_DEPLOYMENT_REPOSITORY, altSnapshotDeploymentRepository );
+                putPluginContextValue( DEPLOY_ALT_DEPLOYMENT_REPOSITORY, altDeploymentRepository );
+                getLog().info( "Deferring deploy for " + getProjectReferenceId( project ) + " at end" );
             }
         }
 
-        boolean projectsReady = READYPROJECTSCOUNTER.incrementAndGet() == reactorProjects.size();
-        if ( projectsReady )
+        if ( allProjectsMarked() )
         {
-            synchronized ( DEPLOYREQUESTS )
+            for ( MavenProject reactorProject : reactorProjects )
             {
-                while ( !DEPLOYREQUESTS.isEmpty() )
+                Map<String, Object> pluginContext = getSession().getPluginContext( pluginDescriptor, reactorProject );
+                State state = getState( pluginContext );
+                if ( state == State.TO_BE_DEPLOYED )
                 {
-                    ArtifactRepository repo = getDeploymentRepository( DEPLOYREQUESTS.get( 0 ) );
-
-                    deployProject( getSession().getProjectBuildingRequest(), DEPLOYREQUESTS.remove( 0 ), repo );
+                    String altReleaseDeploymentRepository =
+                        getPluginContextValue( pluginContext, DEPLOY_ALT_RELEASE_DEPLOYMENT_REPOSITORY );
+                    String altSnapshotDeploymentRepository =
+                        getPluginContextValue( pluginContext, DEPLOY_ALT_SNAPSHOT_DEPLOYMENT_REPOSITORY );
+                    String altDeploymentRepository =
+                        getPluginContextValue( pluginContext, DEPLOY_ALT_DEPLOYMENT_REPOSITORY );
+
+                    ProjectDeployerRequest pdr = new ProjectDeployerRequest()
+                        .setProject( reactorProject )
+                        .setRetryFailedDeploymentCount( getRetryFailedDeploymentCount() )
+                        .setAltReleaseDeploymentRepository( altReleaseDeploymentRepository )
+                        .setAltSnapshotDeploymentRepository( altSnapshotDeploymentRepository )
+                        .setAltDeploymentRepository( altDeploymentRepository );
+
+                    ArtifactRepository repo = getDeploymentRepository( pdr );
+
+                    deployProject( getSession().getProjectBuildingRequest(), pdr, repo );
                 }
             }
         }
-        else if ( addedDeployRequest )
+    }
+
+    private String getProjectReferenceId( MavenProject mavenProject )
+    {
+        return mavenProject.getGroupId() + ":" + mavenProject.getArtifactId() + ":" + mavenProject.getVersion();
+    }
+
+    private boolean allProjectsMarked()
+    {
+        for ( MavenProject reactorProject : reactorProjects )
         {
-            getLog().info( "Deploying " + project.getGroupId() + ":" + project.getArtifactId() + ":"
-                + project.getVersion() + " at end" );
+            if ( !hasState( reactorProject ) )
+            {
+                return false;
+            }
         }
+        return true;
     }
 
     private void deployProject( ProjectBuildingRequest pbr, ProjectDeployerRequest pir, ArtifactRepository repo )
diff --git a/src/test/java/org/apache/maven/plugins/deploy/DeployMojoTest.java b/src/test/java/org/apache/maven/plugins/deploy/DeployMojoTest.java
index 6404f5a..c8350c4 100644
--- a/src/test/java/org/apache/maven/plugins/deploy/DeployMojoTest.java
+++ b/src/test/java/org/apache/maven/plugins/deploy/DeployMojoTest.java
@@ -19,6 +19,7 @@ package org.apache.maven.plugins.deploy;
  * under the License.
  */
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -28,11 +29,13 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.maven.artifact.repository.ArtifactRepository;
 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.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
 import org.apache.maven.plugins.deploy.stubs.ArtifactDeployerStub;
@@ -68,7 +71,6 @@ public class DeployMojoTest
     
     MavenProjectStub project = new MavenProjectStub();
 
-    @Mock
     private MavenSession session;
     
     @InjectMocks
@@ -78,7 +80,11 @@ public class DeployMojoTest
         throws Exception
     {
         super.setUp();
-        
+
+        session = mock( MavenSession.class );
+        when( session.getPluginContext(any(PluginDescriptor.class), any(MavenProject.class)))
+                .thenReturn( new ConcurrentHashMap<String, Object>() );
+
         remoteRepo = new File( REMOTE_REPO );
         
         remoteRepo.mkdirs();  
@@ -144,7 +150,8 @@ public class DeployMojoTest
         assertTrue( file.exists() );
 
         MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
-        
+
+        setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
         setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
         
         artifact = ( DeployArtifactStub ) project.getArtifact();
@@ -251,8 +258,11 @@ public class DeployMojoTest
         assertTrue( file.exists() );
 
         MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
-        
+
+        setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() );
+        setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
         setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
+        setVariableValueToObject( mojo, "session", session );
 
         artifact = (DeployArtifactStub) project.getArtifact();
 
@@ -316,6 +326,7 @@ public class DeployMojoTest
         
         MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
 
+        setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
         setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
 
         artifact = (DeployArtifactStub) project.getArtifact();
@@ -381,6 +392,7 @@ public class DeployMojoTest
         
         MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
 
+        setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
         setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
 
         artifact = (DeployArtifactStub) project.getArtifact();
@@ -422,6 +434,7 @@ public class DeployMojoTest
 
         MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
 
+        setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
         setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
 
         artifact = (DeployArtifactStub) project.getArtifact();
@@ -523,6 +536,7 @@ public class DeployMojoTest
         
         MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
 
+        setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
         setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
 
         artifact = (DeployArtifactStub) project.getArtifact();