View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.release.phase;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.io.File;
26  import java.util.List;
27  
28  import org.apache.maven.project.MavenProject;
29  import org.apache.maven.scm.ScmBranchParameters;
30  import org.apache.maven.scm.ScmException;
31  import org.apache.maven.scm.ScmFileSet;
32  import org.apache.maven.scm.command.branch.BranchScmResult;
33  import org.apache.maven.scm.manager.NoSuchScmProviderException;
34  import org.apache.maven.scm.provider.ScmProvider;
35  import org.apache.maven.scm.repository.ScmRepository;
36  import org.apache.maven.scm.repository.ScmRepositoryException;
37  import org.apache.maven.shared.release.ReleaseExecutionException;
38  import org.apache.maven.shared.release.ReleaseFailureException;
39  import org.apache.maven.shared.release.ReleaseResult;
40  import org.apache.maven.shared.release.config.ReleaseDescriptor;
41  import org.apache.maven.shared.release.env.ReleaseEnvironment;
42  import org.apache.maven.shared.release.scm.ReleaseScmCommandException;
43  import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
44  import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
45  import org.apache.maven.shared.release.util.ReleaseUtil;
46  
47  /**
48   * Branch the SCM repository.
49   *
50   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
51   */
52  @Singleton
53  @Named("scm-branch")
54  public class ScmBranchPhase extends AbstractReleasePhase {
55      /**
56       * Tool that gets a configured SCM repository from release configuration.
57       */
58      private final ScmRepositoryConfigurator scmRepositoryConfigurator;
59  
60      @Inject
61      public ScmBranchPhase(ScmRepositoryConfigurator scmRepositoryConfigurator) {
62          this.scmRepositoryConfigurator = scmRepositoryConfigurator;
63      }
64  
65      @Override
66      public ReleaseResult execute(
67              ReleaseDescriptor releaseDescriptor,
68              ReleaseEnvironment releaseEnvironment,
69              List<MavenProject> reactorProjects)
70              throws ReleaseExecutionException, ReleaseFailureException {
71          ReleaseResult relResult = new ReleaseResult();
72  
73          validateConfiguration(releaseDescriptor);
74  
75          logInfo(relResult, "Branching release with the label " + releaseDescriptor.getScmReleaseLabel() + "...");
76  
77          ReleaseDescriptor basedirAlignedReleaseDescriptor =
78                  ReleaseUtil.createBasedirAlignedReleaseDescriptor(releaseDescriptor, reactorProjects);
79  
80          ScmRepository repository;
81          ScmProvider provider;
82          try {
83              repository = scmRepositoryConfigurator.getConfiguredRepository(
84                      basedirAlignedReleaseDescriptor.getScmSourceUrl(),
85                      releaseDescriptor,
86                      releaseEnvironment.getSettings());
87  
88              repository.getProviderRepository().setPushChanges(releaseDescriptor.isPushChanges());
89  
90              repository.getProviderRepository().setWorkItem(releaseDescriptor.getWorkItem());
91  
92              provider = scmRepositoryConfigurator.getRepositoryProvider(repository);
93  
94          } catch (ScmRepositoryException e) {
95              throw new ReleaseScmRepositoryException(e.getMessage(), e.getValidationMessages());
96          } catch (NoSuchScmProviderException e) {
97              throw new ReleaseExecutionException("Unable to configure SCM repository: " + e.getMessage(), e);
98          }
99  
100         BranchScmResult result;
101         try {
102             ScmFileSet fileSet = new ScmFileSet(new File(basedirAlignedReleaseDescriptor.getWorkingDirectory()));
103             String branchName = releaseDescriptor.getScmReleaseLabel();
104 
105             ScmBranchParameters scmBranchParameters = new ScmBranchParameters();
106             scmBranchParameters.setMessage(releaseDescriptor.getScmCommentPrefix() + "copy for branch " + branchName);
107             scmBranchParameters.setRemoteBranching(releaseDescriptor.isRemoteTagging());
108             scmBranchParameters.setScmRevision(releaseDescriptor.getScmReleasedPomRevision());
109             scmBranchParameters.setPinExternals(releaseDescriptor.isPinExternals());
110 
111             result = provider.branch(repository, fileSet, branchName, scmBranchParameters);
112         } catch (ScmException e) {
113             throw new ReleaseExecutionException("An error is occurred in the branch process: " + e.getMessage(), e);
114         }
115 
116         if (!result.isSuccess()) {
117             throw new ReleaseScmCommandException("Unable to branch SCM", result);
118         }
119 
120         relResult.setResultCode(ReleaseResult.SUCCESS);
121 
122         return relResult;
123     }
124 
125     @Override
126     public ReleaseResult simulate(
127             ReleaseDescriptor releaseDescriptor,
128             ReleaseEnvironment releaseEnvironment,
129             List<MavenProject> reactorProjects)
130             throws ReleaseExecutionException, ReleaseFailureException {
131         ReleaseResult result = new ReleaseResult();
132 
133         validateConfiguration(releaseDescriptor);
134         ReleaseDescriptor basedirAlignedReleaseDescriptor =
135                 ReleaseUtil.createBasedirAlignedReleaseDescriptor(releaseDescriptor, reactorProjects);
136 
137         logInfo(result, "Full run would branch " + basedirAlignedReleaseDescriptor.getWorkingDirectory());
138         if (releaseDescriptor.getScmBranchBase() != null) {
139             logInfo(result, "  to SCM URL " + releaseDescriptor.getScmBranchBase());
140         }
141         logInfo(result, "  with label '" + releaseDescriptor.getScmReleaseLabel() + "'");
142         if (releaseDescriptor.isPinExternals()) {
143             logInfo(result, "  and pinned externals");
144         }
145 
146         result.setResultCode(ReleaseResult.SUCCESS);
147 
148         return result;
149     }
150 
151     private static void validateConfiguration(ReleaseDescriptor releaseDescriptor) throws ReleaseFailureException {
152         if (releaseDescriptor.getScmReleaseLabel() == null) {
153             throw new ReleaseFailureException("A release label is required for committing");
154         }
155     }
156 }