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.git.jgit.command.tag; 020 021import java.util.ArrayList; 022import java.util.List; 023 024import org.apache.maven.scm.ScmException; 025import org.apache.maven.scm.ScmFile; 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.tag.AbstractTagCommand; 031import org.apache.maven.scm.command.tag.TagScmResult; 032import org.apache.maven.scm.provider.ScmProviderRepository; 033import org.apache.maven.scm.provider.git.command.GitCommand; 034import org.apache.maven.scm.provider.git.jgit.command.JGitUtils; 035import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository; 036import org.eclipse.jgit.api.Git; 037import org.eclipse.jgit.lib.Constants; 038import org.eclipse.jgit.lib.Ref; 039import org.eclipse.jgit.revwalk.RevCommit; 040import org.eclipse.jgit.revwalk.RevWalk; 041import org.eclipse.jgit.transport.RefSpec; 042import org.eclipse.jgit.treewalk.TreeWalk; 043 044/** 045 * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a> 046 * @author Dominik Bartholdi (imod) 047 * @since 1.9 048 */ 049public class JGitTagCommand extends AbstractTagCommand implements GitCommand { 050 051 public ScmResult executeTagCommand(ScmProviderRepository repo, ScmFileSet fileSet, String tag, String message) 052 throws ScmException { 053 return executeTagCommand(repo, fileSet, tag, new ScmTagParameters(message)); 054 } 055 056 /** 057 * {@inheritDoc} 058 */ 059 public ScmResult executeTagCommand( 060 ScmProviderRepository repo, ScmFileSet fileSet, String tag, ScmTagParameters scmTagParameters) 061 throws ScmException { 062 if (tag == null || tag.trim().isEmpty()) { 063 throw new ScmException("tag name must be specified"); 064 } 065 066 if (!fileSet.getFileList().isEmpty()) { 067 throw new ScmException("This provider doesn't support tagging subsets of a directory"); 068 } 069 070 String escapedTagName = tag.trim().replace(' ', '_'); 071 072 Git git = null; 073 try { 074 git = JGitUtils.openRepo(fileSet.getBasedir()); 075 076 // tag the revision 077 String tagMessage = scmTagParameters.getMessage(); 078 Ref tagRef = git.tag() 079 .setName(escapedTagName) 080 .setMessage(tagMessage) 081 .setForceUpdate(false) 082 .call(); 083 084 if (repo.isPushChanges()) { 085 logger.info("push tag [" + escapedTagName + "] to remote..."); 086 JGitUtils.push(git, (GitScmProviderRepository) repo, new RefSpec(Constants.R_TAGS + escapedTagName)); 087 } 088 089 // search for the tagged files 090 RevWalk revWalk = new RevWalk(git.getRepository()); 091 RevCommit commit = revWalk.parseCommit(tagRef.getObjectId()); 092 revWalk.close(); 093 094 final TreeWalk walk = new TreeWalk(git.getRepository()); 095 walk.reset(); // drop the first empty tree, which we do not need here 096 walk.setRecursive(true); 097 walk.addTree(commit.getTree()); 098 099 List<ScmFile> taggedFiles = new ArrayList<>(); 100 while (walk.next()) { 101 taggedFiles.add(new ScmFile(walk.getPathString(), ScmFileStatus.CHECKED_OUT)); 102 } 103 walk.close(); 104 105 return new TagScmResult("JGit tag", taggedFiles); 106 } catch (Exception e) { 107 throw new ScmException("JGit tag failure!", e); 108 } finally { 109 JGitUtils.closeRepo(git); 110 } 111 } 112}