com.amashchenko.maven.plugin.gitflow.AbstractGitFlowMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gitflow-maven-plugin Show documentation
Show all versions of gitflow-maven-plugin Show documentation
The Git-Flow Maven Plugin supports various Git workflows, including Vincent Driessen's successful Git branching model and GitHub Flow. This plugin runs Git and Maven commands from the command line. Supports Eclipse Plugins build with Tycho.
/*
* Copyright 2014-2018 Aleksandr Mashchenko.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.amashchenko.maven.plugin.gitflow;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.components.interactivity.Prompter;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;
/**
* Abstract git flow mojo.
*
*/
public abstract class AbstractGitFlowMojo extends AbstractMojo {
/** A full name of the versions-maven-plugin set goal. */
private static final String VERSIONS_MAVEN_PLUGIN_SET_GOAL = "org.codehaus.mojo:versions-maven-plugin:2.1:set";
/** Name of the tycho-versions-plugin set-version goal. */
private static final String TYCHO_VERSIONS_PLUGIN_SET_GOAL = "org.eclipse.tycho:tycho-versions-plugin:set-version";
/** System line separator. */
protected static final String LS = System.getProperty("line.separator");
/** Success exit code. */
private static final int SUCCESS_EXIT_CODE = 0;
/** Pattern of disallowed characters in Maven commands. */
private static final Pattern MAVEN_DISALLOWED_PATTERN = Pattern
.compile("[&|;]");
/** Command line for Git executable. */
private final Commandline cmdGit = new Commandline();
/** Command line for Maven executable. */
private final Commandline cmdMvn = new Commandline();
/** Git flow configuration. */
@Parameter(defaultValue = "${gitFlowConfig}")
protected GitFlowConfig gitFlowConfig;
/**
* Git commit messages.
*
* @since 1.2.1
*/
@Parameter(defaultValue = "${commitMessages}")
protected CommitMessages commitMessages;
/**
* Whether this is Tycho build.
*
* @since 1.1.0
*/
@Parameter(defaultValue = "false")
protected boolean tychoBuild;
/**
* Whether to call Maven install goal during the mojo execution.
*
* @since 1.0.5
*/
@Parameter(property = "installProject", defaultValue = "false")
protected boolean installProject = false;
/**
* Whether to fetch remote branch and compare it with the local one.
*
* @since 1.3.0
*/
@Parameter(property = "fetchRemote", defaultValue = "true")
protected boolean fetchRemote;
/**
* Whether to print commands output into the console.
*
* @since 1.0.7
*/
@Parameter(property = "verbose", defaultValue = "false")
private boolean verbose = false;
/**
* Command line arguments to pass to the underlying Maven commands.
*
* @since 1.8.0
*/
@Parameter(property = "argLine")
private String argLine;
/**
* Whether to make a GPG-signed commit.
*
* @since 1.9.0
*/
@Parameter(property = "gpgSignCommit", defaultValue = "false")
private boolean gpgSignCommit = false;
/**
* The path to the Maven executable. Defaults to "mvn".
*/
@Parameter(property = "mvnExecutable")
private String mvnExecutable;
/**
* The path to the Git executable. Defaults to "git".
*/
@Parameter(property = "gitExecutable")
private String gitExecutable;
/** Maven session. */
@Parameter(defaultValue = "${session}", readonly = true)
private MavenSession mavenSession;
/** Default prompter. */
@Component
protected Prompter prompter;
/** Maven settings. */
@Parameter(defaultValue = "${settings}", readonly = true)
protected Settings settings;
/**
* Initializes command line executables.
*
*/
private void initExecutables() {
if (StringUtils.isBlank(cmdMvn.getExecutable())) {
if (StringUtils.isBlank(mvnExecutable)) {
mvnExecutable = "mvn";
}
cmdMvn.setExecutable(mvnExecutable);
}
if (StringUtils.isBlank(cmdGit.getExecutable())) {
if (StringUtils.isBlank(gitExecutable)) {
gitExecutable = "git";
}
cmdGit.setExecutable(gitExecutable);
}
}
/**
* Validates plugin configuration. Throws exception if configuration is not
* valid.
*
* @param params
* Configuration parameters to validate.
* @throws MojoFailureException
* If configuration is not valid.
*/
protected void validateConfiguration(String... params)
throws MojoFailureException {
if (StringUtils.isNotBlank(argLine)
&& MAVEN_DISALLOWED_PATTERN.matcher(argLine).find()) {
throw new MojoFailureException(
"The argLine doesn't match allowed pattern.");
}
if (params != null && params.length > 0) {
for (String p : params) {
if (StringUtils.isNotBlank(p)
&& MAVEN_DISALLOWED_PATTERN.matcher(p).find()) {
throw new MojoFailureException("The '" + p
+ "' value doesn't match allowed pattern.");
}
}
}
}
/**
* Gets current project version from pom.xml file.
*
* @return Current project version.
* @throws MojoFailureException
*/
protected String getCurrentProjectVersion() throws MojoFailureException {
try {
// read pom.xml
final MavenXpp3Reader mavenReader = new MavenXpp3Reader();
final FileReader fileReader = new FileReader(mavenSession
.getCurrentProject().getFile().getAbsoluteFile());
try {
final Model model = mavenReader.read(fileReader);
if (model.getVersion() == null) {
throw new MojoFailureException(
"Cannot get current project version. This plugin should be executed from the parent project.");
}
return model.getVersion();
} finally {
if (fileReader != null) {
fileReader.close();
}
}
} catch (Exception e) {
throw new MojoFailureException("", e);
}
}
/**
* Compares the production branch name with the development branch name.
*
* @return true
if the production branch name is different from
* the development branch name, false
otherwise.
*/
protected boolean notSameProdDevName() {
return !gitFlowConfig.getProductionBranch().equals(
gitFlowConfig.getDevelopmentBranch());
}
/**
* Checks uncommitted changes.
*
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void checkUncommittedChanges() throws MojoFailureException,
CommandLineException {
getLog().info("Checking for uncommitted changes.");
if (executeGitHasUncommitted()) {
throw new MojoFailureException(
"You have some uncommitted files. Commit or discard local changes in order to proceed.");
}
}
protected void checkSnapshotDependencies() throws MojoFailureException {
getLog().info("Checking for SNAPSHOT versions in dependencies.");
List snapshots = new ArrayList();
List builtArtifacts = new ArrayList();
List projects = mavenSession.getProjects();
for (MavenProject project : projects) {
builtArtifacts.add(project.getGroupId() + ":"
+ project.getArtifactId() + ":" + project.getVersion());
List dependencies = project.getDependencies();
for (Dependency d : dependencies) {
String id = d.getGroupId() + ":" + d.getArtifactId() + ":"
+ d.getVersion();
if (!builtArtifacts.contains(id)
&& ArtifactUtils.isSnapshot(d.getVersion())) {
snapshots.add(project + " -> " + d);
}
}
}
if (!snapshots.isEmpty()) {
for (String s : snapshots) {
getLog().warn(s);
}
throw new MojoFailureException(
"There is some SNAPSHOT dependencies in the project, see warnings above. Change them or ignore with `allowSnapshots` property.");
}
}
/**
* Checks if branch name is acceptable.
*
* @param branchName
* Branch name to check.
* @return true
when name is valid, false
* otherwise.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected boolean validBranchName(final String branchName)
throws MojoFailureException, CommandLineException {
CommandResult r = executeGitCommandExitCode("check-ref-format",
"--allow-onelevel", branchName);
return r.getExitCode() == SUCCESS_EXIT_CODE;
}
/**
* Executes git commands to check for uncommitted changes.
*
* @return true
when there are uncommitted changes,
* false
otherwise.
* @throws CommandLineException
* @throws MojoFailureException
*/
private boolean executeGitHasUncommitted() throws MojoFailureException,
CommandLineException {
boolean uncommited = false;
// 1 if there were differences and 0 means no differences
// git diff --no-ext-diff --ignore-submodules --quiet --exit-code
final CommandResult diffCommandResult = executeGitCommandExitCode(
"diff", "--no-ext-diff", "--ignore-submodules", "--quiet",
"--exit-code");
String error = null;
if (diffCommandResult.getExitCode() == SUCCESS_EXIT_CODE) {
// git diff-index --cached --quiet --ignore-submodules HEAD --
final CommandResult diffIndexCommandResult = executeGitCommandExitCode(
"diff-index", "--cached", "--quiet", "--ignore-submodules",
"HEAD", "--");
if (diffIndexCommandResult.getExitCode() != SUCCESS_EXIT_CODE) {
error = diffIndexCommandResult.getError();
uncommited = true;
}
} else {
error = diffCommandResult.getError();
uncommited = true;
}
if (StringUtils.isNotBlank(error)) {
throw new MojoFailureException(error);
}
return uncommited;
}
/**
* Executes git config commands to set Git Flow configuration.
*
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void initGitFlowConfig() throws MojoFailureException,
CommandLineException {
gitSetConfig("gitflow.branch.master",
gitFlowConfig.getProductionBranch());
gitSetConfig("gitflow.branch.develop",
gitFlowConfig.getDevelopmentBranch());
gitSetConfig("gitflow.prefix.feature",
gitFlowConfig.getFeatureBranchPrefix());
gitSetConfig("gitflow.prefix.release",
gitFlowConfig.getReleaseBranchPrefix());
gitSetConfig("gitflow.prefix.hotfix",
gitFlowConfig.getHotfixBranchPrefix());
gitSetConfig("gitflow.prefix.support",
gitFlowConfig.getSupportBranchPrefix());
gitSetConfig("gitflow.prefix.versiontag",
gitFlowConfig.getVersionTagPrefix());
gitSetConfig("gitflow.origin", gitFlowConfig.getOrigin());
}
/**
* Executes git config command.
*
* @param name
* Option name.
* @param value
* Option value.
* @throws MojoFailureException
* @throws CommandLineException
*/
private void gitSetConfig(final String name, String value)
throws MojoFailureException, CommandLineException {
if (value == null || value.isEmpty()) {
value = "\"\"";
}
// ignore error exit codes
executeGitCommandExitCode("config", name, value);
}
/**
* Executes git for-each-ref with refname:short
format.
*
* @param branchName
* Branch name to find.
* @param firstMatch
* Return first match.
* @return Branch names which matches refs/heads/{branchName}*
.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected String gitFindBranches(final String branchName,
final boolean firstMatch) throws MojoFailureException,
CommandLineException {
String wildcard = "*";
if (branchName.endsWith("/")) {
wildcard = "**";
}
String branches;
if (firstMatch) {
branches = executeGitCommandReturn("for-each-ref", "--count=1",
"--format=\"%(refname:short)\"", "refs/heads/" + branchName
+ wildcard);
} else {
branches = executeGitCommandReturn("for-each-ref",
"--format=\"%(refname:short)\"", "refs/heads/" + branchName
+ wildcard);
}
// on *nix systems return values from git for-each-ref are wrapped in
// quotes
// https://github.com/aleksandr-m/gitflow-maven-plugin/issues/3
branches = removeQuotes(branches);
return branches;
}
/**
* Executes git for-each-ref to get all tags.
*
* @return Git tags.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected String gitFindTags() throws MojoFailureException, CommandLineException {
String tags = executeGitCommandReturn("for-each-ref", "--sort=*authordate", "--format=\"%(refname:short)\"",
"refs/tags/");
// https://github.com/aleksandr-m/gitflow-maven-plugin/issues/3
tags = removeQuotes(tags);
return tags;
}
/**
* Executes git for-each-ref to get the last tag.
*
* @return Last tag.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected String gitFindLastTag() throws MojoFailureException, CommandLineException {
String tag = executeGitCommandReturn("for-each-ref", "--sort=-*authordate", "--count=1",
"--format=\"%(refname:short)\"", "refs/tags/");
// https://github.com/aleksandr-m/gitflow-maven-plugin/issues/3
tag = removeQuotes(tag);
tag = tag.replaceAll("\\r?\\n", "");
return tag;
}
/**
* Removes double quotes from the string.
*
* @param str
* String to remove quotes from.
* @return String without quotes.
*/
private String removeQuotes(String str) {
if (str != null && !str.isEmpty()) {
str = str.replaceAll("\"", "");
}
return str;
}
/**
* Checks if local branch with given name exists.
*
* @param branchName
* Name of the branch to check.
* @return true
if local branch exists, false
* otherwise.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected boolean gitCheckBranchExists(final String branchName)
throws MojoFailureException, CommandLineException {
CommandResult commandResult = executeGitCommandExitCode("show-ref",
"--verify", "--quiet", "refs/heads/" + branchName);
return commandResult.getExitCode() == SUCCESS_EXIT_CODE;
}
/**
* Checks if local tag with given name exists.
*
* @param tagName
* Name of the tag to check.
* @return true
if local tag exists, false
otherwise.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected boolean gitCheckTagExists(final String tagName) throws MojoFailureException, CommandLineException {
CommandResult commandResult = executeGitCommandExitCode("show-ref", "--verify", "--quiet",
"refs/tags/" + tagName);
return commandResult.getExitCode() == SUCCESS_EXIT_CODE;
}
/**
* Executes git checkout.
*
* @param branchName
* Branch name to checkout.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitCheckout(final String branchName)
throws MojoFailureException, CommandLineException {
getLog().info("Checking out '" + branchName + "' branch.");
executeGitCommand("checkout", branchName);
}
/**
* Executes git checkout -b.
*
* @param newBranchName
* Create branch with this name.
* @param fromBranchName
* Create branch from this branch.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitCreateAndCheckout(final String newBranchName,
final String fromBranchName) throws MojoFailureException,
CommandLineException {
getLog().info(
"Creating a new branch '" + newBranchName + "' from '"
+ fromBranchName + "' and checking it out.");
executeGitCommand("checkout", "-b", newBranchName, fromBranchName);
}
/**
* Executes git branch.
*
* @param newBranchName
* Create branch with this name.
* @param fromBranchName
* Create branch from this branch.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitCreateBranch(final String newBranchName, final String fromBranchName)
throws MojoFailureException, CommandLineException {
getLog().info(
"Creating a new branch '" + newBranchName + "' from '"
+ fromBranchName + "'.");
executeGitCommand("branch", newBranchName, fromBranchName);
}
/**
* Executes git commit -a -m.
*
* @param message
* Commit message.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitCommit(final String message) throws MojoFailureException,
CommandLineException {
gitCommit(message, null);
}
/**
* Executes git commit -a -m, replacing @{map.key}
with
* map.value
.
*
* @param message
* Commit message.
* @param map
* Key is a string to replace wrapped in @{...}
.
* Value is a string to replace with.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitCommit(String message, Map map)
throws MojoFailureException, CommandLineException {
if (map != null) {
for (Entry entr : map.entrySet()) {
message = StringUtils.replace(message, "@{" + entr.getKey()
+ "}", entr.getValue());
}
}
if (gpgSignCommit) {
getLog().info("Committing changes. GPG-signed.");
executeGitCommand("commit", "-a", "-S", "-m", message);
} else {
getLog().info("Committing changes.");
executeGitCommand("commit", "-a", "-m", message);
}
}
/**
* Executes git rebase or git merge --ff-only or git merge --no-ff or git merge.
*
* @param branchName
* Branch name to merge.
* @param rebase
* Do rebase.
* @param noff
* Merge with --no-ff.
* @param ffonly
* Merge with --ff-only.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitMerge(final String branchName, boolean rebase, boolean noff, boolean ffonly)
throws MojoFailureException, CommandLineException {
String sign = "";
if (gpgSignCommit) {
sign = "-S";
}
if (rebase) {
getLog().info("Rebasing '" + branchName + "' branch.");
executeGitCommand("rebase", sign, branchName);
} else if (ffonly) {
getLog().info("Merging (--ff-only) '" + branchName + "' branch.");
executeGitCommand("merge", "--ff-only", sign, branchName);
} else if (noff) {
getLog().info("Merging (--no-ff) '" + branchName + "' branch.");
executeGitCommand("merge", "--no-ff", sign, branchName);
} else {
getLog().info("Merging '" + branchName + "' branch.");
executeGitCommand("merge", sign, branchName);
}
}
/**
* Executes git merge --no-ff.
*
* @param branchName
* Branch name to merge.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitMergeNoff(final String branchName)
throws MojoFailureException, CommandLineException {
gitMerge(branchName, false, true, false);
}
/**
* Executes git merge --squash.
*
* @param branchName
* Branch name to merge.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitMergeSquash(final String branchName)
throws MojoFailureException, CommandLineException {
getLog().info("Squashing '" + branchName + "' branch.");
executeGitCommand("merge", "--squash", branchName);
}
/**
* Executes git tag -a [-s] -m.
*
* @param tagName
* Name of the tag.
* @param message
* Tag message.
* @param gpgSignTag
* Make a GPG-signed tag.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitTag(final String tagName, final String message, boolean gpgSignTag)
throws MojoFailureException, CommandLineException {
if (gpgSignTag) {
getLog().info("Creating GPG-signed '" + tagName + "' tag.");
executeGitCommand("tag", "-a", "-s", tagName, "-m", message);
} else {
getLog().info("Creating '" + tagName + "' tag.");
executeGitCommand("tag", "-a", tagName, "-m", message);
}
}
/**
* Executes git branch -d.
*
* @param branchName
* Branch name to delete.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitBranchDelete(final String branchName)
throws MojoFailureException, CommandLineException {
getLog().info("Deleting '" + branchName + "' branch.");
executeGitCommand("branch", "-d", branchName);
}
/**
* Executes git branch -D.
*
* @param branchName
* Branch name to delete.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitBranchDeleteForce(final String branchName)
throws MojoFailureException, CommandLineException {
getLog().info("Deleting (-D) '" + branchName + "' branch.");
executeGitCommand("branch", "-D", branchName);
}
/**
* Fetches and checkouts from remote if local branch doesn't exist.
*
* @param branchName
* Branch name to check.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitFetchRemoteAndCreate(final String branchName)
throws MojoFailureException, CommandLineException {
if (!gitCheckBranchExists(branchName)) {
getLog().info(
"Local branch '"
+ branchName
+ "' doesn't exist. Trying to fetch and check it out from '"
+ gitFlowConfig.getOrigin() + "'.");
gitFetchRemote(branchName);
gitCreateAndCheckout(branchName, gitFlowConfig.getOrigin() + "/"
+ branchName);
}
}
/**
* Executes git fetch and compares local branch with the remote.
*
* @param branchName
* Branch name to fetch and compare.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitFetchRemoteAndCompare(final String branchName)
throws MojoFailureException, CommandLineException {
if (gitFetchRemote(branchName)) {
getLog().info(
"Comparing local branch '" + branchName + "' with remote '"
+ gitFlowConfig.getOrigin() + "/" + branchName
+ "'.");
String revlistout = executeGitCommandReturn("rev-list",
"--left-right", "--count", branchName + "..."
+ gitFlowConfig.getOrigin() + "/" + branchName);
String[] counts = org.apache.commons.lang3.StringUtils.split(
revlistout, '\t');
if (counts != null && counts.length > 1) {
if (!"0".equals(org.apache.commons.lang3.StringUtils
.deleteWhitespace(counts[1]))) {
throw new MojoFailureException("Remote branch '"
+ gitFlowConfig.getOrigin() + "/" + branchName
+ "' is ahead of the local branch '" + branchName
+ "'. Execute git pull.");
}
}
}
}
/**
* Executes git fetch.
*
* @param branchName
* Branch name to fetch.
* @return true
if git fetch returned success exit code,
* false
otherwise.
* @throws MojoFailureException
* @throws CommandLineException
*/
private boolean gitFetchRemote(final String branchName)
throws MojoFailureException, CommandLineException {
getLog().info(
"Fetching remote branch '" + gitFlowConfig.getOrigin() + " "
+ branchName + "'.");
CommandResult result = executeGitCommandExitCode("fetch", "--quiet",
gitFlowConfig.getOrigin(), branchName);
boolean success = result.getExitCode() == SUCCESS_EXIT_CODE;
if (!success) {
getLog().warn(
"There were some problems fetching remote branch '"
+ gitFlowConfig.getOrigin()
+ " "
+ branchName
+ "'. You can turn off remote branch fetching by setting the 'fetchRemote' parameter to false.");
}
return success;
}
/**
* Executes git push, optionally with the --follow-tags
* argument.
*
* @param branchName
* Branch name to push.
* @param pushTags
* If true
adds --follow-tags
argument
* to the git push
command.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void gitPush(final String branchName, boolean pushTags)
throws MojoFailureException, CommandLineException {
getLog().info(
"Pushing '" + branchName + "' branch" + " to '"
+ gitFlowConfig.getOrigin() + "'.");
if (pushTags) {
executeGitCommand("push", "--quiet", "-u", "--follow-tags",
gitFlowConfig.getOrigin(), branchName);
} else {
executeGitCommand("push", "--quiet", "-u",
gitFlowConfig.getOrigin(), branchName);
}
}
protected void gitPushDelete(final String branchName)
throws MojoFailureException, CommandLineException {
getLog().info(
"Deleting remote branch '" + branchName + "' from '"
+ gitFlowConfig.getOrigin() + "'.");
CommandResult result = executeGitCommandExitCode("push", "--delete",
gitFlowConfig.getOrigin(), branchName);
if (result.getExitCode() != SUCCESS_EXIT_CODE) {
getLog().warn(
"There were some problems deleting remote branch '"
+ branchName + "' from '"
+ gitFlowConfig.getOrigin() + "'.");
}
}
/**
* Executes 'set' goal of versions-maven-plugin or 'set-version' of
* tycho-versions-plugin in case it is tycho build.
*
* @param version
* New version to set.
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void mvnSetVersions(final String version)
throws MojoFailureException, CommandLineException {
getLog().info("Updating version(s) to '" + version + "'.");
if (tychoBuild) {
executeMvnCommand(TYCHO_VERSIONS_PLUGIN_SET_GOAL, "-DnewVersion="
+ version, "-Dtycho.mode=maven");
} else {
executeMvnCommand(VERSIONS_MAVEN_PLUGIN_SET_GOAL, "-DnewVersion="
+ version, "-DgenerateBackupPoms=false");
}
}
/**
* Executes mvn clean test.
*
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void mvnCleanTest() throws MojoFailureException,
CommandLineException {
getLog().info("Cleaning and testing the project.");
if (tychoBuild) {
executeMvnCommand("clean", "verify");
} else {
executeMvnCommand("clean", "test");
}
}
/**
* Executes mvn clean install.
*
* @throws MojoFailureException
* @throws CommandLineException
*/
protected void mvnCleanInstall() throws MojoFailureException,
CommandLineException {
getLog().info("Cleaning and installing the project.");
executeMvnCommand("clean", "install");
}
/**
* Executes Maven goals.
*
* @param goals
* The goals to execute.
* @throws Exception
*/
protected void mvnRun(final String goals) throws Exception {
getLog().info("Running Maven goals: " + goals);
executeMvnCommand(CommandLineUtils.translateCommandline(goals));
}
/**
* Executes Git command and returns output.
*
* @param args
* Git command line arguments.
* @return Command output.
* @throws CommandLineException
* @throws MojoFailureException
*/
private String executeGitCommandReturn(final String... args)
throws CommandLineException, MojoFailureException {
return executeCommand(cmdGit, true, null, args).getOut();
}
/**
* Executes Git command without failing on non successful exit code.
*
* @param args
* Git command line arguments.
* @return Command result.
* @throws CommandLineException
* @throws MojoFailureException
*/
private CommandResult executeGitCommandExitCode(final String... args)
throws CommandLineException, MojoFailureException {
return executeCommand(cmdGit, false, null, args);
}
/**
* Executes Git command.
*
* @param args
* Git command line arguments.
* @throws CommandLineException
* @throws MojoFailureException
*/
private void executeGitCommand(final String... args)
throws CommandLineException, MojoFailureException {
executeCommand(cmdGit, true, null, args);
}
/**
* Executes Maven command.
*
* @param args
* Maven command line arguments.
* @throws CommandLineException
* @throws MojoFailureException
*/
private void executeMvnCommand(final String... args)
throws CommandLineException, MojoFailureException {
executeCommand(cmdMvn, true, argLine, args);
}
/**
* Executes command line.
*
* @param cmd
* Command line.
* @param failOnError
* Whether to throw exception on NOT success exit code.
* @param argStr
* Command line arguments as a string.
* @param args
* Command line arguments.
* @return {@link CommandResult} instance holding command exit code, output
* and error if any.
* @throws CommandLineException
* @throws MojoFailureException
* If failOnError
is true
and command
* exit code is NOT equals to 0.
*/
private CommandResult executeCommand(final Commandline cmd,
final boolean failOnError, final String argStr,
final String... args) throws CommandLineException,
MojoFailureException {
// initialize executables
initExecutables();
if (getLog().isDebugEnabled()) {
getLog().debug(
cmd.getExecutable() + " " + StringUtils.join(args, " ")
+ (argStr == null ? "" : " " + argStr));
}
cmd.clearArgs();
cmd.addArguments(args);
if (StringUtils.isNotBlank(argStr)) {
cmd.createArg().setLine(argStr);
}
final StringBufferStreamConsumer out = new StringBufferStreamConsumer(
verbose);
final CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
// execute
final int exitCode = CommandLineUtils.executeCommandLine(cmd, out, err);
String errorStr = err.getOutput();
String outStr = out.getOutput();
if (failOnError && exitCode != SUCCESS_EXIT_CODE) {
// not all commands print errors to error stream
if (StringUtils.isBlank(errorStr) && StringUtils.isNotBlank(outStr)) {
errorStr = outStr;
}
throw new MojoFailureException(errorStr);
}
return new CommandResult(exitCode, outStr, errorStr);
}
private static class CommandResult {
private final int exitCode;
private final String out;
private final String error;
private CommandResult(final int exitCode, final String out,
final String error) {
this.exitCode = exitCode;
this.out = out;
this.error = error;
}
/**
* @return the exitCode
*/
public int getExitCode() {
return exitCode;
}
/**
* @return the out
*/
public String getOut() {
return out;
}
/**
* @return the error
*/
public String getError() {
return error;
}
}
public void setArgLine(String argLine) {
this.argLine = argLine;
}
}