Skip to content

Commit 89c28fb

Browse files
authored
[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).
1 parent dd39f5d commit 89c28fb

File tree

4 files changed

+127
-46
lines changed

4 files changed

+127
-46
lines changed

src/it/deploy-at-end-fail/verify.groovy

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ assert !( new File( basedir, "module1/target/repo/org/apache/maven/its/deploy/da
2222

2323
File buildLog = new File( basedir, 'build.log' )
2424
assert buildLog.exists()
25-
assert buildLog.text.contains( "[INFO] Deploying org.apache.maven.its.deploy.dae.fail:dae:1.0 at end" )
25+
assert buildLog.text.contains( "[INFO] Deferring deploy for org.apache.maven.its.deploy.dae.fail:dae:1.0 at end" )
2626

src/it/deploy-at-end-pass/verify.groovy

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ assert new File( basedir, "module1/target/repo/org/apache/maven/its/deploy/dae/p
2222

2323
File buildLog = new File( basedir, 'build.log' )
2424
assert buildLog.exists()
25-
assert buildLog.text.contains( "[INFO] Deploying org.apache.maven.its.deploy.dae.pass:dae:1.0 at end" )
25+
assert buildLog.text.contains( "[INFO] Deferring deploy for org.apache.maven.its.deploy.dae.pass:dae:1.0 at end" )
2626

src/main/java/org/apache/maven/plugins/deploy/DeployMojo.java

+107-40
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,16 @@
1919
* under the License.
2020
*/
2121

22-
import java.util.ArrayList;
23-
import java.util.Collections;
2422
import java.util.List;
25-
import java.util.concurrent.atomic.AtomicInteger;
23+
import java.util.Map;
2624
import java.util.regex.Matcher;
2725
import java.util.regex.Pattern;
2826

2927
import org.apache.maven.artifact.ArtifactUtils;
3028
import org.apache.maven.artifact.repository.ArtifactRepository;
3129
import org.apache.maven.plugin.MojoExecutionException;
3230
import org.apache.maven.plugin.MojoFailureException;
31+
import org.apache.maven.plugin.descriptor.PluginDescriptor;
3332
import org.apache.maven.plugins.annotations.Component;
3433
import org.apache.maven.plugins.annotations.LifecyclePhase;
3534
import org.apache.maven.plugins.annotations.Mojo;
@@ -55,23 +54,15 @@ public class DeployMojo
5554

5655
private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+?)::(.+)" );
5756

58-
/**
59-
* When building with multiple threads, reaching the last project doesn't have to mean that all projects are ready
60-
* to be deployed
61-
*/
62-
private static final AtomicInteger READYPROJECTSCOUNTER = new AtomicInteger();
63-
64-
private static final List<ProjectDeployerRequest> DEPLOYREQUESTS =
65-
Collections.synchronizedList( new ArrayList<ProjectDeployerRequest>() );
66-
67-
/**
68-
*/
6957
@Parameter( defaultValue = "${project}", readonly = true, required = true )
7058
private MavenProject project;
7159

7260
@Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
7361
private List<MavenProject> reactorProjects;
7462

63+
@Parameter( defaultValue = "${plugin}", required = true, readonly = true )
64+
private PluginDescriptor pluginDescriptor;
65+
7566
/**
7667
* Whether every project should be deployed during its own deploy-phase or at the end of the multimodule build. If
7768
* set to {@code true} and the build fails, none of the reactor projects is deployed.
@@ -143,63 +134,139 @@ public class DeployMojo
143134
@Component
144135
private ProjectDeployer projectDeployer;
145136

137+
private enum State
138+
{
139+
SKIPPED, DEPLOYED, TO_BE_DEPLOYED
140+
}
141+
142+
private static final String DEPLOY_PROCESSED_MARKER = DeployMojo.class.getName() + ".processed";
143+
144+
private static final String DEPLOY_ALT_RELEASE_DEPLOYMENT_REPOSITORY =
145+
DeployMojo.class.getName() + ".altReleaseDeploymentRepository";
146+
147+
private static final String DEPLOY_ALT_SNAPSHOT_DEPLOYMENT_REPOSITORY =
148+
DeployMojo.class.getName() + ".altSnapshotDeploymentRepository";
149+
150+
private static final String DEPLOY_ALT_DEPLOYMENT_REPOSITORY =
151+
DeployMojo.class.getName() + ".altDeploymentRepository";
152+
153+
private void putState( State state )
154+
{
155+
getPluginContext().put( DEPLOY_PROCESSED_MARKER, state.name() );
156+
}
157+
158+
private void putPluginContextValue( String key, String value )
159+
{
160+
if ( value != null )
161+
{
162+
getPluginContext().put( key, value );
163+
}
164+
}
165+
166+
private String getPluginContextValue( Map<String, Object> pluginContext, String key )
167+
{
168+
return (String) pluginContext.get( key );
169+
}
170+
171+
private State getState( Map<String, Object> pluginContext )
172+
{
173+
return State.valueOf( getPluginContextValue( pluginContext, DEPLOY_PROCESSED_MARKER ) );
174+
}
175+
176+
private boolean hasState( MavenProject project )
177+
{
178+
Map<String, Object> pluginContext = getSession().getPluginContext( pluginDescriptor, project );
179+
return pluginContext.containsKey( DEPLOY_PROCESSED_MARKER );
180+
}
181+
146182
public void execute()
147183
throws MojoExecutionException, MojoFailureException
148184
{
149-
boolean addedDeployRequest = false;
150185
if ( Boolean.parseBoolean( skip )
151186
|| ( "releases".equals( skip ) && !ArtifactUtils.isSnapshot( project.getVersion() ) )
152187
|| ( "snapshots".equals( skip ) && ArtifactUtils.isSnapshot( project.getVersion() ) )
153188
)
154189
{
155190
getLog().info( "Skipping artifact deployment" );
191+
putState( State.SKIPPED );
156192
}
157193
else
158194
{
159195
failIfOffline();
160196

161-
// CHECKSTYLE_OFF: LineLength
162-
// @formatter:off
163-
ProjectDeployerRequest pdr = new ProjectDeployerRequest()
164-
.setProject( project )
165-
.setRetryFailedDeploymentCount( getRetryFailedDeploymentCount() )
166-
.setAltReleaseDeploymentRepository( altReleaseDeploymentRepository )
167-
.setAltSnapshotDeploymentRepository( altSnapshotDeploymentRepository )
168-
.setAltDeploymentRepository( altDeploymentRepository );
169-
// @formatter:on
170-
// CHECKSTYLE_ON: LineLength
171-
172-
ArtifactRepository repo = getDeploymentRepository( pdr );
173-
174197
if ( !deployAtEnd )
175198
{
199+
// CHECKSTYLE_OFF: LineLength
200+
// @formatter:off
201+
ProjectDeployerRequest pdr = new ProjectDeployerRequest()
202+
.setProject( project )
203+
.setRetryFailedDeploymentCount( getRetryFailedDeploymentCount() )
204+
.setAltReleaseDeploymentRepository( altReleaseDeploymentRepository )
205+
.setAltSnapshotDeploymentRepository( altSnapshotDeploymentRepository )
206+
.setAltDeploymentRepository( altDeploymentRepository );
207+
// @formatter:on
208+
// CHECKSTYLE_ON: LineLength
209+
210+
ArtifactRepository repo = getDeploymentRepository( pdr );
211+
176212
deployProject( getSession().getProjectBuildingRequest(), pdr, repo );
213+
putState( State.DEPLOYED );
177214
}
178215
else
179216
{
180-
DEPLOYREQUESTS.add( pdr );
181-
addedDeployRequest = true;
217+
putState( State.TO_BE_DEPLOYED );
218+
putPluginContextValue( DEPLOY_ALT_RELEASE_DEPLOYMENT_REPOSITORY, altReleaseDeploymentRepository );
219+
putPluginContextValue( DEPLOY_ALT_SNAPSHOT_DEPLOYMENT_REPOSITORY, altSnapshotDeploymentRepository );
220+
putPluginContextValue( DEPLOY_ALT_DEPLOYMENT_REPOSITORY, altDeploymentRepository );
221+
getLog().info( "Deferring deploy for " + getProjectReferenceId( project ) + " at end" );
182222
}
183223
}
184224

185-
boolean projectsReady = READYPROJECTSCOUNTER.incrementAndGet() == reactorProjects.size();
186-
if ( projectsReady )
225+
if ( allProjectsMarked() )
187226
{
188-
synchronized ( DEPLOYREQUESTS )
227+
for ( MavenProject reactorProject : reactorProjects )
189228
{
190-
while ( !DEPLOYREQUESTS.isEmpty() )
229+
Map<String, Object> pluginContext = getSession().getPluginContext( pluginDescriptor, reactorProject );
230+
State state = getState( pluginContext );
231+
if ( state == State.TO_BE_DEPLOYED )
191232
{
192-
ArtifactRepository repo = getDeploymentRepository( DEPLOYREQUESTS.get( 0 ) );
193-
194-
deployProject( getSession().getProjectBuildingRequest(), DEPLOYREQUESTS.remove( 0 ), repo );
233+
String altReleaseDeploymentRepository =
234+
getPluginContextValue( pluginContext, DEPLOY_ALT_RELEASE_DEPLOYMENT_REPOSITORY );
235+
String altSnapshotDeploymentRepository =
236+
getPluginContextValue( pluginContext, DEPLOY_ALT_SNAPSHOT_DEPLOYMENT_REPOSITORY );
237+
String altDeploymentRepository =
238+
getPluginContextValue( pluginContext, DEPLOY_ALT_DEPLOYMENT_REPOSITORY );
239+
240+
ProjectDeployerRequest pdr = new ProjectDeployerRequest()
241+
.setProject( reactorProject )
242+
.setRetryFailedDeploymentCount( getRetryFailedDeploymentCount() )
243+
.setAltReleaseDeploymentRepository( altReleaseDeploymentRepository )
244+
.setAltSnapshotDeploymentRepository( altSnapshotDeploymentRepository )
245+
.setAltDeploymentRepository( altDeploymentRepository );
246+
247+
ArtifactRepository repo = getDeploymentRepository( pdr );
248+
249+
deployProject( getSession().getProjectBuildingRequest(), pdr, repo );
195250
}
196251
}
197252
}
198-
else if ( addedDeployRequest )
253+
}
254+
255+
private String getProjectReferenceId( MavenProject mavenProject )
256+
{
257+
return mavenProject.getGroupId() + ":" + mavenProject.getArtifactId() + ":" + mavenProject.getVersion();
258+
}
259+
260+
private boolean allProjectsMarked()
261+
{
262+
for ( MavenProject reactorProject : reactorProjects )
199263
{
200-
getLog().info( "Deploying " + project.getGroupId() + ":" + project.getArtifactId() + ":"
201-
+ project.getVersion() + " at end" );
264+
if ( !hasState( reactorProject ) )
265+
{
266+
return false;
267+
}
202268
}
269+
return true;
203270
}
204271

205272
private void deployProject( ProjectBuildingRequest pbr, ProjectDeployerRequest pir, ArtifactRepository repo )

src/test/java/org/apache/maven/plugins/deploy/DeployMojoTest.java

+18-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* under the License.
2020
*/
2121

22+
import static org.mockito.ArgumentMatchers.any;
2223
import static org.mockito.Mockito.mock;
2324
import static org.mockito.Mockito.spy;
2425
import static org.mockito.Mockito.when;
@@ -28,11 +29,13 @@
2829
import java.util.Collections;
2930
import java.util.List;
3031
import java.util.Properties;
32+
import java.util.concurrent.ConcurrentHashMap;
3133

3234
import org.apache.maven.artifact.repository.ArtifactRepository;
3335
import org.apache.maven.execution.MavenSession;
3436
import org.apache.maven.plugin.MojoExecutionException;
3537
import org.apache.maven.plugin.MojoFailureException;
38+
import org.apache.maven.plugin.descriptor.PluginDescriptor;
3639
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
3740
import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
3841
import org.apache.maven.plugins.deploy.stubs.ArtifactDeployerStub;
@@ -68,7 +71,6 @@ public class DeployMojoTest
6871

6972
MavenProjectStub project = new MavenProjectStub();
7073

71-
@Mock
7274
private MavenSession session;
7375

7476
@InjectMocks
@@ -78,7 +80,11 @@ public void setUp()
7880
throws Exception
7981
{
8082
super.setUp();
81-
83+
84+
session = mock( MavenSession.class );
85+
when( session.getPluginContext(any(PluginDescriptor.class), any(MavenProject.class)))
86+
.thenReturn( new ConcurrentHashMap<String, Object>() );
87+
8288
remoteRepo = new File( REMOTE_REPO );
8389

8490
remoteRepo.mkdirs();
@@ -144,7 +150,8 @@ public void testBasicDeploy()
144150
assertTrue( file.exists() );
145151

146152
MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
147-
153+
154+
setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
148155
setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
149156

150157
artifact = ( DeployArtifactStub ) project.getArtifact();
@@ -251,8 +258,11 @@ public void testSkippingDeploy()
251258
assertTrue( file.exists() );
252259

253260
MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
254-
261+
262+
setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() );
263+
setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
255264
setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
265+
setVariableValueToObject( mojo, "session", session );
256266

257267
artifact = (DeployArtifactStub) project.getArtifact();
258268

@@ -316,6 +326,7 @@ public void testBasicDeployWithPackagingAsPom()
316326

317327
MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
318328

329+
setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
319330
setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
320331

321332
artifact = (DeployArtifactStub) project.getArtifact();
@@ -381,6 +392,7 @@ public void testDeployIfArtifactFileIsNull()
381392

382393
MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
383394

395+
setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
384396
setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
385397

386398
artifact = (DeployArtifactStub) project.getArtifact();
@@ -422,6 +434,7 @@ public void testDeployWithAttachedArtifacts()
422434

423435
MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
424436

437+
setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
425438
setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
426439

427440
artifact = (DeployArtifactStub) project.getArtifact();
@@ -523,6 +536,7 @@ public void _testBasicDeployWithScpAsProtocol()
523536

524537
MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
525538

539+
setVariableValueToObject( mojo, "pluginContext", new ConcurrentHashMap<>() );
526540
setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) );
527541

528542
artifact = (DeployArtifactStub) project.getArtifact();

0 commit comments

Comments
 (0)