1 package org.apache.maven.plugin.deploy;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.artifact.Artifact;
23 import org.apache.maven.artifact.ArtifactUtils;
24 import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
25 import org.apache.maven.artifact.metadata.ArtifactMetadata;
26 import org.apache.maven.artifact.repository.ArtifactRepository;
27 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
28 import org.apache.maven.plugin.MojoExecutionException;
29 import org.apache.maven.plugin.MojoFailureException;
30 import org.apache.maven.plugins.annotations.Component;
31 import org.apache.maven.plugins.annotations.LifecyclePhase;
32 import org.apache.maven.plugins.annotations.Mojo;
33 import org.apache.maven.plugins.annotations.Parameter;
34 import org.apache.maven.project.MavenProject;
35 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
36
37 import java.io.File;
38 import java.util.ArrayList;
39 import java.util.Collections;
40 import java.util.List;
41 import java.util.concurrent.atomic.AtomicInteger;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
44
45
46
47
48
49
50
51
52 @Mojo( name = "deploy", defaultPhase = LifecyclePhase.DEPLOY, threadSafe = true )
53 public class DeployMojo
54 extends AbstractDeployMojo
55 {
56
57 private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+)::(.+)::(.+)" );
58
59
60
61
62
63 private static final AtomicInteger readyProjectsCounter = new AtomicInteger();
64
65 private static final List<DeployRequest> deployRequests =
66 Collections.synchronizedList( new ArrayList<DeployRequest>() );
67
68
69
70 @Parameter( defaultValue = "${project}", readonly = true, required = true )
71 private MavenProject project;
72
73 @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
74 private List<MavenProject> reactorProjects;
75
76
77
78
79
80
81
82 @Parameter( defaultValue = "false", property = "deployAtEnd" )
83 private boolean deployAtEnd;
84
85
86
87
88 @Parameter( defaultValue = "${project.artifact}", required = true, readonly = true )
89 private Artifact artifact;
90
91
92
93
94 @Parameter( defaultValue = "${project.packaging}", required = true, readonly = true )
95 private String packaging;
96
97
98
99
100 @Parameter( defaultValue = "${project.file}", required = true, readonly = true )
101 private File pomFile;
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 @Parameter( property = "altDeploymentRepository" )
118 private String altDeploymentRepository;
119
120
121
122
123
124
125
126 @Parameter( property = "altSnapshotDeploymentRepository" )
127 private String altSnapshotDeploymentRepository;
128
129
130
131
132
133
134
135 @Parameter( property = "altReleaseDeploymentRepository" )
136 private String altReleaseDeploymentRepository;
137
138
139
140
141 @Parameter( defaultValue = "${project.attachedArtifacts}", required = true, readonly = true )
142 private List attachedArtifacts;
143
144
145
146
147
148
149 @Parameter( property = "maven.deploy.skip", defaultValue = "false" )
150 private boolean skip;
151
152 public void execute()
153 throws MojoExecutionException, MojoFailureException
154 {
155 boolean addedDeployRequest = false;
156 if ( skip )
157 {
158 getLog().info( "Skipping artifact deployment" );
159 }
160 else
161 {
162 failIfOffline();
163
164 DeployRequest currentExecutionDeployRequest =
165 new DeployRequest().setProject( project ).setUpdateReleaseInfo( isUpdateReleaseInfo() ).setRetryFailedDeploymentCount( getRetryFailedDeploymentCount() ).setAltReleaseDeploymentRepository( altReleaseDeploymentRepository ).setAltSnapshotDeploymentRepository( altSnapshotDeploymentRepository ).setAltDeploymentRepository( altDeploymentRepository );
166
167 if ( !deployAtEnd )
168 {
169 deployProject( currentExecutionDeployRequest );
170 }
171 else
172 {
173 deployRequests.add( currentExecutionDeployRequest );
174 addedDeployRequest = true;
175 }
176 }
177
178 boolean projectsReady = readyProjectsCounter.incrementAndGet() == reactorProjects.size();
179 if ( projectsReady )
180 {
181 synchronized ( deployRequests )
182 {
183 while ( !deployRequests.isEmpty() )
184 {
185 deployProject( deployRequests.remove( 0 ) );
186 }
187 }
188 }
189 else if ( addedDeployRequest )
190 {
191 getLog().info( "Deploying " + project.getGroupId() + ":" + project.getArtifactId() + ":"
192 + project.getVersion() + " at end" );
193 }
194 }
195
196 private void deployProject( DeployRequest request )
197 throws MojoExecutionException, MojoFailureException
198 {
199 Artifact artifact = request.getProject().getArtifact();
200 String packaging = request.getProject().getPackaging();
201 File pomFile = request.getProject().getFile();
202
203 @SuppressWarnings( "unchecked" )
204 List<Artifact> attachedArtifacts = request.getProject().getAttachedArtifacts();
205
206 ArtifactRepository repo =
207 getDeploymentRepository( request.getProject(), request.getAltDeploymentRepository(),
208 request.getAltReleaseDeploymentRepository(),
209 request.getAltSnapshotDeploymentRepository() );
210
211 String protocol = repo.getProtocol();
212
213 if ( protocol.equalsIgnoreCase( "scp" ) )
214 {
215 File sshFile = new File( System.getProperty( "user.home" ), ".ssh" );
216
217 if ( !sshFile.exists() )
218 {
219 sshFile.mkdirs();
220 }
221 }
222
223
224 boolean isPomArtifact = "pom".equals( packaging );
225 if ( !isPomArtifact )
226 {
227 ArtifactMetadata metadata = new ProjectArtifactMetadata( artifact, pomFile );
228 artifact.addMetadata( metadata );
229 }
230
231 if ( request.isUpdateReleaseInfo() )
232 {
233 artifact.setRelease( true );
234 }
235
236 int retryFailedDeploymentCount = request.getRetryFailedDeploymentCount();
237
238 try
239 {
240 if ( isPomArtifact )
241 {
242 deploy( pomFile, artifact, repo, getLocalRepository(), retryFailedDeploymentCount );
243 }
244 else
245 {
246 File file = artifact.getFile();
247
248 if ( file != null && file.isFile() )
249 {
250 deploy( file, artifact, repo, getLocalRepository(), retryFailedDeploymentCount );
251 }
252 else if ( !attachedArtifacts.isEmpty() )
253 {
254 getLog().info( "No primary artifact to deploy, deploying attached artifacts instead." );
255
256 Artifact pomArtifact =
257 artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
258 artifact.getBaseVersion() );
259 pomArtifact.setFile( pomFile );
260 if ( request.isUpdateReleaseInfo() )
261 {
262 pomArtifact.setRelease( true );
263 }
264
265 deploy( pomFile, pomArtifact, repo, getLocalRepository(), retryFailedDeploymentCount );
266
267
268 artifact.setResolvedVersion( pomArtifact.getVersion() );
269 }
270 else
271 {
272 String message = "The packaging for this project did not assign a file to the build artifact";
273 throw new MojoExecutionException( message );
274 }
275 }
276
277 for ( Artifact attached : attachedArtifacts )
278 {
279 deploy( attached.getFile(), attached, repo, getLocalRepository(), retryFailedDeploymentCount );
280 }
281 }
282 catch ( ArtifactDeploymentException e )
283 {
284 throw new MojoExecutionException( e.getMessage(), e );
285 }
286 }
287
288 ArtifactRepository getDeploymentRepository( MavenProject project, String altDeploymentRepository,
289 String altReleaseDeploymentRepository,
290 String altSnapshotDeploymentRepository )
291 throws MojoExecutionException, MojoFailureException
292 {
293 ArtifactRepository repo = null;
294
295 String altDeploymentRepo;
296 if ( ArtifactUtils.isSnapshot( project.getVersion() ) && altSnapshotDeploymentRepository != null )
297 {
298 altDeploymentRepo = altSnapshotDeploymentRepository;
299 }
300 else if ( !ArtifactUtils.isSnapshot( project.getVersion() ) && altReleaseDeploymentRepository != null )
301 {
302 altDeploymentRepo = altReleaseDeploymentRepository;
303 }
304 else
305 {
306 altDeploymentRepo = altDeploymentRepository;
307 }
308
309 if ( altDeploymentRepo != null )
310 {
311 getLog().info( "Using alternate deployment repository " + altDeploymentRepo );
312
313 Matcher matcher = ALT_REPO_SYNTAX_PATTERN.matcher( altDeploymentRepo );
314
315 if ( !matcher.matches() )
316 {
317 throw new MojoFailureException( altDeploymentRepo, "Invalid syntax for repository.",
318 "Invalid syntax for alternative repository. Use \"id::layout::url\"." );
319 }
320 else
321 {
322 String id = matcher.group( 1 ).trim();
323 String layout = matcher.group( 2 ).trim();
324 String url = matcher.group( 3 ).trim();
325
326 ArtifactRepositoryLayout repoLayout = getLayout( layout );
327
328 repo = repositoryFactory.createDeploymentArtifactRepository( id, url, repoLayout, true );
329 }
330 }
331
332 if ( repo == null )
333 {
334 repo = project.getDistributionManagementArtifactRepository();
335 }
336
337 if ( repo == null )
338 {
339 String msg =
340 "Deployment failed: repository element was not specified in the POM inside"
341 + " distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter";
342
343 throw new MojoExecutionException( msg );
344 }
345
346 return repo;
347 }
348
349 }