001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.scm.provider.svn.svnexe.command.tag; 020 021import java.io.File; 022import java.io.IOException; 023import java.util.ArrayList; 024import java.util.Iterator; 025import java.util.List; 026 027import org.apache.commons.lang3.StringUtils; 028import org.apache.maven.scm.ScmException; 029import org.apache.maven.scm.ScmFile; 030import org.apache.maven.scm.ScmFileSet; 031import org.apache.maven.scm.ScmFileStatus; 032import org.apache.maven.scm.ScmResult; 033import org.apache.maven.scm.ScmTag; 034import org.apache.maven.scm.ScmTagParameters; 035import org.apache.maven.scm.command.tag.AbstractTagCommand; 036import org.apache.maven.scm.command.tag.TagScmResult; 037import org.apache.maven.scm.provider.ScmProviderRepository; 038import org.apache.maven.scm.provider.svn.SvnCommandUtils; 039import org.apache.maven.scm.provider.svn.SvnTagBranchUtils; 040import org.apache.maven.scm.provider.svn.command.SvnCommand; 041import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository; 042import org.apache.maven.scm.provider.svn.svnexe.command.SvnCommandLineUtils; 043import org.codehaus.plexus.util.FileUtils; 044import org.codehaus.plexus.util.Os; 045import org.codehaus.plexus.util.cli.CommandLineException; 046import org.codehaus.plexus.util.cli.CommandLineUtils; 047import org.codehaus.plexus.util.cli.Commandline; 048 049/** 050 * @author <a href="mailto:brett@apache.org">Brett Porter</a> 051 * @author Olivier Lamy 052 * 053 * TODO since this is just a copy, use that instead. 054 */ 055public class SvnTagCommand extends AbstractTagCommand implements SvnCommand { 056 057 public ScmResult executeTagCommand(ScmProviderRepository repo, ScmFileSet fileSet, String tag, String message) 058 throws ScmException { 059 ScmTagParameters scmTagParameters = new ScmTagParameters(message); 060 // force false to preserve backward comp 061 scmTagParameters.setRemoteTagging(false); 062 scmTagParameters.setPinExternals(false); 063 return executeTagCommand(repo, fileSet, tag, scmTagParameters); 064 } 065 066 /** {@inheritDoc} */ 067 public ScmResult executeTagCommand( 068 ScmProviderRepository repo, ScmFileSet fileSet, String tag, ScmTagParameters scmTagParameters) 069 throws ScmException { 070 // NPE free 071 if (scmTagParameters == null) { 072 logger.debug("SvnTagCommand :: scmTagParameters is null create an empty one"); 073 scmTagParameters = new ScmTagParameters(); 074 scmTagParameters.setRemoteTagging(false); 075 scmTagParameters.setPinExternals(false); 076 } else { 077 logger.debug("SvnTagCommand :: scmTagParameters.remoteTagging : " + scmTagParameters.isRemoteTagging()); 078 } 079 if (tag == null || tag.trim().isEmpty()) { 080 throw new ScmException("tag must be specified"); 081 } 082 083 if (!fileSet.getFileList().isEmpty()) { 084 throw new ScmException("This provider doesn't support tagging subsets of a directory"); 085 } 086 087 SvnScmProviderRepository repository = (SvnScmProviderRepository) repo; 088 089 File messageFile = FileUtils.createTempFile("maven-scm-", ".commit", null); 090 091 try { 092 FileUtils.fileWrite(messageFile.getAbsolutePath(), "UTF-8", scmTagParameters.getMessage()); 093 } catch (IOException ex) { 094 return new TagScmResult( 095 null, 096 "Error while making a temporary file for the commit message: " + ex.getMessage(), 097 null, 098 false); 099 } 100 101 Commandline cl = createCommandLine(repository, fileSet.getBasedir(), tag, messageFile, scmTagParameters); 102 103 CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer(); 104 105 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 106 107 if (logger.isInfoEnabled()) { 108 logger.info("Executing: " + SvnCommandLineUtils.cryptPassword(cl)); 109 110 if (Os.isFamily(Os.FAMILY_WINDOWS)) { 111 logger.info("Working directory: " + cl.getWorkingDirectory().getAbsolutePath()); 112 } 113 } 114 115 int exitCode; 116 117 try { 118 exitCode = SvnCommandLineUtils.execute(cl, stdout, stderr); 119 } catch (CommandLineException ex) { 120 throw new ScmException("Error while executing command.", ex); 121 } finally { 122 try { 123 FileUtils.forceDelete(messageFile); 124 } catch (IOException ex) { 125 // ignore 126 } 127 } 128 129 if (exitCode != 0) { 130 // TODO: Improve this error message 131 return new TagScmResult(cl.toString(), "The svn tag command failed.", stderr.getOutput(), false); 132 } 133 134 List<ScmFile> fileList = new ArrayList<>(); 135 136 List<File> files = null; 137 138 try { 139 if (StringUtils.isNotEmpty(fileSet.getExcludes())) { 140 files = FileUtils.getFiles( 141 fileSet.getBasedir(), 142 (StringUtils.isEmpty(fileSet.getIncludes()) ? "**" : fileSet.getIncludes()), 143 fileSet.getExcludes() + ",**/.svn/**", 144 false); 145 } else { 146 files = FileUtils.getFiles( 147 fileSet.getBasedir(), 148 (StringUtils.isEmpty(fileSet.getIncludes()) ? "**" : fileSet.getIncludes()), 149 "**/.svn/**", 150 false); 151 } 152 } catch (IOException e) { 153 throw new ScmException("Error while executing command.", e); 154 } 155 156 for (Iterator<File> i = files.iterator(); i.hasNext(); ) { 157 File f = i.next(); 158 159 fileList.add(new ScmFile(f.getPath(), ScmFileStatus.TAGGED)); 160 } 161 162 return new TagScmResult(cl.toString(), fileList); 163 } 164 165 // ---------------------------------------------------------------------- 166 // 167 // ---------------------------------------------------------------------- 168 169 /** 170 * @deprecated 171 * @param repository 172 * @param workingDirectory 173 * @param tag 174 * @param messageFile 175 * @return TODO 176 */ 177 public static Commandline createCommandLine( 178 SvnScmProviderRepository repository, File workingDirectory, String tag, File messageFile) { 179 Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine(workingDirectory, repository); 180 181 cl.createArg().setValue("copy"); 182 183 cl.createArg().setValue("--parents"); 184 185 cl.createArg().setValue("--file"); 186 187 cl.createArg().setValue(messageFile.getAbsolutePath()); 188 189 cl.createArg().setValue("."); 190 191 // Note: this currently assumes you have the tag base checked out too 192 String tagUrl = SvnTagBranchUtils.resolveTagUrl(repository, new ScmTag(tag)); 193 tagUrl = SvnCommandUtils.fixUrl(tagUrl, repository.getUser()); 194 cl.createArg().setValue(tagUrl + "@"); 195 196 return cl; 197 } 198 199 public static Commandline createCommandLine( 200 SvnScmProviderRepository repository, 201 File workingDirectory, 202 String tag, 203 File messageFile, 204 ScmTagParameters scmTagParameters) { 205 Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine(workingDirectory, repository); 206 207 cl.createArg().setValue("copy"); 208 209 cl.createArg().setValue("--file"); 210 211 cl.createArg().setValue(messageFile.getAbsolutePath()); 212 213 cl.createArg().setValue("--encoding"); 214 215 cl.createArg().setValue("UTF-8"); 216 217 cl.createArg().setValue("--parents"); 218 219 if (scmTagParameters != null && scmTagParameters.getScmRevision() != null) { 220 cl.createArg().setValue("--revision"); 221 222 cl.createArg().setValue(scmTagParameters.getScmRevision()); 223 } 224 225 if (scmTagParameters != null && scmTagParameters.isPinExternals()) { 226 cl.createArg().setValue("--pin-externals"); 227 } 228 229 if (scmTagParameters != null && scmTagParameters.isRemoteTagging()) { 230 String url = SvnCommandUtils.fixUrl(repository.getUrl(), repository.getUser()); 231 cl.createArg().setValue(url + "@"); 232 } else { 233 cl.createArg().setValue("."); 234 } 235 236 // Note: this currently assumes you have the tag base checked out too 237 String tagUrl = SvnTagBranchUtils.resolveTagUrl(repository, new ScmTag(tag)); 238 tagUrl = SvnCommandUtils.fixUrl(tagUrl, repository.getUser()); 239 cl.createArg().setValue(tagUrl + "@"); 240 241 return cl; 242 } 243}