Java tutorial
/******************************************************************************* * Copyright (c) 2012 Sonatype Inc. 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: * Sonatype Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.tycho.extras.buildtimestamp.jgit; import java.io.IOException; import java.util.Date; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.tycho.buildversion.BuildTimestampProvider; /** * Build timestamp provider that returns date of the most recent commit that touches any file under * project basedir. File additional flexibility, some files can be ignored using gitignore patters * specified in <jgit.ignore> element of tycho-packaging-plugin configuration block * * <p> * Typical usage * * <pre> * ... * <plugin> * <groupId>org.eclipse.tycho</groupId> * <artifactId>tycho-packaging-plugin</artifactId> * <version>${tycho-version}</version> * <dependencies> * <dependency> * <groupId>org.eclipse.tycho.extras</groupId> * <artifactId>tycho-buildtimestamp-jgit</artifactId> * <version>${tycho-version}</version> * </dependency> * </dependencies> * <configuration> * <timestampProvider>jgit</timestampProvider> * <jgit.ignore>pom.xml</jgit.ignore> * </configuration> * </plugin> * ... * </pre> */ @Component(role = BuildTimestampProvider.class, hint = "jgit") public class JGitBuildTimestampProvider implements BuildTimestampProvider { public Date getTimestamp(MavenSession session, MavenProject project, MojoExecution execution) throws MojoExecutionException { FileRepositoryBuilder builder = new FileRepositoryBuilder() // .readEnvironment() // .findGitDir(project.getBasedir()) // .setMustExist(true); try { Repository repository = builder.build(); try { RevWalk walk = new RevWalk(repository); try { String relPath = getRelPath(repository, project); if (relPath != null && relPath.length() > 0) { walk.setTreeFilter(AndTreeFilter.create(new PathFilter(relPath, getIgnoreFilter(execution)), TreeFilter.ANY_DIFF)); } // TODO make sure working tree is clean ObjectId headId = repository.resolve(Constants.HEAD); walk.markStart(walk.parseCommit(headId)); RevCommit commit = walk.next(); return new Date(commit.getCommitTime() * 1000L); } finally { walk.release(); } } finally { repository.close(); } } catch (IOException e) { throw new MojoExecutionException("Could not determine git commit timestamp", e); } } private String getIgnoreFilter(MojoExecution execution) { Xpp3Dom pluginConfiguration = (Xpp3Dom) execution.getPlugin().getConfiguration(); Xpp3Dom ignoreDom = pluginConfiguration.getChild("jgit.ignore"); if (ignoreDom == null) { return null; } return ignoreDom.getValue(); } private String getRelPath(Repository repository, MavenProject project) throws IOException { String workTree = repository.getWorkTree().getAbsolutePath(); String path = project.getBasedir().getAbsolutePath(); if (!path.startsWith(workTree)) { throw new IOException(project + " is not in git repository working tree " + repository.getWorkTree()); } path = path.substring(workTree.length()); if (path.startsWith("/")) { path = path.substring(1); } return path; } }