001package org.apache.maven.scm.provider.git.gitexe.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; 024 025import org.apache.maven.scm.ScmException; 026import org.apache.maven.scm.ScmFileSet; 027import org.apache.maven.scm.ScmFileStatus; 028import org.apache.maven.scm.ScmResult; 029import org.apache.maven.scm.ScmTagParameters; 030import org.apache.maven.scm.command.checkout.CheckOutScmResult; 031import org.apache.maven.scm.command.tag.AbstractTagCommand; 032import org.apache.maven.scm.command.tag.TagScmResult; 033import org.apache.maven.scm.provider.ScmProviderRepository; 034import org.apache.maven.scm.provider.git.command.GitCommand; 035import org.apache.maven.scm.provider.git.gitexe.command.GitCommandLineUtils; 036import org.apache.maven.scm.provider.git.gitexe.command.list.GitListCommand; 037import org.apache.maven.scm.provider.git.gitexe.command.list.GitListConsumer; 038import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository; 039import org.codehaus.plexus.util.FileUtils; 040import org.codehaus.plexus.util.StringUtils; 041import org.codehaus.plexus.util.cli.CommandLineUtils; 042import org.codehaus.plexus.util.cli.Commandline; 043 044/** 045 * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a> 046 * 047 */ 048public class GitTagCommand 049 extends AbstractTagCommand 050 implements GitCommand 051{ 052 053 public ScmResult executeTagCommand( ScmProviderRepository repo, ScmFileSet fileSet, String tag, String message ) 054 throws ScmException 055 { 056 return executeTagCommand( repo, fileSet, tag, new ScmTagParameters( message ) ); 057 } 058 059 /** {@inheritDoc} */ 060 public ScmResult executeTagCommand( ScmProviderRepository repo, ScmFileSet fileSet, String tag, 061 ScmTagParameters scmTagParameters ) 062 throws ScmException 063 { 064 if ( tag == null || StringUtils.isEmpty( tag.trim() ) ) 065 { 066 throw new ScmException( "tag name must be specified" ); 067 } 068 069 if ( !fileSet.getFileList().isEmpty() ) 070 { 071 throw new ScmException( "This provider doesn't support tagging subsets of a directory" ); 072 } 073 074 GitScmProviderRepository repository = (GitScmProviderRepository) repo; 075 076 File messageFile = FileUtils.createTempFile( "maven-scm-", ".commit", null ); 077 078 try 079 { 080 FileUtils.fileWrite( messageFile.getAbsolutePath(), scmTagParameters.getMessage() ); 081 } 082 catch ( IOException ex ) 083 { 084 return new TagScmResult( null, "Error while making a temporary file for the commit message: " 085 + ex.getMessage(), null, false ); 086 } 087 088 try 089 { 090 CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer(); 091 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 092 093 int exitCode; 094 095 Commandline clTag = createCommandLine( repository, fileSet.getBasedir(), tag, messageFile ); 096 097 exitCode = GitCommandLineUtils.execute( clTag, stdout, stderr, getLogger() ); 098 if ( exitCode != 0 ) 099 { 100 return new TagScmResult( clTag.toString(), "The git-tag command failed.", stderr.getOutput(), false ); 101 } 102 103 if ( repo.isPushChanges() ) 104 { 105 // and now push the tag to the configured upstream repository 106 Commandline clPush = createPushCommandLine( repository, fileSet, tag ); 107 108 exitCode = GitCommandLineUtils.execute( clPush, stdout, stderr, getLogger() ); 109 if ( exitCode != 0 ) 110 { 111 return new TagScmResult( clPush.toString(), "The git-push command failed.", stderr.getOutput(), 112 false ); 113 } 114 } 115 116 // plus search for the tagged files 117 GitListConsumer listConsumer = 118 new GitListConsumer( getLogger(), fileSet.getBasedir(), ScmFileStatus.TAGGED ); 119 120 Commandline clList = GitListCommand.createCommandLine( repository, fileSet.getBasedir() ); 121 122 exitCode = GitCommandLineUtils.execute( clList, listConsumer, stderr, getLogger() ); 123 if ( exitCode != 0 ) 124 { 125 return new CheckOutScmResult( clList.toString(), "The git-ls-files command failed.", 126 stderr.getOutput(), false ); 127 } 128 129 return new TagScmResult( clTag.toString(), listConsumer.getListedFiles() ); 130 } 131 finally 132 { 133 try 134 { 135 FileUtils.forceDelete( messageFile ); 136 } 137 catch ( IOException ex ) 138 { 139 // ignore 140 } 141 } 142 143 } 144 145 // ---------------------------------------------------------------------- 146 // 147 // ---------------------------------------------------------------------- 148 149 public static Commandline createCommandLine( GitScmProviderRepository repository, File workingDirectory, 150 String tag, File messageFile ) 151 { 152 Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "tag" ); 153 154 cl.createArg().setValue( "-F" ); 155 cl.createArg().setValue( messageFile.getAbsolutePath() ); 156 157 // Note: this currently assumes you have the tag base checked out too 158 cl.createArg().setValue( tag ); 159 160 return cl; 161 } 162 163 public static Commandline createPushCommandLine( GitScmProviderRepository repository, ScmFileSet fileSet, 164 String tag ) 165 throws ScmException 166 { 167 Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "push" ); 168 169 cl.createArg().setValue( repository.getPushUrl() ); 170 cl.createArg().setValue( "refs/tags/" + tag ); 171 172 return cl; 173 } 174 175}