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.scm.provider.svn.svnexe.command.branch;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import org.apache.commons.lang3.StringUtils;
27  import org.apache.maven.scm.ScmBranch;
28  import org.apache.maven.scm.ScmBranchParameters;
29  import org.apache.maven.scm.ScmException;
30  import org.apache.maven.scm.ScmFile;
31  import org.apache.maven.scm.ScmFileSet;
32  import org.apache.maven.scm.ScmFileStatus;
33  import org.apache.maven.scm.ScmResult;
34  import org.apache.maven.scm.command.branch.AbstractBranchCommand;
35  import org.apache.maven.scm.command.branch.BranchScmResult;
36  import org.apache.maven.scm.provider.ScmProviderRepository;
37  import org.apache.maven.scm.provider.svn.SvnCommandUtils;
38  import org.apache.maven.scm.provider.svn.SvnTagBranchUtils;
39  import org.apache.maven.scm.provider.svn.command.SvnCommand;
40  import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
41  import org.apache.maven.scm.provider.svn.svnexe.command.SvnCommandLineUtils;
42  import org.codehaus.plexus.util.FileUtils;
43  import org.codehaus.plexus.util.Os;
44  import org.codehaus.plexus.util.cli.CommandLineException;
45  import org.codehaus.plexus.util.cli.CommandLineUtils;
46  import org.codehaus.plexus.util.cli.Commandline;
47  
48  /**
49   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
50   * @author Olivier Lamy
51   * TODO since this is just a copy, use that instead
52   */
53  public class SvnBranchCommand extends AbstractBranchCommand implements SvnCommand {
54      private final boolean interactive;
55  
56      public SvnBranchCommand(boolean interactive) {
57          this.interactive = interactive;
58      }
59  
60      public ScmResult executeBranchCommand(
61              ScmProviderRepository repo, ScmFileSet fileSet, String branch, ScmBranchParameters scmBranchParameters)
62              throws ScmException {
63          if (branch == null || branch.trim().isEmpty()) {
64              throw new ScmException("branch name must be specified");
65          }
66  
67          if (!fileSet.getFileList().isEmpty()) {
68              throw new ScmException("This provider doesn't support branching subsets of a directory");
69          }
70  
71          SvnScmProviderRepository repository = (SvnScmProviderRepository) repo;
72  
73          File messageFile = FileUtils.createTempFile("maven-scm-", ".commit", null);
74  
75          try {
76              FileUtils.fileWrite(messageFile.getAbsolutePath(), "UTF-8", scmBranchParameters.getMessage());
77          } catch (IOException ex) {
78              return new BranchScmResult(
79                      null,
80                      "Error while making a temporary file for the commit message: " + ex.getMessage(),
81                      null,
82                      false);
83          }
84  
85          Commandline cl = createCommandLine(repository, fileSet.getBasedir(), branch, messageFile, scmBranchParameters);
86  
87          CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
88  
89          CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
90  
91          if (logger.isInfoEnabled()) {
92              logger.info("Executing: " + SvnCommandLineUtils.cryptPassword(cl));
93  
94              if (Os.isFamily(Os.FAMILY_WINDOWS)) {
95                  logger.info("Working directory: " + cl.getWorkingDirectory().getAbsolutePath());
96              }
97          }
98  
99          int exitCode;
100 
101         try {
102             exitCode = SvnCommandLineUtils.execute(cl, stdout, stderr);
103         } catch (CommandLineException ex) {
104             throw new ScmException("Error while executing command.", ex);
105         } finally {
106             try {
107                 FileUtils.forceDelete(messageFile);
108             } catch (IOException ex) {
109                 // ignore
110             }
111         }
112 
113         if (exitCode != 0) {
114             return new BranchScmResult(cl.toString(), "The svn branch command failed.", stderr.getOutput(), false);
115         }
116 
117         List<ScmFile> fileList = new ArrayList<>();
118 
119         List<File> files = null;
120 
121         try {
122             files = FileUtils.getFiles(fileSet.getBasedir(), "**", "**/.svn/**", false);
123         } catch (IOException e) {
124             throw new ScmException("Error while executing command.", e);
125         }
126 
127         for (File f : files) {
128             fileList.add(new ScmFile(f.getPath(), ScmFileStatus.TAGGED));
129         }
130 
131         return new BranchScmResult(cl.toString(), fileList);
132     }
133 
134     /**
135      * {@inheritDoc}
136      */
137     public ScmResult executeBranchCommand(ScmProviderRepository repo, ScmFileSet fileSet, String branch, String message)
138             throws ScmException {
139         ScmBranchParameters scmBranchParameters = new ScmBranchParameters(message);
140         return executeBranchCommand(repo, fileSet, branch, scmBranchParameters);
141     }
142 
143     // ----------------------------------------------------------------------
144     //
145     // ----------------------------------------------------------------------
146 
147     public Commandline createCommandLine(
148             SvnScmProviderRepository repository, File workingDirectory, String branch, File messageFile) {
149         ScmBranchParameters scmBranchParameters = new ScmBranchParameters();
150         scmBranchParameters.setRemoteBranching(false);
151         scmBranchParameters.setPinExternals(false);
152         return createCommandLine(repository, workingDirectory, branch, messageFile, scmBranchParameters);
153     }
154 
155     public Commandline createCommandLine(
156             SvnScmProviderRepository repository,
157             File workingDirectory,
158             String branch,
159             File messageFile,
160             ScmBranchParameters scmBranchParameters) {
161         Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine(workingDirectory, repository, interactive);
162 
163         cl.createArg().setValue("copy");
164 
165         cl.createArg().setValue("--parents");
166 
167         cl.createArg().setValue("--file");
168 
169         cl.createArg().setValue(messageFile.getAbsolutePath());
170 
171         cl.createArg().setValue("--encoding");
172 
173         cl.createArg().setValue("UTF-8");
174 
175         if (scmBranchParameters != null && scmBranchParameters.isPinExternals()) {
176             cl.createArg().setValue("--pin-externals");
177         }
178 
179         if (scmBranchParameters != null && scmBranchParameters.isRemoteBranching()) {
180             if (StringUtils.isNotBlank(scmBranchParameters.getScmRevision())) {
181                 cl.createArg().setValue("--revision");
182                 cl.createArg().setValue(scmBranchParameters.getScmRevision());
183             }
184             String url = SvnCommandUtils.fixUrl(repository.getUrl(), repository.getUser());
185             cl.createArg().setValue(url + "@");
186         } else {
187             cl.createArg().setValue(".");
188         }
189         // Note: this currently assumes you have the branch base checked out too
190         String branchUrl = SvnTagBranchUtils.resolveBranchUrl(repository, new ScmBranch(branch));
191         branchUrl = SvnCommandUtils.fixUrl(branchUrl, repository.getUser());
192         cl.createArg().setValue(branchUrl + "@");
193 
194         return cl;
195     }
196 }