View Javadoc

1   package org.apache.maven.continuum.release.phase;
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 org.apache.commons.lang.StringUtils;
23  import org.apache.continuum.scm.ContinuumScmUtils;
24  import org.apache.maven.scm.ScmBranch;
25  import org.apache.maven.scm.ScmException;
26  import org.apache.maven.scm.ScmFileSet;
27  import org.apache.maven.scm.ScmVersion;
28  import org.apache.maven.scm.command.checkout.CheckOutScmResult;
29  import org.apache.maven.scm.command.update.UpdateScmResult;
30  import org.apache.maven.scm.manager.NoSuchScmProviderException;
31  import org.apache.maven.scm.manager.plexus.PlexusLogger;
32  import org.apache.maven.scm.provider.ScmProvider;
33  import org.apache.maven.scm.provider.ScmProviderRepository;
34  import org.apache.maven.scm.provider.ScmUrlUtils;
35  import org.apache.maven.scm.provider.git.gitexe.command.branch.GitBranchCommand;
36  import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
37  import org.apache.maven.scm.repository.ScmRepository;
38  import org.apache.maven.scm.repository.ScmRepositoryException;
39  import org.apache.maven.settings.Settings;
40  import org.apache.maven.shared.release.ReleaseExecutionException;
41  import org.apache.maven.shared.release.ReleaseFailureException;
42  import org.apache.maven.shared.release.ReleaseResult;
43  import org.apache.maven.shared.release.config.ReleaseDescriptor;
44  import org.apache.maven.shared.release.env.ReleaseEnvironment;
45  import org.apache.maven.shared.release.phase.AbstractReleasePhase;
46  import org.apache.maven.shared.release.scm.ReleaseScmCommandException;
47  import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
48  import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
49  
50  import java.io.File;
51  import java.util.List;
52  
53  /**
54   * Update working copy
55   *
56   * @author Edwin Punzalan
57   * @version $Id: UpdateWorkingCopyPhase.java 1372260 2012-08-13 04:29:09Z brett $
58   */
59  public class UpdateWorkingCopyPhase
60      extends AbstractReleasePhase
61  {
62      /**
63       * Tool that gets a configured SCM repository from release configuration.
64       */
65      private ScmRepositoryConfigurator scmRepositoryConfigurator;
66  
67      private boolean copyUpdated = false;
68  
69      public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects )
70          throws ReleaseExecutionException, ReleaseFailureException
71      {
72          ReleaseResult relResult = new ReleaseResult();
73  
74          logInfo( relResult, "Updating local copy against the scm..." );
75  
76          ScmRepository repository;
77          ScmProvider provider;
78  
79          // CONTINUUM-2628
80          // if git ssh, use credentials specified in scm url if present. otherwise, use the scm credentials of project
81          String providerType = ScmUrlUtils.getProvider( releaseDescriptor.getScmSourceUrl() );
82          String scmSpecificUrl = releaseDescriptor.getScmSourceUrl().substring( providerType.length() + 5 );
83  
84          if ( providerType.contains( ContinuumScmUtils.GIT_SCM_PROVIDERTYPE ) && scmSpecificUrl.startsWith(
85              GitScmProviderRepository.PROTOCOL_SSH ) )
86          {
87              scmSpecificUrl = scmSpecificUrl.substring( GitScmProviderRepository.PROTOCOL_SSH.length() + 3 );
88  
89              // extract user information
90              int indexAt = scmSpecificUrl.indexOf( "@" );
91              String sshScmUsername = "";
92              String sshScmPassword = "";
93  
94              if ( indexAt >= 0 )
95              {
96                  String userInfo = scmSpecificUrl.substring( 0, indexAt );
97                  sshScmUsername = userInfo;
98  
99                  int indexPwdSep = userInfo.indexOf( ":" );
100                 // password is specified in the url
101                 if ( indexPwdSep < 0 )
102                 {
103                     sshScmUsername = userInfo.substring( indexPwdSep + 1 );
104                 }
105                 else
106                 {
107                     sshScmUsername = userInfo.substring( 0, indexPwdSep );
108                     sshScmPassword = userInfo.substring( indexPwdSep + 1 );
109                 }
110             }
111 
112             if ( !StringUtils.isBlank( sshScmUsername ) )
113             {
114                 releaseDescriptor.setScmUsername( sshScmUsername );
115                 if ( !StringUtils.isBlank( sshScmPassword ) )
116                 {
117                     releaseDescriptor.setScmPassword( sshScmPassword );
118                 }
119                 else
120                 {
121                     releaseDescriptor.setScmPassword( null );
122                 }
123             }
124         }
125 
126         try
127         {
128             repository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor, settings );
129 
130             provider = scmRepositoryConfigurator.getRepositoryProvider( repository );
131         }
132         catch ( ScmRepositoryException e )
133         {
134             throw new ReleaseScmRepositoryException(
135                 e.getMessage() + " for URL: " + releaseDescriptor.getScmSourceUrl(), e.getValidationMessages() );
136         }
137         catch ( NoSuchScmProviderException e )
138         {
139             throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e );
140         }
141 
142         UpdateScmResult updateScmResult = null;
143         CheckOutScmResult checkOutScmResult = null;
144 
145         File workingDirectory = new File( releaseDescriptor.getWorkingDirectory() );
146         ScmFileSet workingDirSet = new ScmFileSet( workingDirectory );
147 
148         try
149         {
150             if ( !workingDirectory.exists() )
151             {
152                 workingDirectory.mkdirs();
153             }
154 
155             ScmVersion scmTag = null;
156 
157             ScmProviderRepository providerRepo = repository.getProviderRepository();
158 
159             // FIXME: This should be handled by the maven-scm git provider
160             if ( providerRepo instanceof GitScmProviderRepository )
161             {
162                 String branchName = GitBranchCommand.getCurrentBranch( new PlexusLogger( getLogger() ),
163                                                                        (GitScmProviderRepository) providerRepo,
164                                                                        workingDirSet );
165                 scmTag = new ScmBranch( branchName );
166             }
167 
168             if ( workingDirectory.listFiles().length > 1 )
169             {
170                 updateScmResult = provider.update( repository, workingDirSet, scmTag );
171             }
172             else
173             {
174                 checkOutScmResult = provider.checkOut( repository, new ScmFileSet( workingDirectory ) );
175                 checkOutScmResult = provider.checkOut( repository, workingDirSet, scmTag );
176             }
177         }
178         catch ( ScmException e )
179         {
180             throw new ReleaseExecutionException( "An error occurred while updating your local copy: " + e.getMessage(),
181                                                  e );
182         }
183 
184         if ( updateScmResult != null )
185         {
186             if ( !updateScmResult.isSuccess() )
187             {
188                 throw new ReleaseScmCommandException( "Unable to update current working copy", updateScmResult );
189             }
190 
191             copyUpdated = updateScmResult.getUpdatedFiles().size() > 0;
192         }
193         else
194         {
195             if ( !checkOutScmResult.isSuccess() )
196             {
197                 throw new ReleaseScmCommandException( "Unable to checkout project", checkOutScmResult );
198             }
199 
200             copyUpdated = checkOutScmResult.getCheckedOutFiles().size() > 0;
201         }
202 
203         relResult.setResultCode( ReleaseResult.SUCCESS );
204 
205         return relResult;
206     }
207 
208     public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects )
209         throws ReleaseExecutionException, ReleaseFailureException
210     {
211         return execute( releaseDescriptor, settings, reactorProjects );
212     }
213 
214     public boolean isCopyUpdated()
215     {
216         return copyUpdated;
217     }
218 
219     public void setCopyUpdated( boolean copyUpdated )
220     {
221         this.copyUpdated = copyUpdated;
222     }
223 
224     public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
225                                   List reactorProjects )
226         throws ReleaseExecutionException, ReleaseFailureException
227     {
228         return execute( releaseDescriptor, releaseEnvironment.getSettings(), reactorProjects );
229     }
230 
231     public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
232                                    List reactorProjects )
233         throws ReleaseExecutionException, ReleaseFailureException
234     {
235         return execute( releaseDescriptor, releaseEnvironment.getSettings(), reactorProjects );
236     }
237 }