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