@Option(name = "ref", description = "branch or tag to build") final String refName,
@Option(name = "checkoutDir", description = "directory in which to clone the repository") final Resource<?> checkoutResource,
@Option(name = "keepSources", description = "keep the sources after checking out", defaultValue = "false", flagOnly = true) final boolean keepSources,
final PipeOut out) throws Exception
{
DirectoryResource buildDir;
if (checkoutResource != null)
{
if (!(checkoutResource instanceof FileResource<?>))
{
throw new IllegalArgumentException("Checkout dir must be a directory path");
}
FileResource<?> checkoutDir = (FileResource<?>) checkoutResource;
// Resource already exists
if (checkoutDir.exists())
{
// Check if it is already a directory
if (!checkoutDir.isDirectory())
{
throw new RuntimeException("Resource " + checkoutDir.getFullyQualifiedName()
+ " is not a valid directory.");
}
buildDir = checkoutDir.reify(DirectoryResource.class);
if (!shell.promptBoolean("Directory " + buildDir.getFullyQualifiedName()
+ " already exists. Do you want to overwrite?", false))
{
throw new AbortedException("Directory " + buildDir.getFullyQualifiedName()
+ " already exists");
}
buildDir.delete(true);
buildDir.mkdirs();
}
else
{
// Resource does not exist. Create it
checkoutDir.mkdirs();
buildDir = checkoutDir.reify(DirectoryResource.class);
}
}
else
{
buildDir = shell.getCurrentDirectory().createTempResource();
}
try
{
ShellMessages.info(out, "Checking out plugin source files to [" + buildDir.getFullyQualifiedName()
+ "] via 'git'");
Git repo = GitUtils.clone(buildDir, gitRepo);
Ref ref = null;
String targetRef = refName;
if (targetRef == null)
{
// Default to Forge runtime version if no Ref name is supplied.
targetRef = environment.getRuntimeVersion();
}
if (targetRef != null)
{
// Try to find a Tag matching the given Ref name or runtime version
Map<String, Ref> tags = repo.getRepository().getTags();
ref = tags.get(targetRef);
// Now try to find a matching Branch
if (ref == null)
{
List<Ref> refs = GitUtils.getRemoteBranches(repo);
for (Ref branchRef : refs)
{
String branchName = branchRef.getName();
if (branchName != null && branchName.endsWith(targetRef))
{
ref = repo.branchCreate().setName(targetRef).setUpstreamMode(SetupUpstreamMode.TRACK)
.setStartPoint("origin/" + targetRef).call();
}
}
}
// Now try to find a tag or branch with same Major.Minor.(x) version.
if (ref == null)
{
// All
List<String> sortedVersions = new ArrayList<String>();
// Branches
for (Ref branchRef : GitUtils.getRemoteBranches(repo))
{
String branchName = branchRef.getName();
branchName = branchName.replaceFirst("refs/heads/", "");
if (InstalledPluginRegistry.isApiCompatible(targetRef, branchName))
sortedVersions.add(branchName);
}
// Tags
// Branches
for (String tag : tags.keySet())
{
if (InstalledPluginRegistry.isApiCompatible(targetRef, tag))
sortedVersions.add(tag);
}
// Sort
Collections.sort(sortedVersions);
if (!sortedVersions.isEmpty())
{
String version = sortedVersions.get(sortedVersions.size() - 1);
if (InstalledPluginRegistry.isApiCompatible(targetRef, version))
{
ref = tags.get(version);
if (ref == null)
{
ref = repo.branchCreate().setName(version).setUpstreamMode(SetupUpstreamMode.TRACK)
.setStartPoint("origin/" + version).call();
}
}
}
}
}
if (ref == null)
{
ref = repo.getRepository().getRef("master");
}
if (ref != null)
{
ShellMessages.info(out, "Switching to branch/tag [" + ref.getName() + "]");
GitUtils.checkout(repo, ref, false, SetupUpstreamMode.TRACK, false);
}
else if (refName != null)
{
throw new RuntimeException("Could not locate ref [" + targetRef + "] in repository ["
+ repo.getRepository().getDirectory().getAbsolutePath() + "]");
}
else
{
ShellMessages.warn(
out,
"Could not find a Ref matching the current Forge version ["
+ environment.getRuntimeVersion()
+ "], building Plugin from HEAD.");
}
buildFromCurrentProject(out, buildDir);
}
finally
{
if (buildDir != null)
{
if (keepSources)
{
ShellMessages.info(out,
"Sources are kept in [" + buildDir.getFullyQualifiedName() + "]");
}
else
{
ShellMessages.info(out,
"Cleaning up temp workspace [" + buildDir.getFullyQualifiedName()
+ "]");
buildDir.delete(true);
}
}
}
ShellMessages.success(out, "Installed from [" + gitRepo + "] successfully.");