src/main/java/com/github/koraktor/mavanagaiata/mojo/AbstractGitMojo.java
/*
* This code is free software; you can redistribute it and/or modify it under
* the terms of the new BSD License.
*
* Copyright (c) 2011-2019, Sebastian Staudt
*/
package com.github.koraktor.mavanagaiata.mojo;
import java.io.File;
import java.util.Properties;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import com.github.koraktor.mavanagaiata.git.GitRepository;
import com.github.koraktor.mavanagaiata.git.GitRepositoryException;
import com.github.koraktor.mavanagaiata.git.jgit.JGitRepository;
import static org.apache.commons.lang3.StringUtils.equalsAnyIgnoreCase;
import static org.eclipse.jgit.lib.Constants.*;
/**
* This abstract Mojo implements initializing a JGit Repository and provides
* this Repository instance to subclasses.
*
* @author Sebastian Staudt
* @see GitRepository
* @since 0.1.0
*/
abstract class AbstractGitMojo extends AbstractMojo {
/**
* The date format to use for various dates
*/
@Parameter(property = "mavanagaiata.dateFormat",
defaultValue = "MM/dd/yyyy hh:mm a Z")
protected String dateFormat;
/**
* The working tree of the Git repository.
* <p>
* If there is only one project inside the Git repository this is probably
* {@code ${project.basedir}} (default).
* <p>
* <strong>Note:</strong> The {@code GIT_DIR} can be found automatically
* even if this is not the real working tree but one of its subdirectories.
* But Mavanagaiata cannot determine the state of the working tree (e.g.
* for the dirty flag) if this is not set correctly.
*/
@Parameter(property = "mavanagaiata.baseDir",
defaultValue = "${project.basedir}")
File baseDir;
/**
* The flag to append to refs if there are changes in the index or working
* tree
* <p>
* Setting this to either {@code "false"} or {@code "null"} will disable
* flagging refs as dirty.
*
* @since 0.4.0
*/
@Parameter(property = "mavanagaiata.dirtyFlag",
defaultValue = "-dirty")
String dirtyFlag;
/**
* Specifies if the dirty flag should also be appended if there are
* untracked files
* <p>
* If {@code false} only modified files that are already known to Git will
* cause the dirty flag to be appended.
* <p>
* <strong>Warning:</strong> Do not enable this if builds should be
* reproducible.
*
* @since 0.5.0
*/
@Parameter(property = "mavanagaiata.dirtyIgnoreUntracked",
defaultValue = "false")
boolean dirtyIgnoreUntracked;
/**
* Specifies if a failed execution of the mojo will stop the build process
* <p>
* If {@code true} a failure during mojo execution will not stop the build
* process.
*
* @since 0.6.0
*/
@Parameter(property = "mavanagaiata.failGracefully",
defaultValue = "false")
boolean failGracefully;
/**
* The {@code GIT_DIR} path of the Git repository
* <p>
* <strong>Warning:</strong> Do not set this when you don't have a good
* reason to do so. The {@code GIT_DIR} can be found automatically if your
* project resides somewhere in a usual Git repository.
*/
@Parameter(property = "mavanagaiata.gitDir")
File gitDir;
/**
* The commit or ref to use as starting point for operations
*/
@Parameter(property = "mavanagaiata.head",
defaultValue = HEAD)
String head;
/**
* Skip the plugin execution
*
* @since 0.5.0
*/
@Parameter(property = "mavanagaiata.skip",
defaultValue = "false")
boolean skip;
/**
* Skip the plugin execution if not inside a Git repository
*
* @since 0.5.0
*/
@Parameter(property = "mavanagaiata.skipNoGit",
defaultValue = "false")
boolean skipNoGit;
/**
* The Maven project
*/
@Parameter(defaultValue = "${project}", readonly = true)
protected MavenProject project;
/**
* The prefixes to prepend to property keys
*/
@Parameter(property = "mavanagaiata.propertyPrefixes",
defaultValue = "mavanagaiata,mvngit")
String[] propertyPrefixes = { "mavanagaiata", "mvngit" };
/**
* Generic execution sequence for a Mavanagaiata mojo
* <p>
* Will initialize any needed resources, run the actual mojo code and
* cleanup afterwards.
*
* @see #init
* @see #run
* @throws MojoExecutionException if the mojo execution fails and
* {@code failGracefully} is {@code false}
* @throws MojoFailureException if the mojo execution fails and
* {@code failGracefully} is {@code true}
*/
public final void execute()
throws MojoExecutionException, MojoFailureException {
if (skip) {
return;
}
try (GitRepository repository = init()) {
if (repository != null) {
run(repository);
}
} catch (MavanagaiataMojoException e) {
if (failGracefully || e.isGraceful()) {
throw new MojoFailureException(e.getMessage(), e);
}
throw new MojoExecutionException(e.getMessage(), e);
}
}
/**
* Saves a property with the given name into the project's properties
* <p>
* The value will be stored two times – with "mavanagaiata" and "mvngit" as
* a prefix.
*
* @param name The property name
* @param value The value of the property
*/
void addProperty(String name, String value) {
Properties properties = project.getProperties();
for (String prefix : propertyPrefixes) {
properties.put(prefix + "." + name, value);
}
if (getLog().isDebugEnabled()) {
getLog().debug(String.format("Added property %s: %s", name, value));
}
}
/**
* Generic initialization for all Mavanagaiata mojos
* <p>
* This will initialize the JGit repository instance for further usage by
* the mojo.
*
* @return {@code false} if the execution should be skipped
* @throws MavanagaiataMojoException if the repository cannot be initialized
*/
protected GitRepository init() throws MavanagaiataMojoException {
try {
prepareParameters();
GitRepository repository = initRepository();
if (repository.isOnUnbornBranch()) {
getLog().warn("Building from an unborn branch. Skipping…");
return null;
}
return repository;
} catch (GitRepositoryException e) {
if (skipNoGit) {
return null;
}
throw MavanagaiataMojoException.create("Unable to initialize Git repository", e);
}
}
/**
* Initializes a JGit Repository object for further reference
*
* @return The repository instance
* @throws GitRepositoryException if retrieving information from the Git
* repository fails
*/
GitRepository initRepository() throws GitRepositoryException {
GitRepository repository = new JGitRepository(baseDir, gitDir, head);
repository.check();
return repository;
}
/**
* Prepares and validates user-supplied parameters
*/
void prepareParameters() {
if (equalsAnyIgnoreCase(dirtyFlag, "false", "null")) {
dirtyFlag = null;
}
}
/**
* The actual implementation of the mojo
*
* @param repository The repository instance to use
* @throws MavanagaiataMojoException if there is an error during execution
*/
protected abstract void run(GitRepository repository) throws MavanagaiataMojoException;
}