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.tag;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.util.ArrayList;
24  import java.util.Iterator;
25  import java.util.List;
26  
27  import org.apache.commons.lang3.StringUtils;
28  import org.apache.maven.scm.ScmException;
29  import org.apache.maven.scm.ScmFile;
30  import org.apache.maven.scm.ScmFileSet;
31  import org.apache.maven.scm.ScmFileStatus;
32  import org.apache.maven.scm.ScmResult;
33  import org.apache.maven.scm.ScmTag;
34  import org.apache.maven.scm.ScmTagParameters;
35  import org.apache.maven.scm.command.tag.AbstractTagCommand;
36  import org.apache.maven.scm.command.tag.TagScmResult;
37  import org.apache.maven.scm.provider.ScmProviderRepository;
38  import org.apache.maven.scm.provider.svn.SvnCommandUtils;
39  import org.apache.maven.scm.provider.svn.SvnTagBranchUtils;
40  import org.apache.maven.scm.provider.svn.command.SvnCommand;
41  import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
42  import org.apache.maven.scm.provider.svn.svnexe.command.SvnCommandLineUtils;
43  import org.codehaus.plexus.util.FileUtils;
44  import org.codehaus.plexus.util.Os;
45  import org.codehaus.plexus.util.cli.CommandLineException;
46  import org.codehaus.plexus.util.cli.CommandLineUtils;
47  import org.codehaus.plexus.util.cli.Commandline;
48  
49  /**
50   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
51   * @author Olivier Lamy
52   * TODO since this is just a copy, use that instead
53   */
54  public class SvnTagCommand extends AbstractTagCommand implements SvnCommand {
55      private final boolean interactive;
56  
57      public SvnTagCommand(boolean interactive) {
58          this.interactive = interactive;
59      }
60  
61      public ScmResult executeTagCommand(ScmProviderRepository repo, ScmFileSet fileSet, String tag, String message)
62              throws ScmException {
63          ScmTagParameters scmTagParameters = new ScmTagParameters(message);
64          // force false to preserve backward comp
65          scmTagParameters.setRemoteTagging(false);
66          scmTagParameters.setPinExternals(false);
67          return executeTagCommand(repo, fileSet, tag, scmTagParameters);
68      }
69  
70      /**
71       * {@inheritDoc}
72       */
73      public ScmResult executeTagCommand(
74              ScmProviderRepository repo, ScmFileSet fileSet, String tag, ScmTagParameters scmTagParameters)
75              throws ScmException {
76          // NPE free
77          if (scmTagParameters == null) {
78              logger.debug("SvnTagCommand :: scmTagParameters is null create an empty one");
79              scmTagParameters = new ScmTagParameters();
80              scmTagParameters.setRemoteTagging(false);
81              scmTagParameters.setPinExternals(false);
82          } else {
83              logger.debug("SvnTagCommand :: scmTagParameters.remoteTagging : " + scmTagParameters.isRemoteTagging());
84          }
85          if (tag == null || tag.trim().isEmpty()) {
86              throw new ScmException("tag must be specified");
87          }
88  
89          if (!fileSet.getFileList().isEmpty()) {
90              throw new ScmException("This provider doesn't support tagging subsets of a directory");
91          }
92  
93          SvnScmProviderRepository repository = (SvnScmProviderRepository) repo;
94  
95          File messageFile = FileUtils.createTempFile("maven-scm-", ".commit", null);
96  
97          try {
98              FileUtils.fileWrite(messageFile.getAbsolutePath(), "UTF-8", scmTagParameters.getMessage());
99          } catch (IOException ex) {
100             return new TagScmResult(
101                     null,
102                     "Error while making a temporary file for the commit message: " + ex.getMessage(),
103                     null,
104                     false);
105         }
106 
107         Commandline cl = createCommandLine(repository, fileSet.getBasedir(), tag, messageFile, scmTagParameters);
108 
109         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
110 
111         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
112 
113         if (logger.isInfoEnabled()) {
114             logger.info("Executing: " + SvnCommandLineUtils.cryptPassword(cl));
115 
116             if (Os.isFamily(Os.FAMILY_WINDOWS)) {
117                 logger.info("Working directory: " + cl.getWorkingDirectory().getAbsolutePath());
118             }
119         }
120 
121         int exitCode;
122 
123         try {
124             exitCode = SvnCommandLineUtils.execute(cl, stdout, stderr);
125         } catch (CommandLineException ex) {
126             throw new ScmException("Error while executing command.", ex);
127         } finally {
128             try {
129                 FileUtils.forceDelete(messageFile);
130             } catch (IOException ex) {
131                 // ignore
132             }
133         }
134 
135         if (exitCode != 0) {
136             // TODO: Improve this error message
137             return new TagScmResult(cl.toString(), "The svn tag command failed.", stderr.getOutput(), false);
138         }
139 
140         List<ScmFile> fileList = new ArrayList<>();
141 
142         List<File> files = null;
143 
144         try {
145             if (StringUtils.isNotEmpty(fileSet.getExcludes())) {
146                 files = FileUtils.getFiles(
147                         fileSet.getBasedir(),
148                         (StringUtils.isEmpty(fileSet.getIncludes()) ? "**" : fileSet.getIncludes()),
149                         fileSet.getExcludes() + ",**/.svn/**",
150                         false);
151             } else {
152                 files = FileUtils.getFiles(
153                         fileSet.getBasedir(),
154                         (StringUtils.isEmpty(fileSet.getIncludes()) ? "**" : fileSet.getIncludes()),
155                         "**/.svn/**",
156                         false);
157             }
158         } catch (IOException e) {
159             throw new ScmException("Error while executing command.", e);
160         }
161 
162         for (Iterator<File> i = files.iterator(); i.hasNext(); ) {
163             File f = i.next();
164 
165             fileList.add(new ScmFile(f.getPath(), ScmFileStatus.TAGGED));
166         }
167 
168         return new TagScmResult(cl.toString(), fileList);
169     }
170 
171     // ----------------------------------------------------------------------
172     //
173     // ----------------------------------------------------------------------
174 
175     /**
176      * @param repository
177      * @param workingDirectory
178      * @param tag
179      * @param messageFile
180      * @return TODO
181      * @deprecated
182      */
183     public Commandline createCommandLine(
184             SvnScmProviderRepository repository, File workingDirectory, String tag, File messageFile) {
185         Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine(workingDirectory, repository, interactive);
186 
187         cl.createArg().setValue("copy");
188 
189         cl.createArg().setValue("--parents");
190 
191         cl.createArg().setValue("--file");
192 
193         cl.createArg().setValue(messageFile.getAbsolutePath());
194 
195         cl.createArg().setValue(".");
196 
197         // Note: this currently assumes you have the tag base checked out too
198         String tagUrl = SvnTagBranchUtils.resolveTagUrl(repository, new ScmTag(tag));
199         tagUrl = SvnCommandUtils.fixUrl(tagUrl, repository.getUser());
200         cl.createArg().setValue(tagUrl + "@");
201 
202         return cl;
203     }
204 
205     public Commandline createCommandLine(
206             SvnScmProviderRepository repository,
207             File workingDirectory,
208             String tag,
209             File messageFile,
210             ScmTagParameters scmTagParameters) {
211         Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine(workingDirectory, repository, interactive);
212 
213         cl.createArg().setValue("copy");
214 
215         cl.createArg().setValue("--file");
216 
217         cl.createArg().setValue(messageFile.getAbsolutePath());
218 
219         cl.createArg().setValue("--encoding");
220 
221         cl.createArg().setValue("UTF-8");
222 
223         cl.createArg().setValue("--parents");
224 
225         if (scmTagParameters != null && scmTagParameters.getScmRevision() != null) {
226             cl.createArg().setValue("--revision");
227 
228             cl.createArg().setValue(scmTagParameters.getScmRevision());
229         }
230 
231         if (scmTagParameters != null && scmTagParameters.isPinExternals()) {
232             cl.createArg().setValue("--pin-externals");
233         }
234 
235         if (scmTagParameters != null && scmTagParameters.isRemoteTagging()) {
236             String url = SvnCommandUtils.fixUrl(repository.getUrl(), repository.getUser());
237             cl.createArg().setValue(url + "@");
238         } else {
239             cl.createArg().setValue(".");
240         }
241 
242         // Note: this currently assumes you have the tag base checked out too
243         String tagUrl = SvnTagBranchUtils.resolveTagUrl(repository, new ScmTag(tag));
244         tagUrl = SvnCommandUtils.fixUrl(tagUrl, repository.getUser());
245         cl.createArg().setValue(tagUrl + "@");
246 
247         return cl;
248     }
249 }