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(), "UTF-8", 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 boolean sign = scmTagParameters.isSign(); 096 097 Commandline clTag = createCommandLine( repository, fileSet.getBasedir(), tag, messageFile, sign ); 098 099 exitCode = GitCommandLineUtils.execute( clTag, stdout, stderr, getLogger() ); 100 if ( exitCode != 0 ) 101 { 102 return new TagScmResult( clTag.toString(), "The git-tag command failed.", stderr.getOutput(), false ); 103 } 104 105 if ( repo.isPushChanges() ) 106 { 107 // and now push the tag to the configured upstream repository 108 Commandline clPush = createPushCommandLine( repository, fileSet, tag ); 109 110 exitCode = GitCommandLineUtils.execute( clPush, stdout, stderr, getLogger() ); 111 if ( exitCode != 0 ) 112 { 113 return new TagScmResult( clPush.toString(), "The git-push command failed.", stderr.getOutput(), 114 false ); 115 } 116 } 117 118 // plus search for the tagged files 119 GitListConsumer listConsumer = 120 new GitListConsumer( getLogger(), fileSet.getBasedir(), ScmFileStatus.TAGGED ); 121 122 Commandline clList = GitListCommand.createCommandLine( repository, fileSet.getBasedir() ); 123 124 exitCode = GitCommandLineUtils.execute( clList, listConsumer, stderr, getLogger() ); 125 if ( exitCode != 0 ) 126 { 127 return new CheckOutScmResult( clList.toString(), "The git-ls-files command failed.", 128 stderr.getOutput(), false ); 129 } 130 131 return new TagScmResult( clTag.toString(), listConsumer.getListedFiles() ); 132 } 133 finally 134 { 135 try 136 { 137 FileUtils.forceDelete( messageFile ); 138 } 139 catch ( IOException ex ) 140 { 141 // ignore 142 } 143 } 144 145 } 146 147 // ---------------------------------------------------------------------- 148 // 149 // ---------------------------------------------------------------------- 150 151 public static Commandline createCommandLine( GitScmProviderRepository repository, File workingDirectory, 152 String tag, File messageFile, boolean sign ) 153 { 154 Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "tag" ); 155 156 if ( sign ) 157 { 158 cl.createArg().setValue( "-s" ); 159 } 160 161 cl.createArg().setValue( "-F" ); 162 cl.createArg().setValue( messageFile.getAbsolutePath() ); 163 164 // Note: this currently assumes you have the tag base checked out too 165 cl.createArg().setValue( tag ); 166 167 return cl; 168 } 169 170 public static Commandline createPushCommandLine( GitScmProviderRepository repository, ScmFileSet fileSet, 171 String tag ) 172 throws ScmException 173 { 174 Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "push" ); 175 176 cl.createArg().setValue( repository.getPushUrl() ); 177 cl.createArg().setValue( "refs/tags/" + tag ); 178 179 return cl; 180 } 181 182}