| /******************************************************************************* |
| * Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com> |
| * |
| * 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: |
| * Chris Aniszczyk - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.egit.internal.relengtools; |
| |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.commands.AbstractHandler; |
| import org.eclipse.core.commands.ExecutionEvent; |
| import org.eclipse.core.commands.ExecutionException; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExecutableExtension; |
| import org.eclipse.egit.core.project.RepositoryMapping; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jgit.api.Git; |
| import org.eclipse.jgit.api.LogCommand; |
| import org.eclipse.jgit.api.errors.NoHeadException; |
| import org.eclipse.jgit.errors.IncorrectObjectTypeException; |
| import org.eclipse.jgit.errors.MissingObjectException; |
| 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.revwalk.RevCommit; |
| import org.eclipse.jgit.revwalk.RevObject; |
| import org.eclipse.jgit.revwalk.RevSort; |
| import org.eclipse.jgit.revwalk.RevTag; |
| import org.eclipse.jgit.revwalk.RevWalk; |
| import org.eclipse.jgit.treewalk.filter.AndTreeFilter; |
| import org.eclipse.jgit.treewalk.filter.PathFilter; |
| import org.eclipse.jgit.treewalk.filter.TreeFilter; |
| import org.eclipse.ui.handlers.HandlerUtil; |
| import org.eclipse.ui.internal.util.Util; |
| |
| public class ShowInfoHandler extends AbstractHandler implements |
| IExecutableExtension { |
| static final String OLD_TAG = "v20100723-1115"; |
| |
| static final String NEW_TAG = "v20101018-1500"; |
| |
| private boolean runTest = false; |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands. |
| * ExecutionEvent) |
| */ |
| @Override |
| public Object execute(ExecutionEvent event) throws ExecutionException { |
| if (runTest) { |
| try { |
| runTest(); |
| } catch (final Exception e) { |
| throw new ExecutionException(e.getMessage(), e); |
| } |
| return null; |
| } |
| // show info on an existing project |
| final ISelection s = HandlerUtil.getCurrentSelection(event); |
| if (s instanceof IStructuredSelection) { |
| final Object obj = ((IStructuredSelection) s).getFirstElement(); |
| final IProject proj = (IProject) Util.getAdapter(obj, |
| IProject.class); |
| if (proj != null) { |
| try { |
| showInfo(proj); |
| } catch (final Exception e) { |
| throw new ExecutionException(e.getMessage(), e); |
| } |
| } |
| } |
| return null; |
| } |
| |
| private void runTest() throws Exception { |
| // first test project |
| deeplinkTest(); |
| |
| // second test project |
| handlerTest(); |
| } |
| |
| private void deeplinkTest() throws Exception { |
| final IProject deeplink = ResourcesPlugin.getWorkspace().getRoot() |
| .getProject("org.eclipse.e4.core.deeplink"); |
| System.out.println("\nTest for project: " + deeplink); |
| final RepositoryMapping rm = RepositoryMapping.getMapping(deeplink); |
| final Repository repo = rm.getRepository(); |
| final RevCommit expectedLastCommit = getCommit(repo, |
| "d660f0a07c8ff16c9b46b3d69bc1c271b2cf4aba"); |
| final RevCommit latestCommit = getLatestCommitFor(rm, repo, deeplink); |
| System.out.println(expectedLastCommit.equals(latestCommit) |
| + " Latest commit: expected: " + expectedLastCommit |
| + "\n\tgot: " + latestCommit); |
| |
| final Map<String, Ref> tags = repo.getTags(); |
| final Set<Ref> expectedTags = new HashSet<Ref>(Arrays.asList(tags |
| .get(NEW_TAG))); |
| final Set<Ref> twoTags = getTagsForCommit(repo, expectedLastCommit); |
| System.out.println(expectedTags.equals(twoTags) |
| + " Found tags: expected: " + expectedTags + "\n\tgot: " |
| + twoTags); |
| |
| final Set<Ref> tagsContainingCommit = getTagsContainingCommit(repo, |
| expectedLastCommit); |
| System.out.println(expectedTags.equals(tagsContainingCommit) |
| + " Found tags containing commit " + expectedLastCommit |
| + ":\n\texpected: " + expectedTags + "\n\tgot: " |
| + tagsContainingCommit); |
| } |
| |
| private void handlerTest() throws Exception { |
| final IProject handler = ResourcesPlugin.getWorkspace().getRoot() |
| .getProject("org.eclipse.e4.core.deeplink.handler"); |
| System.out.println("\nTest for project: " + handler); |
| final RepositoryMapping rm = RepositoryMapping.getMapping(handler); |
| final Repository repo = rm.getRepository(); |
| final RevCommit expectedLastCommit = getCommit(repo, |
| "b42ad39c90fc57b679154ca33dfb306004dc08a3"); |
| final RevCommit latestCommit = getLatestCommitFor(rm, repo, handler); |
| System.out.println(expectedLastCommit.equals(latestCommit) |
| + " Latest commit: expected: " + expectedLastCommit |
| + "\n\tgot: " + latestCommit); |
| |
| final Set<Ref> expectedTags = Collections.EMPTY_SET; |
| final Set<Ref> noTags = getTagsForCommit(repo, expectedLastCommit); |
| System.out.println(expectedTags.equals(noTags) |
| + " Found tags: expected: " + expectedTags + "\n\tgot: " |
| + noTags); |
| |
| final Map<String, Ref> tags = repo.getTags(); |
| final Set<Ref> expectedContainingTags = new HashSet<Ref>(Arrays.asList( |
| tags.get("R0_10"), tags.get("v20100722-1700"), |
| tags.get("v20100723-1115"), tags.get("v20101018-1500"))); |
| final Set<Ref> tagsContainingCommit = getTagsContainingCommit(repo, |
| expectedLastCommit); |
| System.out.println(expectedContainingTags.equals(tagsContainingCommit) |
| + " Found tags containing commit " + expectedLastCommit |
| + ":\n\texpected: " + expectedContainingTags + "\n\tgot: " |
| + tagsContainingCommit); |
| } |
| |
| /** |
| * @param proj |
| * @throws Exception |
| */ |
| private void showInfo(IProject proj) throws Exception { |
| final RepositoryMapping rm = RepositoryMapping.getMapping(proj); |
| final Repository repo = rm.getRepository(); |
| |
| // final RevCommit latestCommit = getLatestCommitFor(rm, repo, proj); |
| final RevCommit latestCommit = getLatestCommitFor(rm, repo, proj); |
| System.out |
| .println(latestCommit + ": " + latestCommit.getShortMessage()); |
| |
| final RevCommit oldCommit = getCommitForTag(repo, OLD_TAG); |
| |
| final RevCommit newCommit = getCommitForTag(repo, NEW_TAG); |
| |
| System.out.println(getTagsForCommit(repo, newCommit)); |
| System.out.println(getTagsForCommit(repo, newCommit)); |
| System.out.println(getTagsForCommit(repo, |
| getCommit(repo, "b42ad39c90fc57b679154ca33dfb306004dc08a3"))); |
| |
| showLogBetween(repo, oldCommit, newCommit); |
| } |
| |
| public static void showLogBetween(final Repository repo, |
| final RevCommit oldCommit, final RevCommit newCommit) |
| throws MissingObjectException, IncorrectObjectTypeException, |
| NoHeadException, Exception { |
| final Git git = new Git(repo); |
| final LogCommand command = git.log(); |
| command.addRange(oldCommit, newCommit); |
| System.out.println("\nCommits:"); |
| for (final RevCommit rc : command.call()) { |
| System.out.println(rc); |
| System.out.print("Tags: "); |
| System.out.println(getTagsForCommit(repo, rc)); |
| System.out.println(rc.getShortMessage()); |
| } |
| } |
| |
| public static RevCommit getLatestCommitFor(RepositoryMapping mapping, |
| Repository repo, IProject project) throws Exception { |
| final RevWalk walk = new RevWalk(repo); |
| walk.reset(); |
| walk.sort(RevSort.TOPO, true); |
| walk.sort(RevSort.COMMIT_TIME_DESC, true); |
| walk.setTreeFilter(AndTreeFilter.create(TreeFilter.ANY_DIFF, |
| PathFilter.create(mapping.getRepoRelativePath(project)))); |
| final ObjectId start = repo.resolve(Constants.HEAD); |
| walk.markStart(walk.parseCommit(start)); |
| |
| // I should only be able to see commits that contain files |
| // where project is a path prefix |
| final RevCommit commit = walk.next(); |
| return commit; |
| } |
| |
| public static RevCommit getCommitForTag(Repository repo, String name) |
| throws Exception { |
| final Ref ref = repo.getTags().get(name); |
| final RevWalk walk = new RevWalk(repo); |
| final RevObject obj = walk.parseAny(ref.getObjectId()); |
| final RevCommit tagCommit; |
| if (obj instanceof RevCommit) { |
| tagCommit = (RevCommit) obj; |
| } else { |
| tagCommit = walk.parseCommit(((RevTag) obj).getObject()); |
| } |
| return tagCommit; |
| } |
| |
| public static Set<Ref> getTagsForCommit(Repository repo, RevCommit c) |
| throws Exception { |
| initializeTagMap(repo); |
| Set<Ref> s = commitToTagRef.get(c); |
| if (s == null) { |
| s = Collections.EMPTY_SET; |
| } |
| return s; |
| } |
| |
| private static HashMap<RevCommit, Set<Ref>> commitToTagRef = null; |
| |
| private static void initializeTagMap(Repository repo) throws Exception { |
| if (commitToTagRef == null) { |
| final RevWalk walk = new RevWalk(repo); |
| commitToTagRef = new HashMap<RevCommit, Set<Ref>>(); |
| for (final Ref ref : repo.getTags().values()) { |
| final RevObject obj = walk.parseAny(ref.getObjectId()); |
| RevCommit commit = null; |
| if (obj instanceof RevCommit) { |
| commit = (RevCommit) obj; |
| } else if (obj instanceof RevTag) { |
| commit = walk.parseCommit(((RevTag) obj).getObject()); |
| } |
| |
| Set<Ref> tags = commitToTagRef.get(commit); |
| if (tags == null) { |
| tags = new HashSet<Ref>(); |
| commitToTagRef.put(commit, tags); |
| } |
| tags.add(ref); |
| } |
| } |
| } |
| |
| // mimic git tag --contains <commit> |
| private static Set<Ref> getTagsContainingCommit(Repository repo, |
| RevCommit commit) throws Exception { |
| final Set<Ref> tags = new HashSet<Ref>(); |
| final RevWalk walk = new RevWalk(repo); |
| commit = walk.parseCommit(commit); |
| for (final Ref ref : repo.getTags().values()) { |
| final RevCommit tagCommit; |
| try { |
| tagCommit = walk.parseCommit(ref.getObjectId()); |
| } catch (final IncorrectObjectTypeException notCommit) { |
| continue; |
| } |
| if (walk.isMergedInto(commit, tagCommit)) { |
| tags.add(ref); |
| } |
| } |
| return tags; |
| } |
| |
| public static RevCommit getCommit(Repository repo, String name) |
| throws Exception { |
| final RevWalk walk = new RevWalk(repo); |
| final ObjectId id = repo.resolve(name); |
| return walk.parseCommit(id); |
| } |
| |
| @Override |
| public void setInitializationData(IConfigurationElement config, |
| String propertyName, Object data) throws CoreException { |
| if ("test".equals(data)) { |
| runTest = true; |
| } |
| } |
| } |