| /******************************************************************************* |
| * 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; |
| } |
| |
| } |