blob: 56c0ad18e0ed5191ca756c6ffd26741e095912d3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP AG - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.extras.sourceref.jgit;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.AmbiguousObjectException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.tycho.packaging.sourceref.ScmUrl;
import org.eclipse.tycho.packaging.sourceref.SourceReferencesProvider;
@Component(role = SourceReferencesProvider.class, hint = "git")
public class JGitSourceReferencesProvider implements SourceReferencesProvider {
@Override
public String getSourceReferencesHeader(MavenProject project, ScmUrl scmUrl) throws MojoExecutionException {
File basedir = project.getBasedir().getAbsoluteFile();
FileRepositoryBuilder builder = new FileRepositoryBuilder().readEnvironment().findGitDir(basedir)
.setMustExist(true);
Repository repo;
Git git;
try {
repo = builder.build();
git = Git.wrap(repo);
} catch (IOException e) {
throw new MojoExecutionException("IO exception trying to create git repo ", e);
}
ObjectId head = resolveHead(repo);
StringBuilder result = new StringBuilder(scmUrl.getUrl());
result.append(";path=\"");
result.append(getRelativePath(basedir, repo.getWorkTree()));
result.append("\"");
String tag = findTagForHead(git, head);
if (tag != null) {
// may contain e.g. spaces, so we quote it
result.append(";tag=\"");
result.append(tag);
result.append("\"");
}
result.append(";commitId=");
result.append(head.getName());
return result.toString();
}
private ObjectId resolveHead(Repository repo) throws MojoExecutionException {
ObjectId head;
try {
head = repo.resolve(Constants.HEAD);
} catch (AmbiguousObjectException e) {
throw new MojoExecutionException("exception trying resolve HEAD", e);
} catch (IOException e) {
throw new MojoExecutionException("exception trying resolve HEAD", e);
}
return head;
}
private String findTagForHead(Git git, ObjectId head) throws MojoExecutionException {
String tag = null;
try {
for (Ref ref : git.tagList().call()) {
ObjectId objectId = ref.getPeeledObjectId();
if (objectId == null) {
objectId = ref.getObjectId();
}
if (head.equals(objectId)) {
tag = ref.getName();
if (tag.startsWith(Constants.R_TAGS)) {
tag = tag.substring(Constants.R_TAGS.length());
}
break;
}
}
} catch (GitAPIException e) {
throw new MojoExecutionException("exception trying to get tag list", e);
}
return tag;
}
String getRelativePath(File subDir, File parentDir) throws MojoExecutionException {
URI subDirUri;
URI relativeUri;
try {
// have to canonicalize before comparing on case-insensitive filesystems
subDirUri = subDir.getCanonicalFile().toURI();
relativeUri = parentDir.getCanonicalFile().toURI().relativize(subDirUri);
} catch (IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
if (relativeUri.equals(subDirUri)) {
throw new MojoExecutionException(subDir + " is not a subdir of " + parentDir);
}
String relative = relativeUri.getPath();
// remove surrounding slashes
if (relative.startsWith("/")) {
relative = relative.substring(1);
}
if (relative.endsWith("/")) {
relative = relative.substring(0, relative.length() - 1);
}
return relative;
}
}