package com.atlassian.jgitflow.core.util;
import java.util.List;
import com.atlassian.jgitflow.core.GitFlowConfiguration;
import com.atlassian.jgitflow.core.JGitFlowConstants;
import com.atlassian.jgitflow.core.JGitFlowReporter;
import com.atlassian.jgitflow.core.exception.*;
import org.eclipse.jgit.api.CreateBranchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.revwalk.RevCommit;
public class RequirementHelper
{
protected final Git git;
protected final GitFlowConfiguration gfConfig;
protected final JGitFlowReporter reporter = JGitFlowReporter.get();
protected final String commandName;
public RequirementHelper(Git git, GitFlowConfiguration gfConfig, String commandName)
{
this.git = git;
this.gfConfig = gfConfig;
this.commandName = commandName;
}
/**
* Requires that git flow has been initialized for the project represented by the internal {Git} instance
*
* @throws com.atlassian.jgitflow.core.exception.NotInitializedException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException
*/
public void requireGitFlowInitialized() throws NotInitializedException, JGitFlowGitAPIException
{
if (!gfConfig.gitFlowIsInitialized())
{
reporter.errorText(commandName, "requireGitFlowInitialized() failed");
reporter.flush();
throw new NotInitializedException("Git flow is not initialized in " + git.getRepository().getWorkTree().getPath());
}
}
/**
* Requires that a local branch with the given name does not yet exist
*
* @param branch the name of the branch to test
* @throws com.atlassian.jgitflow.core.exception.LocalBranchExistsException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException
*/
public void requireLocalBranchAbsent(String branch) throws LocalBranchExistsException, JGitFlowGitAPIException
{
if (GitHelper.localBranchExists(git, branch))
{
reporter.errorText(commandName, "requireLocalBranchAbsent() failed: '" + branch + "' already exists");
reporter.flush();
throw new LocalBranchExistsException("local branch '" + branch + "' already exists");
}
}
/**
* Requires that a local branch with the given name exists
*
* @param branch The name of the branch to test
* @throws com.atlassian.jgitflow.core.exception.LocalBranchMissingException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException
*/
public void requireLocalBranchExists(String branch) throws LocalBranchMissingException, JGitFlowGitAPIException
{
if (!GitHelper.localBranchExists(git, branch) && GitHelper.remoteBranchExists(git, branch))
{
try
{
git.checkout()
.setName(branch)
.setCreateBranch(true)
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
.setStartPoint(Constants.DEFAULT_REMOTE_NAME + "/" + branch)
.call();
}
catch (GitAPIException e)
{
throw new JGitFlowGitAPIException("error checking out remote branch.", e);
}
}
if (!GitHelper.localBranchExists(git, branch))
{
reporter.errorText(commandName, "localBranchExists() failed: '" + branch + "' does not exist");
reporter.flush();
throw new LocalBranchMissingException("local branch " + branch + " does not exist");
}
}
/**
* Requires that a remote branch with the given name does not yet exist
*
* @param branch The name of the branch to test
* @throws com.atlassian.jgitflow.core.exception.RemoteBranchExistsException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException
*/
public void requireRemoteBranchAbsent(String branch) throws RemoteBranchExistsException, JGitFlowGitAPIException
{
if (GitHelper.remoteBranchExists(git, branch))
{
reporter.errorText(commandName, "requireRemoteBranchAbsent() failed: '" + branch + "' already exists");
reporter.flush();
throw new RemoteBranchExistsException("remote branch '" + branch + "' already exists");
}
}
/**
* Requires that a remote branch with the given name exists
*
* @param branch The name of the branch to test
* @throws com.atlassian.jgitflow.core.exception.RemoteBranchMissingException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException
*/
public void requireRemoteBranchExists(String branch) throws RemoteBranchMissingException, JGitFlowGitAPIException
{
if (!GitHelper.remoteBranchExists(git, branch))
{
reporter.errorText(commandName, "requireRemoteBranchExists() failed: '" + branch + "' does not exist");
reporter.flush();
throw new RemoteBranchMissingException("remote branch " + branch + " does not exist");
}
}
/**
* Requires that a tag with the given name does not yet exist
*
* @param name The name of the tag to test
* @throws com.atlassian.jgitflow.core.exception.TagExistsException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException
*/
public void requireTagAbsent(String name) throws TagExistsException, JGitFlowGitAPIException
{
if (GitHelper.tagExists(git, name))
{
reporter.errorText(commandName, "requireTagAbsent() failed: '" + name + "' already exists");
reporter.flush();
throw new TagExistsException("tag '" + name + "' already exists");
}
}
/**
* Requires that the local branch with the given name is not behind a remote brach with the same name
*
* @param branch The name of the branch to test
* @throws com.atlassian.jgitflow.core.exception.BranchOutOfDateException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowIOException
*/
public void requireLocalBranchNotBehindRemote(String branch) throws BranchOutOfDateException, JGitFlowIOException
{
reporter.debugMethod(commandName, "requireLocalBranchNotBehindRemote");
boolean behind = GitHelper.localBranchBehindRemote(git, branch);
if (behind)
{
reporter.errorText(commandName, "local branch '" + branch + "' is behind the remote branch");
reporter.endMethod();
reporter.flush();
throw new BranchOutOfDateException("local branch '" + branch + "' is behind the remote branch");
}
reporter.endMethod();
}
/**
* Requires that the local working tree has no un-committed changes
*
* @throws com.atlassian.jgitflow.core.exception.DirtyWorkingTreeException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowIOException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException
*/
public void requireCleanWorkingTree(boolean allowUntracked) throws DirtyWorkingTreeException, JGitFlowIOException, JGitFlowGitAPIException
{
CleanStatus cs = GitHelper.workingTreeIsClean(git, allowUntracked);
if (cs.isNotClean())
{
reporter.errorText(commandName, cs.getMessage());
reporter.flush();
throw new DirtyWorkingTreeException(cs.getMessage());
}
}
/**
* Requires that no release branches already exist
*
* @throws com.atlassian.jgitflow.core.exception.ReleaseBranchExistsException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException
*/
public void requireNoExistingReleaseBranches() throws ReleaseBranchExistsException, JGitFlowGitAPIException
{
List<Ref> branches = GitHelper.listBranchesWithPrefix(git, gfConfig.getPrefixValue(JGitFlowConstants.PREFIXES.RELEASE.configKey()));
if (!branches.isEmpty())
{
reporter.errorText(commandName, "a release branch [" + branches.get(0).getName() + "] already exists. Finish that first!");
reporter.flush();
throw new ReleaseBranchExistsException("a release branch [" + branches.get(0).getName() + "] already exists. Finish that first!");
}
}
/**
* Requires that no hotfix branches already exist
*
* @throws com.atlassian.jgitflow.core.exception.HotfixBranchExistsException
* @throws com.atlassian.jgitflow.core.exception.JGitFlowGitAPIException
*/
public void requireNoExistingHotfixBranches() throws HotfixBranchExistsException, JGitFlowGitAPIException
{
List<Ref> branches = GitHelper.listBranchesWithPrefix(git, gfConfig.getPrefixValue(JGitFlowConstants.PREFIXES.HOTFIX.configKey()));
if (!branches.isEmpty())
{
reporter.errorText(commandName, "a hotfix branch [" + branches.get(0).getName() + "] already exists. Finish that first!");
reporter.flush();
throw new HotfixBranchExistsException("a hotfix branch [" + branches.get(0).getName() + "] already exists. Finish that first!");
}
}
/**
* Requires that a local branch contains the given commit
*
* @param commit the commit to test
* @param branch the name of the branch to check
*/
public void requireCommitOnBranch(RevCommit commit, String branch) throws LocalBranchExistsException, JGitFlowGitAPIException, JGitFlowIOException
{
if (!GitHelper.isMergedInto(git, commit, branch))
{
reporter.errorText(commandName, "requireCommitOnBranch() failed: '" + commit.getName() + "' is not on " + branch);
reporter.flush();
throw new LocalBranchExistsException("commit '" + commit.getName() + "' does not exist on " + branch);
}
}
}