View Javadoc
1   package org.apache.maven.plugins.deploy;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.List;
25  import java.util.concurrent.atomic.AtomicInteger;
26  import java.util.regex.Matcher;
27  import java.util.regex.Pattern;
28  
29  import org.apache.maven.artifact.ArtifactUtils;
30  import org.apache.maven.artifact.repository.ArtifactRepository;
31  import org.apache.maven.plugin.MojoExecutionException;
32  import org.apache.maven.plugin.MojoFailureException;
33  import org.apache.maven.plugins.annotations.Component;
34  import org.apache.maven.plugins.annotations.LifecyclePhase;
35  import org.apache.maven.plugins.annotations.Mojo;
36  import org.apache.maven.plugins.annotations.Parameter;
37  import org.apache.maven.project.MavenProject;
38  import org.apache.maven.project.ProjectBuildingRequest;
39  import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
40  import org.apache.maven.shared.transfer.project.NoFileAssignedException;
41  import org.apache.maven.shared.transfer.project.deploy.ProjectDeployer;
42  import org.apache.maven.shared.transfer.project.deploy.ProjectDeployerRequest;
43  
44  /**
45   * Deploys an artifact to remote repository.
46   * 
47   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
48   * @author <a href="mailto:jdcasey@apache.org">John Casey (refactoring only)</a>
49   * @version $Id$
50   */
51  @Mojo( name = "deploy", defaultPhase = LifecyclePhase.DEPLOY, threadSafe = true )
52  public class DeployMojo
53      extends AbstractDeployMojo
54  {
55  
56      private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+)::(.+)" );
57  
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       */
69      @Parameter( defaultValue = "${project}", readonly = true, required = true )
70      private MavenProject project;
71  
72      @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
73      private List<MavenProject> reactorProjects;
74  
75      /**
76       * Whether every project should be deployed during its own deploy-phase or at the end of the multimodule build. If
77       * set to {@code true} and the build fails, none of the reactor projects is deployed.
78       * <strong>(experimental)</strong>
79       * 
80       * @since 2.8
81       */
82      @Parameter( defaultValue = "false", property = "deployAtEnd" )
83      private boolean deployAtEnd;
84  
85      /**
86       * Specifies an alternative repository to which the project artifacts should be deployed ( other than those
87       * specified in &lt;distributionManagement&gt; ). <br/>
88       * Format: id::layout::url
89       * <dl>
90       * <dt>id</dt>
91       * <dd>The id can be used to pick up the correct credentials from the settings.xml</dd>
92       * <dt>url</dt>
93       * <dd>The location of the repository</dd>
94       * </dl>
95       * <b>Note: Since 3.0.0 the layout part has been removed.</b>
96       */
97      @Parameter( property = "altDeploymentRepository" )
98      private String altDeploymentRepository;
99  
100     /**
101      * The alternative repository to use when the project has a snapshot version.
102      * 
103      * @since 2.8
104      * @see DeployMojo#altDeploymentRepository
105      */
106     @Parameter( property = "altSnapshotDeploymentRepository" )
107     private String altSnapshotDeploymentRepository;
108 
109     /**
110      * The alternative repository to use when the project has a final version.
111      * 
112      * @since 2.8
113      * @see DeployMojo#altDeploymentRepository
114      */
115     @Parameter( property = "altReleaseDeploymentRepository" )
116     private String altReleaseDeploymentRepository;
117 
118     /**
119      * Set this to 'true' to bypass artifact deploy
120      * 
121      * @since 2.4
122      */
123     @Parameter( property = "maven.deploy.skip", defaultValue = "false" )
124     private boolean skip;
125 
126     /**
127      * Component used to deploy project.
128      */
129     @Component
130     private ProjectDeployer projectDeployer;
131 
132     public void execute()
133         throws MojoExecutionException, MojoFailureException
134     {
135         boolean addedDeployRequest = false;
136         if ( skip )
137         {
138             getLog().info( "Skipping artifact deployment" );
139         }
140         else
141         {
142             failIfOffline();
143 
144             // CHECKSTYLE_OFF: LineLength
145             // @formatter:off
146             ProjectDeployerRequest pdr = new ProjectDeployerRequest()
147                 .setProject( project )
148                 .setRetryFailedDeploymentCount( getRetryFailedDeploymentCount() )
149                 .setAltReleaseDeploymentRepository( altReleaseDeploymentRepository )
150                 .setAltSnapshotDeploymentRepository( altSnapshotDeploymentRepository )
151                 .setAltDeploymentRepository( altDeploymentRepository );
152             // @formatter:on
153             // CHECKSTYLE_ON: LineLength
154 
155             ArtifactRepository repo = getDeploymentRepository( pdr );
156 
157             if ( !deployAtEnd )
158             {
159                 deployProject( getSession().getProjectBuildingRequest(), pdr, repo );
160             }
161             else
162             {
163                 DEPLOYREQUESTS.add( pdr );
164                 addedDeployRequest = true;
165             }
166         }
167 
168         boolean projectsReady = READYPROJECTSCOUNTER.incrementAndGet() == reactorProjects.size();
169         if ( projectsReady )
170         {
171             synchronized ( DEPLOYREQUESTS )
172             {
173                 while ( !DEPLOYREQUESTS.isEmpty() )
174                 {
175                     ArtifactRepository repo = getDeploymentRepository( DEPLOYREQUESTS.get( 0 ) );
176 
177                     deployProject( getSession().getProjectBuildingRequest(), DEPLOYREQUESTS.remove( 0 ), repo );
178                 }
179             }
180         }
181         else if ( addedDeployRequest )
182         {
183             getLog().info( "Deploying " + project.getGroupId() + ":" + project.getArtifactId() + ":"
184                 + project.getVersion() + " at end" );
185         }
186     }
187 
188     private void deployProject( ProjectBuildingRequest pbr, ProjectDeployerRequest pir, ArtifactRepository repo )
189         throws MojoFailureException, MojoExecutionException
190     {
191         try
192         {
193             projectDeployer.deploy( pbr, pir, repo );
194         }
195         catch ( NoFileAssignedException e )
196         {
197             throw new MojoExecutionException( "NoFileAssignedException", e );
198         }
199         catch ( ArtifactDeployerException e )
200         {
201             throw new MojoExecutionException( "ArtifactDeployerException", e );
202         }
203 
204     }
205 
206     ArtifactRepository getDeploymentRepository( ProjectDeployerRequest pdr )
207 
208         throws MojoExecutionException, MojoFailureException
209     {
210         MavenProject project = pdr.getProject();
211         String altDeploymentRepository = pdr.getAltDeploymentRepository();
212         String altReleaseDeploymentRepository = pdr.getAltReleaseDeploymentRepository();
213         String altSnapshotDeploymentRepository = pdr.getAltSnapshotDeploymentRepository();
214 
215         ArtifactRepository repo = null;
216 
217         String altDeploymentRepo;
218         if ( ArtifactUtils.isSnapshot( project.getVersion() ) && altSnapshotDeploymentRepository != null )
219         {
220             altDeploymentRepo = altSnapshotDeploymentRepository;
221         }
222         else if ( !ArtifactUtils.isSnapshot( project.getVersion() ) && altReleaseDeploymentRepository != null )
223         {
224             altDeploymentRepo = altReleaseDeploymentRepository;
225         }
226         else
227         {
228             altDeploymentRepo = altDeploymentRepository;
229         }
230 
231         if ( altDeploymentRepo != null )
232         {
233             getLog().info( "Using alternate deployment repository " + altDeploymentRepo );
234 
235             Matcher matcher = ALT_REPO_SYNTAX_PATTERN.matcher( altDeploymentRepo );
236 
237             if ( !matcher.matches() )
238             {
239                 throw new MojoFailureException( altDeploymentRepo, "Invalid syntax for repository.",
240                                                 "Invalid syntax for alternative repository. Use \"id::url\"." );
241             }
242             else
243             {
244                 String id = matcher.group( 1 ).trim();
245                 String url = matcher.group( 2 ).trim();
246 
247                 repo = createDeploymentArtifactRepository( id, url );
248             }
249         }
250 
251         if ( repo == null )
252         {
253             repo = project.getDistributionManagementArtifactRepository();
254         }
255 
256         if ( repo == null )
257         {
258             String msg = "Deployment failed: repository element was not specified in the POM inside"
259                 + " distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter";
260 
261             throw new MojoExecutionException( msg );
262         }
263 
264         return repo;
265     }
266 
267 }