org.kuali.maven.plugins.fusion.FuseMojo Maven / Gradle / Ivy
/**
*
*/
package org.kuali.maven.plugins.fusion;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.kuali.maven.plugins.fusion.util.GitFusionUtils;
import org.kuali.student.git.model.GitRepositoryUtils;
import org.kuali.student.git.model.ExternalModuleUtils;
import org.kuali.student.git.model.ref.utils.GitRefUtils;
import org.kuali.student.git.utils.ExternalGitUtils;
import org.kuali.student.svn.model.ExternalModuleInfo;
/**
* @author ocleirig
*
*/
@Mojo(name = FusionMavenPluginConstants.FUSE_MOJO)
@Execute(goal = FusionMavenPluginConstants.FUSE_MOJO)
public class FuseMojo extends AbstractFusionMojo {
/*
* The location of a text file that contains the fusion-maven-plugin.dat definitions
*
*/
@Parameter (property=FusionMavenPluginConstants.PREFER_FUSION_DATA_FILE, defaultValue=FusionMavenPluginConstants.PREFER_FUSION_DATA_FILE_DEFAULT)
protected String preferFusionDataFile;
/*
* Resolve the fusion heads using the latest values for the branches named.
*
*/
@Parameter (property=FusionMavenPluginConstants.FUSE_LATEST_BRANCH_HEADS, defaultValue=FusionMavenPluginConstants.FUSE_LATEST_BRANCH_HEADS_DEFAULT)
protected String fuseLatestBranchHeads;
/*
* The location of a text file that contains the fusion-maven-plugin.dat definitions
*
*/
@Parameter (property=FusionMavenPluginConstants.FUSION_DATA_FILE, defaultValue=FusionMavenPluginConstants.FUSION_DATA_FILE_DEFAULT)
protected File fusionDataFile;
/*
* true or false and is used to determine if we should check out the newly
* created fused branch.
*/
@Parameter(property = FusionMavenPluginConstants.CHECKOUT_FUSED_BRANCH_PREFIX, defaultValue = FusionMavenPluginConstants.CHECKOUT_FUSED_BRANCH_PREFIX_DEFAULT)
protected String checkoutFusedBranch;
/**
*
*/
public FuseMojo() {
// TODO Auto-generated constructor stub
}
/*
* (non-Javadoc)
*
* @see org.apache.maven.plugin.Mojo#execute()
*/
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
try {
/*
* Assume that we are running on the aggregate and that the
* configuration will tell us how to fuse with our modules.
*/
File baseDir = project.getBasedir();
/*
* Assume that the pom is located in the working copy of the git
* repository on the branch we want to fuse into
*/
Repository repo = GitRepositoryUtils.buildFileRepository(baseDir,
false, false);
ObjectReader objectReader = repo.newObjectReader();
ObjectInserter objectInserter = repo.newObjectInserter();
RevWalk rw = new RevWalk(repo);
String currentBranchName = repo.getBranch();
Ref currentHead = repo
.getRef(Constants.R_HEADS + currentBranchName);
RevCommit commit = rw.parseCommit(currentHead.getObjectId());
List externals = new ArrayList<>();
Set mergeParents = new HashSet<>();
Set mergedModules = new HashSet<>();
mergeParents.add(currentHead.getObjectId());
if (nullSafePropertyValueCheck(this.preferFusionDataFile, "true") && this.fusionDataFile != null) {
/*
* Could change this to look into the tree of the aggregate and if present then reconstitute using this file.
*
* The flag would then become more of a use file if it exists instead of the mappings from the pom.xml
*/
FileInputStream inputStream;
/*
* Source the externals from the file not the pom.
*/
externals.addAll(ExternalModuleUtils.extractFusionMavenPluginData(inputStream = new FileInputStream (this.fusionDataFile)));
inputStream.close();
for (ExternalModuleInfo external : externals) {
ObjectId commitId = external.getBranchHeadId();
if (nullSafePropertyValueCheck(this.fuseLatestBranchHeads, "true")) {
// resolve using the latest branch version
Ref ref = repo.getRef(external.getBranchName());
if (ref == null) {
ref = repo.getRef(getBranchName (external));
if (ref == null)
throw new MojoFailureException("For module: " + external.getModuleName() + "Can't resolve branch name: " + external.getBranchName());
}
ObjectId latestCommitId = ref.getObjectId();
getLog().info("overriding " + commitId.name() + " with the latest commit on branch: " + external.getBranchName() + " with : " + latestCommitId.name());
commitId = latestCommitId;
external.setBranchHeadId(commitId);
}
mergeParents.add(commitId);
mergedModules.add(external.getModuleName());
}
} else {
if (mappings == null)
throw new MojoFailureException("There are no mappings defined in the pom.xml file");
for (Mapping mapping : mappings) {
Ref branchHead = repo.getRef(getBranchName(mapping));
if (branchHead == null) {
objectReader.release();
objectInserter.flush();
rw.release();
repo.close();
throw new MojoFailureException(
"Unable to find a branch head for : "
+ mapping.getBranchName());
}
ObjectId headCommitId = branchHead.getObjectId();
ExternalModuleInfo external = new ExternalModuleInfo(
mapping.getModule(), mapping.getBranchName(),
headCommitId);
externals.add(external);
mergeParents.add(headCommitId);
mergedModules.add(mapping.getModule());
}
}
AnyObjectId fusedTree = ExternalModuleUtils.createFusedTree(
objectReader, objectInserter, rw, commit, externals, true);
/*
* Who should we commit as? and where should that be specified?
*
* I think we might be able to use something like how the build
* number is set.
*/
ObjectId commitId = GitFusionUtils.commit(objectInserter, "jcaddel", "[email protected]", "Fused " + currentBranchName, fusedTree.toObjectId(), mergeParents);
String fusedBranchName = "fused_" + currentBranchName;
Ref branch = GitRefUtils.createOrUpdateBranch(repo,
Constants.R_HEADS + fusedBranchName, commitId);
if (branch == null)
throw new MojoFailureException(
"Unable to create fused branch: " + fusedBranchName);
getLog().info(
"created fused branch : " + fusedBranchName
+ " from modules : "
+ StringUtils.join(mergedModules.iterator(), ", "));
if (this.checkoutFusedBranch != null
&& this.checkoutFusedBranch.equals("true")) {
if (this.externalCGitCommand != null) {
// use C git
if (!ExternalGitUtils.checkoutBranch(this.externalCGitCommand, repo, fusedBranchName, true, System.out)) {
getLog().error("Failed to checkout " + fusedBranchName);
}
}
else {
CheckoutCommand checkOutCommand = new Git(repo).checkout();
checkOutCommand.setName(fusedBranchName);
checkOutCommand.setCreateBranch(false);
checkOutCommand.setForce(true);
Ref ref = checkOutCommand.call();
if (ref == null)
throw new MojoFailureException(
"Unable to checkout fused branch: "
+ fusedBranchName);
getLog().info("checkedout fused branch : " + fusedBranchName);
}
}
objectReader.release();
objectInserter.flush();
rw.release();
repo.close();
} catch (Exception e) {
if (e instanceof MojoExecutionException)
throw (MojoExecutionException) e;
else if (e instanceof MojoFailureException)
throw (MojoFailureException) e;
else
throw new MojoExecutionException(
"FuseMojo failed unexpectantly: ", e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy