diff options
author | Robin Rosenberg | 2011-06-17 06:32:09 +0000 |
---|---|---|
committer | Matthias Sohn | 2011-06-17 06:32:09 +0000 |
commit | 9ddb5f1e04cb23ab18e52db08c015d9926df3ca1 (patch) | |
tree | 2ffd2e36a22fdba0b9b737119ec0476ddf4598c2 | |
parent | 719370df91eb06538fdd34e46fa795487b018162 (diff) | |
download | egit-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>
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; + } +} |