diff options
author | Kevin Sawicki | 2011-04-22 18:30:17 -0400 |
---|---|---|
committer | Chris Aniszczyk | 2011-05-05 20:17:09 -0400 |
commit | 99dd356b60813ad490441e416e448f8e74694a91 (patch) | |
tree | b29539828e18f0bba562edc124a9352ce2a0d845 | |
parent | 513669caf8449908e845159eb8623177da0aec4f (diff) | |
download | egit-github-99dd356b60813ad490441e416e448f8e74694a91.zip egit-github-99dd356b60813ad490441e416e448f8e74694a91.tar.gz egit-github-99dd356b60813ad490441e416e448f8e74694a91.tar.xz |
Add clone gist handler
This handler clones a gist locally, adds it as
a registered gist repository and creates a project
with the files in the gist.
Change-Id: I8b2a81a40258bf443593470940d8e672de7907f8
Signed-off-by: Kevin Sawicki <kevin@github.com>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
-rw-r--r-- | org.eclipse.mylyn.github.ui/plugin.xml | 9 | ||||
-rw-r--r-- | org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/internal/github/ui/gist/CloneGistHandler.java | 232 |
2 files changed, 241 insertions, 0 deletions
diff --git a/org.eclipse.mylyn.github.ui/plugin.xml b/org.eclipse.mylyn.github.ui/plugin.xml index f381c0b..33c1376 100644 --- a/org.eclipse.mylyn.github.ui/plugin.xml +++ b/org.eclipse.mylyn.github.ui/plugin.xml @@ -34,6 +34,11 @@ id="org.eclipse.mylyn.github.ui.command.createGist"
name="Create Gist">
</command>
+ <command
+ description="Clone Gist into Git repository"
+ id="org.eclipse.mylyn.github.ui.command.cloneGist"
+ name="Clone Gist">
+ </command>
</extension>
<extension
point="org.eclipse.ui.menus">
@@ -76,6 +81,10 @@ class="org.eclipse.mylyn.github.ui.internal.CreateGistHandler"
commandId="org.eclipse.mylyn.github.ui.command.createGist">
</handler>
+ <handler
+ class="org.eclipse.mylyn.internal.github.ui.gist.CloneGistHandler"
+ commandId="org.eclipse.mylyn.github.ui.command.cloneGist">
+ </handler>
</extension>
<extension
point="org.eclipse.mylyn.tasks.ui.repositories">
diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/internal/github/ui/gist/CloneGistHandler.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/internal/github/ui/gist/CloneGistHandler.java new file mode 100644 index 0000000..e1e508e --- /dev/null +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/internal/github/ui/gist/CloneGistHandler.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (c) 2011 GitHub Inc. + * 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: + * Kevin Sawicki (GitHub Inc.) - initial API and implementation + *******************************************************************************/ +package org.eclipse.mylyn.internal.github.ui.gist; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.text.MessageFormat; + +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.IProjectDescription; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.egit.core.RepositoryUtil; +import org.eclipse.egit.core.op.CloneOperation; +import org.eclipse.egit.core.op.CloneOperation.PostCloneTask; +import org.eclipse.egit.core.op.ConnectProviderOperation; +import org.eclipse.egit.ui.Activator; +import org.eclipse.egit.ui.UIPreferences; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.mylyn.commons.net.AuthenticationCredentials; +import org.eclipse.mylyn.commons.net.AuthenticationType; +import org.eclipse.mylyn.internal.github.core.gist.GistAttribute; +import org.eclipse.mylyn.internal.github.core.gist.GistConnector; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.core.data.TaskData; +import org.eclipse.mylyn.tasks.ui.TasksUi; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.progress.IWorkbenchSiteProgressService; + +/** + * Clone Gist handler class. + * + * @author Kevin Sawicki (kevin@github.com) + */ +public class CloneGistHandler extends AbstractHandler { + + /** + * ID + */ + public static final String ID = "org.eclipse.mylyn.github.ui.command.cloneGist"; //$NON-NLS-1$ + + private File getParentDirectory() { + String destinationDir = Activator.getDefault().getPreferenceStore() + .getString(UIPreferences.DEFAULT_REPO_DIR); + File parentDir = new File(destinationDir); + if (!parentDir.exists() || !parentDir.isDirectory()) + parentDir = ResourcesPlugin.getWorkspace().getRoot() + .getRawLocation().toFile(); + return parentDir; + } + + private void createProject(final File workDir, final String name, + final Repository repository, IProgressMonitor monitor) + throws CoreException { + IProjectDescription description = null; + String projectName = null; + File projectFile = new File(workDir, ".project"); //$NON-NLS-1$ + if (projectFile.exists()) { + description = ResourcesPlugin.getWorkspace() + .loadProjectDescription( + Path.fromOSString(projectFile.getAbsolutePath())); + projectName = description.getName(); + } else { + description = ResourcesPlugin.getWorkspace().newProjectDescription( + name); + description + .setLocation(Path.fromOSString(workDir.getAbsolutePath())); + projectName = name; + } + + monitor.setTaskName(Messages.CloneGistHandler_TaskCreatingProject); + IProject project = ResourcesPlugin.getWorkspace().getRoot() + .getProject(projectName); + project.create(description, monitor); + project.open(IResource.BACKGROUND_REFRESH, monitor); + + monitor.setTaskName(Messages.CloneGistHandler_TaskConnectingProject); + ConnectProviderOperation cpo = new ConnectProviderOperation(project, + repository.getDirectory()); + cpo.execute(monitor); + } + + private CloneOperation createCloneOperation(TaskData data, String name) + throws IOException, URISyntaxException { + String pullUrl = data.getRoot() + .getAttribute(GistAttribute.CLONE_URL.getId()).getValue(); + URIish uri = new URIish(pullUrl); + int timeout = Activator.getDefault().getPreferenceStore() + .getInt(UIPreferences.REMOTE_CONNECTION_TIMEOUT); + final File workDir = new File(getParentDirectory(), name); + + if (getRepoUtil().getConfiguredRepositories().contains( + new File(workDir, Constants.DOT_GIT).getAbsolutePath())) + throw new IOException(MessageFormat.format( + Messages.CloneGistHandler_ErrorRepoExists, name)); + + return new CloneOperation(uri, true, null, workDir, Constants.R_HEADS + + Constants.MASTER, Constants.DEFAULT_REMOTE_NAME, timeout); + } + + private void updateCredentials(TaskData data, CloneOperation operation) { + TaskRepository repository = TasksUi.getRepositoryManager() + .getRepository(GistConnector.KIND, data.getRepositoryUrl()); + AuthenticationCredentials credentials = repository + .getCredentials(AuthenticationType.REPOSITORY); + if (credentials != null) { + UsernamePasswordCredentialsProvider provider = new UsernamePasswordCredentialsProvider( + credentials.getUserName(), credentials.getPassword() + .toCharArray()); + operation.setCredentialsProvider(provider); + } + } + + private RepositoryUtil getRepoUtil() { + return org.eclipse.egit.core.Activator.getDefault().getRepositoryUtil(); + } + + private Job createCloneJob(final ExecutionEvent event, final TaskData data) { + Job job = new Job(Messages.CloneGistHandler_TaskCloning) { + + protected IStatus run(IProgressMonitor monitor) { + try { + final String name = "gist-" + data.getTaskId(); //$NON-NLS-1$ + + CloneOperation operation = createCloneOperation(data, name); + updateCredentials(data, operation); + + operation.addPostCloneTask(new PostCloneTask() { + + public void execute(Repository repository, + IProgressMonitor monitor) throws CoreException { + if (monitor.isCanceled()) + return; + monitor.setTaskName(Messages.CloneGistHandler_TaskRegisteringRepository); + getRepoUtil().addConfiguredRepository( + repository.getDirectory()); + } + }); + + operation.addPostCloneTask(new PostCloneTask() { + + public void execute(final Repository repository, + IProgressMonitor monitor) throws CoreException { + IWorkspaceRunnable runnable = new IWorkspaceRunnable() { + + public void run(IProgressMonitor monitor) + throws CoreException { + if (monitor.isCanceled()) + return; + createProject(repository.getDirectory() + .getParentFile(), name, repository, + monitor); + } + }; + ResourcesPlugin.getWorkspace().run(runnable, + monitor); + } + }); + + operation.run(monitor); + } catch (Exception e) { + displayError(event, e); + Activator.logError("Error cloning gist", e); //$NON-NLS-1$ + } + return Status.OK_STATUS; + } + }; + return job; + } + + private void displayError(final ExecutionEvent event, Exception exception) { + final Throwable cause = exception.getCause() != null ? exception + .getCause() : exception; + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + + public void run() { + ErrorDialog.openError(HandlerUtil.getActiveShell(event), + Messages.CloneGistHandler_ErrorTitle, + Messages.CloneGistHandler_ErrorMessage, Activator + .createErrorStatus(cause.getLocalizedMessage(), + cause)); + } + }); + } + + /** + * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent) + */ + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchSite activeSite = HandlerUtil.getActiveSite(event); + IWorkbenchSiteProgressService service = (IWorkbenchSiteProgressService) activeSite + .getService(IWorkbenchSiteProgressService.class); + + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (selection == null || selection.isEmpty()) + selection = HandlerUtil.getActiveMenuSelection(event); + + if (selection instanceof IStructuredSelection && !selection.isEmpty()) { + Object first = ((IStructuredSelection) selection).getFirstElement(); + if (first instanceof TaskData) + service.schedule(createCloneJob(event, (TaskData) first)); + } + return null; + } +} |