Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Rosenberg2011-06-17 06:32:09 +0000
committerMatthias Sohn2011-06-17 06:32:09 +0000
commit9ddb5f1e04cb23ab18e52db08c015d9926df3ca1 (patch)
tree2ffd2e36a22fdba0b9b737119ec0476ddf4598c2
parent719370df91eb06538fdd34e46fa795487b018162 (diff)
downloadegit-9ddb5f1e04cb23ab18e52db08c015d9926df3ca1.tar.gz
egit-9ddb5f1e04cb23ab18e52db08c015d9926df3ca1.tar.xz
egit-9ddb5f1e04cb23ab18e52db08c015d9926df3ca1.zip
Add support for git variables in launchers
This adds git_dir, git_work_tree, git_repo_relative_path and git_branch. They all work on the selected or named resource, i.e. ${git_branch} would return the current branch in the (first) selected project. ${git_branch:org.eclipse.jgit/.project} would return the current branch of the main JGit repository in the workspace. The code to pick the selected resource is stolen from Chris Aniszczyk's commit on a similar topic. Change-Id: Idad98f57440eb3b083ffd1be0f382bdac33963e3 Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/variables/DynamicVariablesTest.java189
-rw-r--r--org.eclipse.egit.ui/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.egit.ui/plugin.properties5
-rw-r--r--org.eclipse.egit.ui/plugin.xml27
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java9
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties3
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/variables/GitVariableResolver.java196
7 files changed, 430 insertions, 0 deletions
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/variables/DynamicVariablesTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/variables/DynamicVariablesTest.java
new file mode 100644
index 0000000000..62a79b9630
--- /dev/null
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/variables/DynamicVariablesTest.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (C) 2009, Robin Rosenberg
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * See LICENSE for the full license text, also available.
+ *******************************************************************************/
+package org.eclipse.egit.ui.variables;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.Collections;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.variables.IDynamicVariable;
+import org.eclipse.core.variables.VariablesPlugin;
+import org.eclipse.egit.core.GitProvider;
+import org.eclipse.egit.core.project.GitProjectData;
+import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.ui.common.EGitTestCase;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.storage.file.FileRepository;
+import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.ui.PlatformUI;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(SWTBotJunit4ClassRunner.class)
+public class DynamicVariablesTest extends EGitTestCase {
+
+ private File gitDir;
+ private File gitDir2;
+ private IProject project;
+ private IProject project2;
+ private FileRepository repository;
+ private FileRepository repository2;
+ private Git git;
+
+ private static final String TEST_PROJECT = "TestProject";
+ private static final String TEST_PROJECT_LOC = "Sub/TestProject";
+ private static final String TEST_PROJECT2 = "TestProject2";
+
+ private static final String TEST_FILE = "TestFile";
+ private static final String TEST_FILE2 = "TestFile2";
+
+ @Before
+ public void setUp() throws Exception {
+
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+ new File(root.getLocation().toFile(),"Sub").mkdir();
+ gitDir = new File(new File(root.getLocation().toFile(), "Sub"), Constants.DOT_GIT);
+
+ repository = new FileRepository(gitDir);
+ repository.create();
+
+ project = root.getProject(TEST_PROJECT);
+ project.create(null);
+ project.open(null);
+ IProjectDescription description = project.getDescription();
+ description.setLocation(root.getLocation().append(TEST_PROJECT_LOC));
+ project.move(description, IResource.FORCE, null);
+
+ project2 = root.getProject(TEST_PROJECT2);
+ project2.create(null);
+ project2.open(null);
+ gitDir2 = new File(project2.getLocation().toFile().getAbsoluteFile(), Constants.DOT_GIT);
+ repository2 = new FileRepository(gitDir2);
+ repository2.create();
+
+ RepositoryMapping mapping = new RepositoryMapping(project, gitDir);
+ RepositoryMapping mapping2 = new RepositoryMapping(project2, gitDir2);
+
+ GitProjectData projectData = new GitProjectData(project);
+ GitProjectData projectData2 = new GitProjectData(project2);
+ projectData.setRepositoryMappings(Collections.singletonList(mapping));
+ projectData.store();
+ projectData2.setRepositoryMappings(Collections.singletonList(mapping2));
+ projectData2.store();
+ GitProjectData.add(project, projectData);
+ GitProjectData.add(project2, projectData2);
+
+ RepositoryProvider.map(project, GitProvider.class.getName());
+ RepositoryProvider.map(project2, GitProvider.class.getName());
+
+ FileWriter fileWriter = new FileWriter(new File(repository.getWorkTree(), TEST_PROJECT+"/"+TEST_FILE));
+ fileWriter.write("Some data");
+ fileWriter.close();
+ FileWriter fileWriter2 = new FileWriter(new File(repository2.getWorkTree(), TEST_FILE2));
+ fileWriter2.write("Some other data");
+ fileWriter2.close();
+ project.refreshLocal(IResource.DEPTH_INFINITE, null);
+ project2.refreshLocal(IResource.DEPTH_INFINITE, null);
+ git = new Git(repository);
+ git.add().addFilepattern(".").call();
+ git.commit().setMessage("Initial commit").call();
+
+ git = new Git(repository2);
+ git.add().addFilepattern(".").call();
+ git.commit().setMessage("Initial commit").call();
+ git.branchRename().setNewName("main").call();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ Thread.sleep(1000); // FIXME: We need a good way to wait for things to settle
+
+ RepositoryProvider.unmap(project);
+ RepositoryProvider.unmap(project2);
+
+ GitProjectData.delete(project);
+ GitProjectData.delete(project2);
+
+ project.delete(true, true, null);
+ project2.delete(true, true, null);
+
+ repository.close();
+ repository2.close();
+
+ org.eclipse.egit.core.Activator.getDefault().getRepositoryCache().clear();
+
+ FileUtils.delete(gitDir, FileUtils.RECURSIVE);
+ // gitDir2 is inside project, already gone
+ }
+
+ @Test
+ public void testGitDir() throws CoreException {
+ assertVariable(gitDir.getPath(), "git_dir", null);
+ assertVariable(gitDir.getPath(), "git_dir", TEST_PROJECT);
+ assertVariable(gitDir2.getPath(), "git_dir", TEST_PROJECT2);
+ assertVariable(gitDir2.getPath(), "git_dir", TEST_PROJECT2 + "/" + TEST_FILE2);
+ }
+
+ @Test
+ public void testGitWorkTree() throws CoreException {
+ assertVariable(gitDir.getParentFile().getPath(), "git_work_tree", null);
+ assertVariable(gitDir.getParentFile().getPath(), "git_work_tree", TEST_PROJECT);
+ assertVariable(gitDir2.getParentFile().getPath(), "git_work_tree", TEST_PROJECT2);
+ }
+
+ @Test
+ public void testGitPath() throws CoreException {
+ assertVariable(TEST_PROJECT + File.separatorChar + TEST_FILE, "git_repo_relative_path", null);
+ assertVariable(TEST_FILE2, "git_repo_relative_path", TEST_PROJECT2 + "/" + TEST_FILE2);
+ }
+
+ @Test
+ public void testGitBranch() throws CoreException {
+ assertVariable("master", "git_branch", null);
+ assertVariable("master", "git_branch", TEST_PROJECT + "/" + TEST_FILE);
+ assertVariable("main", "git_branch", TEST_PROJECT2 + "/" + TEST_FILE2);
+ assertVariable("main", "git_branch", TEST_PROJECT2);
+ }
+
+ private void assertVariable(String expected, String variableName,
+ String argument) throws CoreException {
+ IResource findMember = project.findMember(TEST_FILE);
+
+ final ISelectionProvider selectionProvider = bot.viewByTitle("Package Explorer").getViewReference().getView(true).getSite().getSelectionProvider();
+ final StructuredSelection structuredSelection = new StructuredSelection(
+ findMember);
+ PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+
+ public void run() {
+ selectionProvider.setSelection(structuredSelection);
+ }
+ });
+
+ IDynamicVariable dynamicVariable = VariablesPlugin.getDefault()
+ .getStringVariableManager().getDynamicVariable(variableName);
+ String value = dynamicVariable.getValue(argument);
+ assertEquals(expected, value);
+ }
+}
diff --git a/org.eclipse.egit.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.ui/META-INF/MANIFEST.MF
index 9d2239be93..24629a6b64 100644
--- a/org.eclipse.egit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.ui/META-INF/MANIFEST.MF
@@ -10,6 +10,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
org.eclipse.core.filesystem;bundle-version="[1.1.0,2.0.0)",
org.eclipse.core.resources;bundle-version="[3.4.0,4.0.0)",
org.eclipse.core.net;bundle-version="[1.1.0,2.0.0)",
+ org.eclipse.core.variables;bundle-version="[3.2.400,4.0.0)",
org.eclipse.ui;bundle-version="[3.5.0,4.0.0)",
org.eclipse.team.core;bundle-version="[3.4.0,4.0.0)",
org.eclipse.team.ui;bundle-version="[3.4.0,4.0.0)",
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties
index ab81e0ff03..6dc6c0111d 100644
--- a/org.eclipse.egit.ui/plugin.properties
+++ b/org.eclipse.egit.ui/plugin.properties
@@ -305,3 +305,8 @@ NavigationActionSet.label = Git Navigation Actions
OpenCommitAction.tooltip = Open Git Commit
OpenCommitAction.label = Open Git Commit
ShowBlameAction_label = Show Blame Annotations
+
+GitVariable_git_dir=The path to the .git directory for the selected or named resource
+GitVariable_git_repo_relative_path=Path of the selected or named resource relative to the Git repository
+GitVariable__git_work_tree_description=Work tree root of the Git repository for the selected or referenced resource
+GitVariable_git_branch_description=Current HEAD in the Git repository that contains the selected ot referenced resource
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index 0e8aa348c5..d178de71b6 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -3726,4 +3726,31 @@
tooltip="%OpenCommitAction.tooltip"/>
</actionSet>
</extension>
+ <extension
+ point="org.eclipse.core.variables.dynamicVariables">
+ <variable
+ description="%GitVariable_git_dir"
+ name="git_dir"
+ resolver="org.eclipse.egit.ui.variables.GitVariableResolver"
+ supportsArgument="true">
+ </variable>
+ <variable
+ description="%GitVariable_git_repo_relative_path"
+ name="git_repo_relative_path"
+ resolver="org.eclipse.egit.ui.variables.GitVariableResolver"
+ supportsArgument="true">
+ </variable>
+ <variable
+ description="%GitVariable__git_work_tree_description"
+ name="git_work_tree"
+ resolver="org.eclipse.egit.ui.variables.GitVariableResolver"
+ supportsArgument="true">
+ </variable>
+ <variable
+ description="%GitVariable_git_branch_description"
+ name="git_branch"
+ resolver="org.eclipse.egit.ui.variables.GitVariableResolver"
+ supportsArgument="true">
+ </variable>
+ </extension>
</plugin>
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
index 34e1ccf9fe..9c0d19d211 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
@@ -3740,6 +3740,15 @@ public class UIText extends NLS {
public static String GitActionContributor_Pull;
/** */
+ public static String GitVariableResolver_InternalError;
+
+ /** */
+ public static String GitVariableResolver_NoSelectedResource;
+
+ /** */
+ public static String GitVariableResolver_VariableReferencesNonExistentResource;
+
+ /** */
public static String DecoratableResourceHelper_noHead;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
index 8f3afc4227..aad6db9505 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
@@ -1294,6 +1294,9 @@ SwitchToMenu_OtherMenuLabel=&Other...
GitActionContributor_ExpandAll=Expand All
GitActionContributor_Push=Push
GitActionContributor_Pull=Pull
+GitVariableResolver_InternalError=Internal error
+GitVariableResolver_NoSelectedResource=No selected resource
+GitVariableResolver_VariableReferencesNonExistentResource=Variable references non-existent resource : {0}
OpenWorkingFileAction_text=&Open
OpenWorkingFileAction_tooltip=Open working file
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/variables/GitVariableResolver.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/variables/GitVariableResolver.java
new file mode 100644
index 0000000000..1e4bcfbf69
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/variables/GitVariableResolver.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Robin Rosenberg
+ * 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
+ *******************************************************************************/
+package org.eclipse.egit.ui.variables;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.variables.IDynamicVariable;
+import org.eclipse.core.variables.IDynamicVariableResolver;
+import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.UIText;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Resolves Git related information so launchers can use them
+ */
+public class GitVariableResolver implements IDynamicVariableResolver {
+
+ private static final String GIT_REPO_RELATIVE_PATH = "git_repo_relative_path"; //$NON-NLS-1$
+ private static final String GIT_DIR = "git_dir"; //$NON-NLS-1$
+ private static final String GIT_WORK_TREE = "git_work_tree"; //$NON-NLS-1$
+ private static final String GIT_BRANCH = "git_branch"; //$NON-NLS-1$
+
+ public String resolveValue(IDynamicVariable variable, String argument)
+ throws CoreException {
+ if (variable.getName().equals(GIT_DIR))
+ return getGitDir(argument);
+ if (variable.getName().equals(GIT_REPO_RELATIVE_PATH))
+ return getGitRepoRelativePath(argument);
+ if (variable.getName().equals(GIT_WORK_TREE))
+ return getGitWorkTree(argument);
+ if (variable.getName().equals(GIT_BRANCH))
+ return getGitBranch(argument);
+ throw new CoreException(new Status(IStatus.ERROR, Activator
+ .getPluginId(), UIText.GitVariableResolver_InternalError));
+ }
+
+ private String getGitRepoRelativePath(String argument) throws CoreException {
+ IResource res = getResource(argument);
+ if (res == null)
+ return ""; //$NON-NLS-1$
+ RepositoryMapping mapping = RepositoryMapping.getMapping(res);
+ if (mapping != null) {
+ String repoRelativePath = mapping.getRepoRelativePath(res);
+ if (repoRelativePath.equals("")) //$NON-NLS-1$
+ return "."; //$NON-NLS-1$
+ else
+ return repoRelativePath;
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ private String getGitDir(String argument) throws CoreException {
+ IResource res = getResource(argument);
+ if (res == null)
+ return ""; //$NON-NLS-1$
+ RepositoryMapping mapping = RepositoryMapping.getMapping(res);
+ if (mapping != null)
+ return mapping.getRepository().getDirectory().getAbsolutePath();
+ else
+ return ""; //$NON-NLS-1$
+ }
+
+ private String getGitWorkTree(String argument) throws CoreException {
+ IResource res = getResource(argument);
+ if (res == null)
+ return ""; //$NON-NLS-1$
+ RepositoryMapping mapping = RepositoryMapping.getMapping(res);
+ if (mapping != null)
+ return mapping.getWorkTree().getAbsolutePath();
+ else
+ return ""; //$NON-NLS-1$
+ }
+
+ private String getGitBranch(String argument) throws CoreException {
+ IResource res = getResource(argument);
+ if (res == null)
+ return ""; //$NON-NLS-1$
+ RepositoryMapping mapping = RepositoryMapping.getMapping(res);
+ if (mapping != null)
+ try {
+ return mapping.getRepository().getBranch();
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.getPluginId(), e.getMessage()));
+ }
+ else
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the currently selected or specified resource
+ * @param argument named resource or null for selected
+ *
+ * @return the currently selected <code>IResource</code>, or <code>null</code> if none.
+ * @throws CoreException
+ */
+ private IResource getResource(String argument) throws CoreException {
+ IResource res;
+ if (argument == null) {
+ res = getResource();
+ if (res == null)
+ throw new CoreException(new Status(IStatus.ERROR, Activator
+ .getPluginId(), UIText.GitVariableResolver_NoSelectedResource));
+ } else {
+ res = ResourcesPlugin.getWorkspace().getRoot().findMember(argument);
+ if (res == null || !res.exists()) {
+ throw new CoreException(
+ new Status(
+ IStatus.ERROR,
+ Activator.getPluginId(),
+ NLS.bind(
+ UIText.GitVariableResolver_VariableReferencesNonExistentResource,
+ argument)));
+ }
+ }
+ return res;
+ }
+
+ private IResource getResource() {
+ Display display = PlatformUI.getWorkbench().getDisplay();
+ if(display.getThread().equals(Thread.currentThread()))
+ return getSelectedResource();
+ else {
+ final IResource[] resource = new IResource[1];
+ display.syncExec(new Runnable() {
+ public void run() {
+ resource[0] = getSelectedResource();
+ }
+ });
+ return resource[0];
+ }
+ }
+
+ private IResource getSelectedResource() {
+ IResource resource = null;
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow window = null;
+ if (workbench != null)
+ window = workbench.getActiveWorkbenchWindow();
+ if(window != null) {
+ IWorkbenchPage page = window.getActivePage();
+ if(page != null) {
+ IWorkbenchPart part = page.getActivePart();
+ if(part instanceof IEditorPart) {
+ IEditorPart epart = (IEditorPart) part;
+ resource = (IResource) epart.getEditorInput().getAdapter(IResource.class);
+ }
+ else if(part != null) {
+ IWorkbenchPartSite site = part.getSite();
+ if(site != null) {
+ ISelectionProvider provider = site.getSelectionProvider();
+ if(provider != null) {
+ ISelection selection = provider.getSelection();
+ if(selection instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection) selection;
+ if(!ss.isEmpty()) {
+ Iterator iterator = ss.iterator();
+ while (iterator.hasNext() && resource == null) {
+ Object next = iterator.next();
+ resource = (IResource) Platform.getAdapterManager().getAdapter(next, IResource.class);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return resource;
+ }
+}

Back to the top