diff options
author | Kevin Sawicki | 2011-08-01 22:01:59 +0000 |
---|---|---|
committer | Kevin Sawicki | 2011-08-01 22:01:59 +0000 |
commit | 6c43a4d617667cf9c0e1ec2fa4b908e5814c6542 (patch) | |
tree | 5fc6b5b531908b26a643a16786c09b8d32335fac /org.eclipse.mylyn.github.core/src/org/eclipse | |
parent | 433497079eb3ee28c15ab23b3e4d2e9e8ae12bc5 (diff) | |
download | egit-github-6c43a4d617667cf9c0e1ec2fa4b908e5814c6542.tar.gz egit-github-6c43a4d617667cf9c0e1ec2fa4b908e5814c6542.tar.xz egit-github-6c43a4d617667cf9c0e1ec2fa4b908e5814c6542.zip |
Add task repository for pull requests.
Initially supports:
* Editing summary & description
* Browsing & adding comments
* Browsing & opening associated commits
* Closing & re-opening the pull request
* Checking out the pull request's commits into a topic branch
* Fetching pull request commits
* Generating a context with the files modified in the pull request
Change-Id: Iba75e999353dbc5d095dc95dd2977e9f21d694e6
Signed-off-by: Kevin Sawicki <kevin@github.com>
Diffstat (limited to 'org.eclipse.mylyn.github.core/src/org/eclipse')
17 files changed, 1048 insertions, 68 deletions
diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/GitHub.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/GitHub.java index a98bbca2..5867f795 100644 --- a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/GitHub.java +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/GitHub.java @@ -32,25 +32,28 @@ import org.eclipse.mylyn.tasks.core.TaskRepository; public class GitHub { /** BUNDLE_ID */ - public static final String BUNDLE_ID = "org.eclipse.mylyn.github.core"; + public static final String BUNDLE_ID = "org.eclipse.mylyn.github.core"; //$NON-NLS-1$ /** CONNECTOR_KIND */ - public static final String CONNECTOR_KIND = "github"; + public static final String CONNECTOR_KIND = "github"; //$NON-NLS-1$ /** HTTP_WWW_GITHUB_ORG */ - public static final String HTTP_WWW_GITHUB_ORG = "http://www.github.org"; + public static final String HTTP_WWW_GITHUB_ORG = "http://www.github.org"; //$NON-NLS-1$ /** HTTP_GITHUB_COM */ - public static final String HTTP_GITHUB_COM = "http://github.com"; + public static final String HTTP_GITHUB_COM = "http://github.com"; //$NON-NLS-1$ /** URL_PATTERN */ - public static final Pattern URL_PATTERN = Pattern.compile("(?:" - + Pattern.quote(HTTP_WWW_GITHUB_ORG) + "|" - + Pattern.quote(HTTP_GITHUB_COM) + ")/([^/]+)/([^/]+)"); + public static final Pattern URL_PATTERN = Pattern.compile("(?:" //$NON-NLS-1$ + + Pattern.quote(HTTP_WWW_GITHUB_ORG) + "|" //$NON-NLS-1$ + + Pattern.quote(HTTP_GITHUB_COM) + ")/([^/]+)/([^/]+)"); //$NON-NLS-1$ /** USER_AGENT */ public static final String USER_AGENT = "GitHubEclipse/1.1.0"; //$NON-NLS-1$ + /** REPOSITORY_SEGMENTS */ + public static final String REPOSITORY_SEGMENTS = "/user/repository"; //$NON-NLS-1$ + /** * Configure client with standard configuration * @@ -130,7 +133,7 @@ public class GitHub { */ public static IStatus createErrorStatus(Throwable e) { return createStatus(IStatus.ERROR, - "Unexpected error: " + e.getLocalizedMessage(), e); + "Unexpected error: " + e.getLocalizedMessage(), e); //$NON-NLS-1$ } /** diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/GitHubException.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/GitHubException.java index da31e61c..c6bde874 100644 --- a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/GitHubException.java +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/GitHubException.java @@ -53,7 +53,7 @@ public class GitHubException extends IOException { RequestError error = ((RequestException) getCause()).getError(); String errorMessage = error.getMessage(); if (errorMessage == null) - errorMessage = ""; + errorMessage = ""; //$NON-NLS-1$ StringBuilder message = new StringBuilder(errorMessage); List<FieldError> errors = error.getErrors(); if (errors != null && errors.size() > 0) { diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/gist/messages.properties b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/gist/messages.properties index aa9f10a5..e416f05b 100644 --- a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/gist/messages.properties +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/gist/messages.properties @@ -9,7 +9,7 @@ GistAttribute_LabelModified=Modified: GistAttribute_LabelNewComment=New Comment GistAttribute_LabelSummary=Summary GistAttribute_LabelUrl=Url -GistConnector_LabelConnector=Github Gists +GistConnector_LabelConnector=GitHub Gists GistTaskDataHandler_FilesMultiple={0} files GistTaskDataHandler_FilesSingle=1 file GistTaskDataHandler_SizeByte=1 byte diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueAttribute.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueAttribute.java index 58604166..2af15afd 100644 --- a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueAttribute.java +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueAttribute.java @@ -109,21 +109,7 @@ public enum IssueAttribute { */ REPORTER_GRAVATAR(Messages.IssueAttribute_LabelReporterGravatar, "github.issue.reporter.gravatar", TaskAttribute.TYPE_URL, null, //$NON-NLS-1$ - true, false), - - /** - * URL to diff if issue is a pull request - */ - PULL_REQUEST_DIFF(Messages.IssueAttribute_LabelPullRequestDiffUrl, - "github.issue.pull.diff", //$NON-NLS-2$ //$NON-NLS-1$ - TaskAttribute.TYPE_URL, null, true, false), - - /** - * Body of pull request if issue is a pull request - */ - PULL_REQUEST_BODY(Messages.IssueAttribute_LabelPullRequestBody, - "github.issue.pull.body", //$NON-NLS-2$ - TaskAttribute.TYPE_LONG_TEXT, null, true, false); + true, false); private final GitHubAttributeMetadata metadata; diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueConnector.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueConnector.java index 427f29d6..399ebf1a 100644 --- a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueConnector.java +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueConnector.java @@ -13,7 +13,6 @@ package org.eclipse.mylyn.internal.github.core.issue; import java.io.IOException; -import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; @@ -28,26 +27,30 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.egit.github.core.Comment; +import org.eclipse.egit.github.core.IRepositoryIdProvider; import org.eclipse.egit.github.core.Issue; import org.eclipse.egit.github.core.Label; import org.eclipse.egit.github.core.Milestone; +import org.eclipse.egit.github.core.PullRequest; +import org.eclipse.egit.github.core.Repository; import org.eclipse.egit.github.core.RepositoryId; import org.eclipse.egit.github.core.client.GitHubClient; -import org.eclipse.egit.github.core.client.IGitHubConstants; import org.eclipse.egit.github.core.service.IssueService; import org.eclipse.egit.github.core.service.LabelService; import org.eclipse.egit.github.core.service.MilestoneService; import org.eclipse.egit.github.core.util.LabelComparator; import org.eclipse.egit.github.core.util.MilestoneComparator; +import org.eclipse.mylyn.commons.net.AuthenticationCredentials; +import org.eclipse.mylyn.commons.net.AuthenticationType; import org.eclipse.mylyn.commons.net.Policy; import org.eclipse.mylyn.internal.github.core.GitHub; import org.eclipse.mylyn.internal.github.core.QueryUtils; import org.eclipse.mylyn.internal.github.core.RepositoryConnector; +import org.eclipse.mylyn.internal.github.core.pr.PullRequestConnector; +import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants; import org.eclipse.mylyn.tasks.core.IRepositoryQuery; -import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler; -import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.mylyn.tasks.core.data.TaskData; import org.eclipse.mylyn.tasks.core.data.TaskDataCollector; import org.eclipse.mylyn.tasks.core.sync.ISynchronizationSession; @@ -63,20 +66,48 @@ public class IssueConnector extends RepositoryConnector { public static final String KIND = GitHub.CONNECTOR_KIND; /** + * Get repository label for id provider + * + * @param repo + * @return label + */ + public static String getRepositoryLabel(IRepositoryIdProvider repo) { + return repo.generateId() + Messages.IssueConnector_LabelIssues; + } + + /** + * Create issue task repository + * + * @param repo + * @param username + * @param password + * @return task repository + */ + public static TaskRepository createTaskRepository(Repository repo, + String username, String password) { + String url = GitHub.createGitHubUrl(repo.getOwner().getLogin(), + repo.getName()); + TaskRepository repository = new TaskRepository( + PullRequestConnector.KIND, url); + repository.setProperty(IRepositoryConstants.PROPERTY_LABEL, + getRepositoryLabel(repo)); + if (username != null && password != null) + repository.setCredentials(AuthenticationType.REPOSITORY, + new AuthenticationCredentials(username, password), true); + repository.setProperty(IRepositoryConstants.PROPERTY_CATEGORY, + IRepositoryConstants.CATEGORY_BUGS); + return repository; + } + + /** * Create client for repository * * @param repository * @return client */ public static GitHubClient createClient(TaskRepository repository) { - GitHubClient client; - try { - String host = new URL(repository.getRepositoryUrl()).getHost(); - host = IGitHubConstants.SUBDOMAIN_API + "." + host; - client = new GitHubClient(host, -1, IGitHubConstants.PROTOCOL_HTTPS); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } + GitHubClient client = GitHubClient.createClient(repository + .getRepositoryUrl()); GitHub.addCredentials(client, repository); return GitHub.configureClient(client); } @@ -295,7 +326,7 @@ public class IssueConnector extends RepositoryConnector { // collect task data for (Issue issue : issues) { - if (issue.getPullRequest() == null) + if (isPullRequest(issue)) continue; List<Comment> comments = null; if (issue.getComments() > 0) @@ -315,6 +346,11 @@ public class IssueConnector extends RepositoryConnector { return result; } + private boolean isPullRequest(Issue issue) { + PullRequest request = issue.getPullRequest(); + return request != null && request.getDiffUrl() != null; + } + @Override public TaskData getTaskData(TaskRepository repository, String taskId, IProgressMonitor monitor) throws CoreException { @@ -325,6 +361,8 @@ public class IssueConnector extends RepositoryConnector { IssueService service = new IssueService(client); Issue issue = service.getIssue(repo.getOwner(), repo.getName(), taskId); + if (isPullRequest(issue)) + return null; List<Comment> comments = null; if (issue.getComments() > 0) comments = service.getComments(repo.getOwner(), repo.getName(), @@ -375,22 +413,4 @@ public class IssueConnector extends RepositoryConnector { refreshMilestones(taskRepository); monitor.done(); } - - @Override - public void updateTaskFromTaskData(TaskRepository taskRepository, - ITask task, TaskData taskData) { - if (!taskData.isNew()) { - String diffUrl = null; - TaskAttribute prDiff = taskData.getRoot().getAttribute( - IssueAttribute.PULL_REQUEST_DIFF.getMetadata().getId()); - if (prDiff != null) { - diffUrl = taskData.getAttributeMapper().getValue(prDiff); - if (diffUrl.length() == 0) - diffUrl = null; - } - task.setAttribute(IssueAttribute.PULL_REQUEST_DIFF.getMetadata() - .getId(), diffUrl); - } - super.updateTaskFromTaskData(taskRepository, task, taskData); - } } diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueOperation.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueOperation.java index f8263859..647b8fe7 100644 --- a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueOperation.java +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueOperation.java @@ -20,17 +20,17 @@ public enum IssueOperation { /** * LEAD */ - LEAVE("Leave "), + LEAVE("Leave "), //$NON-NLS-1$ /** * REOPEN */ - REOPEN("Reopen"), + REOPEN("Reopen"), //$NON-NLS-1$ /** * CLOSE */ - CLOSE("Close"); + CLOSE("Close"); //$NON-NLS-1$ private final String label; diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueTaskDataHandler.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueTaskDataHandler.java index f1bf04e4..a9060f8d 100644 --- a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueTaskDataHandler.java +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/IssueTaskDataHandler.java @@ -24,7 +24,6 @@ import org.eclipse.egit.github.core.Comment; import org.eclipse.egit.github.core.Issue; import org.eclipse.egit.github.core.Label; import org.eclipse.egit.github.core.Milestone; -import org.eclipse.egit.github.core.PullRequest; import org.eclipse.egit.github.core.RepositoryId; import org.eclipse.egit.github.core.User; import org.eclipse.egit.github.core.client.GitHubClient; @@ -113,14 +112,6 @@ public class IssueTaskDataHandler extends GitHubTaskDataHandler { createMilestones(repository, data, issue); - PullRequest pr = issue.getPullRequest(); - String prDiffUrl = pr != null ? pr.getDiffUrl() : null; - createAttribute(data, IssueAttribute.PULL_REQUEST_DIFF.getMetadata(), - prDiffUrl); - if (prDiffUrl != null) - createAttribute(data, - IssueAttribute.PULL_REQUEST_BODY.getMetadata(), ""); //$NON-NLS-1$ - return data; } diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/Messages.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/Messages.java index 7ac7f551..dd57e377 100644 --- a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/Messages.java +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/Messages.java @@ -23,6 +23,9 @@ public class Messages extends NLS { public static String IssueConnector_LabelConnector; /** */ + public static String IssueConnector_LabelIssues; + + /** */ public static String IssueConector_TaskQuerying; /** */ diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/messages.properties b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/messages.properties index 350f6a86..ba0d170f 100644 --- a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/messages.properties +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/issue/messages.properties @@ -1,4 +1,5 @@ IssueConnector_LabelConnector=GitHub Issues +IssueConnector_LabelIssues=\ issues IssueConector_TaskQuerying=Querying repository... IssueConnector_TaskUpdatingLabels=Updating labels IssueConnector_TaskUpdatingMilestones=Updating milestones diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/Messages.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/Messages.java new file mode 100644 index 00000000..5ba25b68 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/Messages.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * 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.core.pr; + +import org.eclipse.osgi.util.NLS; + +/** + * NLS for Mylyn GitHub Core + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.mylyn.internal.github.core.pr.messages"; //$NON-NLS-1$ + + /** */ + public static String PullRequestAttribute_LabelClosedAt; + + /** */ + public static String PullRequestAttribute_LabelComment; + + /** */ + public static String PullRequestAttribute_LabelCreatedAt; + + /** */ + public static String PullRequestAttribute_LabelDescription; + + /** */ + public static String PullRequestAttribute_LabelKey; + + /** */ + public static String PullRequestAttribute_LabelMergedAt; + + /** */ + public static String PullRequestAttribute_LabelModel; + + /** */ + public static String PullRequestAttribute_LabelModifiedAt; + + /** */ + public static String PullRequestAttribute_LabelReporter; + + /** */ + public static String PullRequestAttribute_LabelStatus; + + /** */ + public static String PullRequestAttribute_LabelSummary; + + /** */ + public static String PullRequestConnector_Label; + + /** */ + public static String PullRequestConnector_LabelPullRequests; + + /** */ + public static String PullRequestConnector_TaskFetching; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestAttribute.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestAttribute.java new file mode 100644 index 00000000..1c12251d --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestAttribute.java @@ -0,0 +1,121 @@ +/****************************************************************************** + * 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.core.pr; + +import org.eclipse.mylyn.internal.github.core.GitHubAttributeMetadata; +import org.eclipse.mylyn.tasks.core.data.TaskAttribute; + +/** + * GitHub pull request attributes + */ +public enum PullRequestAttribute { + + /** + * Pull request key + */ + KEY(Messages.PullRequestAttribute_LabelKey, TaskAttribute.TASK_KEY, + TaskAttribute.TYPE_SHORT_TEXT, true, true), + + /** + * Pull request title + */ + TITLE(Messages.PullRequestAttribute_LabelSummary, TaskAttribute.SUMMARY, + TaskAttribute.TYPE_SHORT_RICH_TEXT, false, true), + + /** + * Pull request description + */ + BODY(Messages.PullRequestAttribute_LabelDescription, + TaskAttribute.DESCRIPTION, TaskAttribute.TYPE_LONG_RICH_TEXT, + false, true), + + /** + * Pull request creation date + */ + CREATION_DATE(Messages.PullRequestAttribute_LabelCreatedAt, + TaskAttribute.DATE_CREATION, TaskAttribute.TYPE_DATETIME, true, + false), + + /** + * Pull request modification date + */ + MODIFICATION_DATE(Messages.PullRequestAttribute_LabelModifiedAt, + TaskAttribute.DATE_MODIFICATION, TaskAttribute.TYPE_DATETIME, true, + false), + + /** + * Pull request closed date + */ + CLOSED_DATE(Messages.PullRequestAttribute_LabelClosedAt, + TaskAttribute.DATE_COMPLETION, TaskAttribute.TYPE_DATETIME, true, + false), + + /** + * Pull request merged date + */ + MERGED_DATE(Messages.PullRequestAttribute_LabelMergedAt, + "github.pr.merged.at", TaskAttribute.TYPE_DATETIME, true, false), //$NON-NLS-1$ + + /** + * Pull request status + */ + STATUS(Messages.PullRequestAttribute_LabelStatus, TaskAttribute.STATUS, + TaskAttribute.TYPE_SHORT_TEXT, false, true), + + /** + * Pull request reporter + */ + REPORTER(Messages.PullRequestAttribute_LabelReporter, + TaskAttribute.USER_REPORTER, TaskAttribute.TYPE_PERSON, true, false), + + /** + * Comment being added to pull request + */ + COMMENT_NEW(Messages.PullRequestAttribute_LabelComment, + TaskAttribute.COMMENT_NEW, TaskAttribute.TYPE_LONG_RICH_TEXT, + false, false), + + /** + * Pull request reporter gravatar + */ + REPORTER_GRAVATAR(Messages.PullRequestAttribute_LabelReporter, + "github.pr.reporter.gravatar", TaskAttribute.TYPE_URL, null, true, //$NON-NLS-1$ + false), + + /** + * Full pull request model stored as JSON + */ + MODEL(Messages.PullRequestAttribute_LabelModel, "github.pr.model", //$NON-NLS-1$ + TaskAttribute.TYPE_LONG_TEXT, null, true, false); + + private final GitHubAttributeMetadata metadata; + + private PullRequestAttribute(String label, String id, String type, + boolean readOnly, boolean initTask) { + metadata = new GitHubAttributeMetadata(id, label, type, readOnly, + initTask); + } + + private PullRequestAttribute(String label, String id, String type, + String kind, boolean readOnly, boolean initTask) { + metadata = new GitHubAttributeMetadata(id, label, kind, type, readOnly, + initTask); + } + + /** + * Get attribute metadata + * + * @return metadata + */ + public GitHubAttributeMetadata getMetadata() { + return metadata; + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestComposite.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestComposite.java new file mode 100644 index 00000000..c7b47ea5 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestComposite.java @@ -0,0 +1,58 @@ +/****************************************************************************** + * 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.core.pr; + +import java.util.List; + +import org.eclipse.egit.github.core.PullRequest; +import org.eclipse.egit.github.core.PullRequestCommit; + +/** + * Pull request composite that includes commits + */ +public class PullRequestComposite { + + private PullRequest request; + + private List<PullRequestCommit> commits; + + /** + * @return request + */ + public PullRequest getRequest() { + return request; + } + + /** + * @param request + * @return this pull request composite + */ + public PullRequestComposite setRequest(PullRequest request) { + this.request = request; + return this; + } + + /** + * @return commits + */ + public List<PullRequestCommit> getCommits() { + return commits; + } + + /** + * @param commits + * @return this pull request composite + */ + public PullRequestComposite setCommits(List<PullRequestCommit> commits) { + this.commits = commits; + return this; + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestConnector.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestConnector.java new file mode 100644 index 00000000..14355cb2 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestConnector.java @@ -0,0 +1,265 @@ +/****************************************************************************** + * 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.core.pr; + +import java.io.IOException; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.egit.github.core.Comment; +import org.eclipse.egit.github.core.IRepositoryIdProvider; +import org.eclipse.egit.github.core.PullRequest; +import org.eclipse.egit.github.core.Repository; +import org.eclipse.egit.github.core.RepositoryId; +import org.eclipse.egit.github.core.client.GitHubClient; +import org.eclipse.egit.github.core.client.GsonUtils; +import org.eclipse.egit.github.core.client.IGitHubConstants; +import org.eclipse.egit.github.core.service.IssueService; +import org.eclipse.egit.github.core.service.PullRequestService; +import org.eclipse.mylyn.commons.net.AuthenticationCredentials; +import org.eclipse.mylyn.commons.net.AuthenticationType; +import org.eclipse.mylyn.internal.github.core.GitHub; +import org.eclipse.mylyn.internal.github.core.QueryUtils; +import org.eclipse.mylyn.internal.github.core.RepositoryConnector; +import org.eclipse.mylyn.internal.github.core.issue.IssueConnector; +import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants; +import org.eclipse.mylyn.tasks.core.IRepositoryQuery; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler; +import org.eclipse.mylyn.tasks.core.data.TaskData; +import org.eclipse.mylyn.tasks.core.data.TaskDataCollector; +import org.eclipse.mylyn.tasks.core.sync.ISynchronizationSession; + +/** + * GitHub pull request connector. + */ +public class PullRequestConnector extends RepositoryConnector { + + /** + * SEGMENT_PULL + */ + public static final String SEGMENT_PULL = "/pull"; //$NON-NLS-1$ + + /** + * GitHub kind. + */ + public static final String KIND = "githubPullRequests"; //$NON-NLS-1$ + + /** + * Get repository label for id provider. + * + * @param repo + * @return label + */ + public static String getRepositoryLabel(IRepositoryIdProvider repo) { + return repo.generateId() + Messages.PullRequestConnector_LabelPullRequests; + } + + /** + * Create pull request task repository + * + * @param repo + * @param username + * @param password + * @return task repository + */ + public static TaskRepository createTaskRepository(Repository repo, + String username, String password) { + String url = PullRequestConnector.appendPulls(GitHub.createGitHubUrl( + repo.getOwner().getLogin(), repo.getName())); + TaskRepository repository = new TaskRepository( + PullRequestConnector.KIND, url); + repository.setProperty(IRepositoryConstants.PROPERTY_LABEL, + getRepositoryLabel(repo)); + if (username != null && password != null) + repository.setCredentials(AuthenticationType.REPOSITORY, + new AuthenticationCredentials(username, password), true); + repository.setProperty(IRepositoryConstants.PROPERTY_CATEGORY, + IRepositoryConstants.CATEGORY_REVIEW); + return repository; + } + + /** + * Appends a trailing '/pull's segment to the given url + * + * @param repoUrl + * @return appended string + */ + public static String appendPulls(final String repoUrl) { + return repoUrl + IGitHubConstants.SEGMENT_PULLS; + } + + /** + * Strip trailing '/pulls' segment from string if it ends with it. + * + * @param repoUrl + * @return stripped string + */ + public static String stripPulls(String repoUrl) { + if (repoUrl.endsWith(IGitHubConstants.SEGMENT_PULLS)) + repoUrl = repoUrl.substring(0, repoUrl.length() + - IGitHubConstants.SEGMENT_PULLS.length()); + return repoUrl; + } + + /** + * Get pull request from task data + * + * @param data + * @return pull request + */ + public static PullRequestComposite getPullRequest(TaskData data) { + if (data == null) + return null; + String value = PullRequestAttribute.MODEL.getMetadata().getValue(data); + if (value.length() == 0) + return null; + return GsonUtils.fromJson(value, PullRequestComposite.class); + } + + /** + * Get repository id from pull request task repository url + * + * @param prRepoUrl + * @return repository id + */ + public static RepositoryId getRepository(String prRepoUrl) { + return GitHub.getRepository(stripPulls(prRepoUrl)); + } + + /** + * GitHub specific {@link AbstractTaskDataHandler}. + */ + private final PullRequestTaskDataHandler taskDataHandler; + + /** + * Create GitHub issue repository connector + */ + public PullRequestConnector() { + taskDataHandler = new PullRequestTaskDataHandler(this); + } + + /** + * {@inheritDoc} + * + * @see #KIND + */ + @Override + public String getConnectorKind() { + return KIND; + } + + /** + * {@inheritDoc} + */ + @Override + public String getLabel() { + return Messages.PullRequestConnector_Label; + } + + /** + * {@inheritDoc} + */ + @Override + public AbstractTaskDataHandler getTaskDataHandler() { + return taskDataHandler; + } + + @Override + public IStatus performQuery(TaskRepository repository, + IRepositoryQuery query, TaskDataCollector collector, + ISynchronizationSession session, IProgressMonitor monitor) { + IStatus result = Status.OK_STATUS; + List<String> statuses = QueryUtils.getAttributes( + IssueService.FILTER_STATE, query); + + monitor.beginTask(Messages.PullRequestConnector_TaskFetching, + statuses.size()); + try { + RepositoryId repo = getRepository(repository.getRepositoryUrl()); + + GitHubClient client = IssueConnector.createClient(repository); + PullRequestService service = new PullRequestService(client); + IssueService commentService = new IssueService(client); + + for (String status : statuses) { + List<PullRequest> pulls = service.getPullRequests(repo, status); + + // collect task data + for (PullRequest pr : pulls) { + pr = service.getPullRequest(repo, pr.getNumber()); + PullRequestComposite prComp = new PullRequestComposite(); + prComp.setRequest(pr); + List<Comment> comments = null; + if (pr.getComments() > 0) + comments = commentService.getComments(repo.getOwner(), + repo.getName(), + Integer.toString(pr.getNumber())); + if (pr.getCommits() > 0) + prComp.setCommits(service.getCommits(repo, + pr.getNumber())); + TaskData taskData = taskDataHandler.createTaskData( + repository, monitor, repo, prComp, comments); + collector.accept(taskData); + } + monitor.worked(1); + } + } catch (IOException e) { + result = GitHub.createWrappedStatus(e); + } + + monitor.done(); + return result; + } + + @Override + public TaskData getTaskData(TaskRepository repository, String taskId, + IProgressMonitor monitor) throws CoreException { + RepositoryId repo = getRepository(repository.getRepositoryUrl()); + + try { + GitHubClient client = IssueConnector.createClient(repository); + PullRequestService service = new PullRequestService(client); + PullRequest pr = service.getPullRequest(repo, + Integer.parseInt(taskId)); + PullRequestComposite prComp = new PullRequestComposite(); + prComp.setRequest(pr); + IssueService commentService = new IssueService(client); + List<Comment> comments = null; + if (pr.getComments() > 0) + comments = commentService.getComments(repo.getOwner(), + repo.getName(), taskId); + if (pr.getCommits() > 0) + prComp.setCommits(service.getCommits(repo, pr.getNumber())); + return taskDataHandler.createTaskData(repository, monitor, repo, + prComp, comments); + } catch (IOException e) { + throw new CoreException(GitHub.createWrappedStatus(e)); + } + } + + @Override + public String getRepositoryUrlFromTaskUrl(String taskFullUrl) { + int lastPull = taskFullUrl.lastIndexOf(SEGMENT_PULL); + if (lastPull != -1) + return taskFullUrl.substring(0, lastPull) + + IGitHubConstants.SEGMENT_PULLS; + return null; + } + + @Override + public String getTaskUrl(String repositoryUrl, String taskId) { + return stripPulls(repositoryUrl) + SEGMENT_PULL + "/" + taskId; //$NON-NLS-1$ + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestOperation.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestOperation.java new file mode 100644 index 00000000..6e2dabbd --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestOperation.java @@ -0,0 +1,72 @@ +/****************************************************************************** + * 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.core.pr; + +/** + * Enumeration of task operations + */ +public enum PullRequestOperation { + + /** + * LEAD + */ + LEAVE("Leave "), //$NON-NLS-1$ + + /** + * REOPEN + */ + REOPEN("Reopen"), //$NON-NLS-1$ + + /** + * CLOSE + */ + CLOSE("Close"); //$NON-NLS-1$ + + private final String label; + + private PullRequestOperation(String label) { + this.label = label; + } + + /** + * Get label + * + * @return label + */ + public String getLabel() { + return label; + } + + /** + * Get id + * + * @return id + */ + public String getId() { + return name(); + } + + /** + * get the operation by its id + * + * @param opId + * the id, or null + * @return the operation, or null if the id was null or did not match any + * operation + */ + public static PullRequestOperation fromId(final String opId) { + for (PullRequestOperation op : values()) + if (op.getId().equals(opId)) + return op; + return null; + } + +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestTaskDataHandler.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestTaskDataHandler.java new file mode 100644 index 00000000..d7f24620 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestTaskDataHandler.java @@ -0,0 +1,230 @@ +/****************************************************************************** + * 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.core.pr; + +import java.io.IOException; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.egit.github.core.Comment; +import org.eclipse.egit.github.core.IRepositoryIdProvider; +import org.eclipse.egit.github.core.PullRequest; +import org.eclipse.egit.github.core.RepositoryId; +import org.eclipse.egit.github.core.User; +import org.eclipse.egit.github.core.client.GitHubClient; +import org.eclipse.egit.github.core.client.GsonUtils; +import org.eclipse.egit.github.core.service.IssueService; +import org.eclipse.egit.github.core.service.PullRequestService; +import org.eclipse.mylyn.internal.github.core.GitHub; +import org.eclipse.mylyn.internal.github.core.GitHubTaskDataHandler; +import org.eclipse.mylyn.internal.github.core.issue.IssueConnector; +import org.eclipse.mylyn.tasks.core.ITaskMapping; +import org.eclipse.mylyn.tasks.core.RepositoryResponse; +import org.eclipse.mylyn.tasks.core.RepositoryResponse.ResponseKind; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.core.data.TaskAttribute; +import org.eclipse.mylyn.tasks.core.data.TaskData; + +/** + * GitHub issue task data handler + */ +public class PullRequestTaskDataHandler extends GitHubTaskDataHandler { + + private static final String DATA_VERSION = "1.1"; //$NON-NLS-1$ + + /** + * Create GitHub issue task data handler for connector + * + * @param connector + */ + public PullRequestTaskDataHandler(PullRequestConnector connector) { + } + + /** + * Create task data for pull request + * + * @param repository + * @param monitor + * @param repo + * @param prComp + * @return task data + */ + public TaskData createTaskData(TaskRepository repository, + IProgressMonitor monitor, IRepositoryIdProvider repo, + PullRequestComposite prComp) { + PullRequest pr = prComp.getRequest(); + String key = Integer.toString(pr.getNumber()); + TaskData data = new TaskData(getAttributeMapper(repository), + PullRequestConnector.KIND, repository.getRepositoryUrl(), key); + data.setVersion(DATA_VERSION); + + createOperations(data, pr); + + createAttribute(data, PullRequestAttribute.KEY.getMetadata(), key); + createAttribute(data, PullRequestAttribute.TITLE.getMetadata(), + pr.getTitle()); + createAttribute(data, PullRequestAttribute.BODY.getMetadata(), + pr.getBody()); + createAttribute(data, PullRequestAttribute.STATUS.getMetadata(), + pr.getState()); + createAttribute(data, PullRequestAttribute.CREATION_DATE.getMetadata(), + pr.getCreatedAt()); + createAttribute(data, + PullRequestAttribute.MODIFICATION_DATE.getMetadata(), + pr.getUpdatedAt()); + createAttribute(data, PullRequestAttribute.CLOSED_DATE.getMetadata(), + pr.getClosedAt()); + + User reporter = pr.getUser(); + createAttribute(data, PullRequestAttribute.REPORTER.getMetadata(), + reporter, repository); + String reporterGravatar = reporter != null ? reporter.getAvatarUrl() + : null; + createAttribute(data, + PullRequestAttribute.REPORTER_GRAVATAR.getMetadata(), + reporterGravatar); + + createAttribute(data, PullRequestAttribute.COMMENT_NEW.getMetadata()); + + createAttribute(data, PullRequestAttribute.MODEL.getMetadata(), + GsonUtils.toJson(prComp)); + + return data; + } + + private void createOperations(TaskData data, PullRequest pr) { + createOperationAttribute(data); + + if (data.isNew()) + return; + + String state = pr.getState(); + if (state != null) { + addOperation(data, pr, PullRequestOperation.LEAVE, true); + if (state.equals(IssueService.STATE_OPEN)) + addOperation(data, pr, PullRequestOperation.CLOSE, false); + else if (state.equals(IssueService.STATE_CLOSED)) + addOperation(data, pr, PullRequestOperation.REOPEN, false); + } + } + + private void addOperation(TaskData data, PullRequest pr, + PullRequestOperation operation, boolean isDefault) { + String id = operation.getId(); + String label = createOperationLabel(pr, operation); + addOperation(data, id, label, isDefault); + } + + private String createOperationLabel(PullRequest pr, + PullRequestOperation operation) { + return operation == PullRequestOperation.LEAVE ? operation.getLabel() + + pr.getState() : operation.getLabel(); + } + + /** + * Create task data for pull request + * + * @param repository + * @param monitor + * @param repo + * @param pr + * @param comments + * @return task data + */ + public TaskData createTaskData(TaskRepository repository, + IProgressMonitor monitor, IRepositoryIdProvider repo, + PullRequestComposite pr, List<Comment> comments) { + TaskData taskData = createTaskData(repository, monitor, repo, pr); + taskData.setPartial(false); + + addComments(taskData.getRoot(), comments, repository); + + return taskData; + } + + private PullRequest createPullRequest(TaskData taskData) { + PullRequest pr = new PullRequest(); + if (!taskData.isNew()) + pr.setNumber(Integer.parseInt(taskData.getTaskId())); + + pr.setBody(getAttributeValue(taskData, + PullRequestAttribute.BODY.getMetadata())); + pr.setTitle(getAttributeValue(taskData, + PullRequestAttribute.TITLE.getMetadata())); + + return pr; + } + + @Override + public boolean initializeTaskData(TaskRepository repository, TaskData data, + ITaskMapping initializationData, IProgressMonitor monitor) + throws CoreException { + data.setVersion(DATA_VERSION); + for (PullRequestAttribute attr : PullRequestAttribute.values()) + if (attr.getMetadata().isInitTask()) + createAttribute(data, attr.getMetadata(), (String) null); + return true; + } + + @Override + public RepositoryResponse postTaskData(TaskRepository repository, + TaskData taskData, Set<TaskAttribute> oldAttributes, + IProgressMonitor monitor) throws CoreException { + String taskId = taskData.getTaskId(); + PullRequest pr = createPullRequest(taskData); + RepositoryId repo = PullRequestConnector.getRepository(repository + .getRepositoryUrl()); + try { + GitHubClient client = IssueConnector.createClient(repository); + PullRequestService prService = new PullRequestService(client); + IssueService issueService = new IssueService(client); + if (taskData.isNew()) { + pr.setState(IssueService.STATE_OPEN); + pr = prService.createPullRequest(repo, pr); + taskId = Integer.toString(pr.getNumber()); + } else { + // Handle new comment + String comment = getAttributeValue(taskData, + PullRequestAttribute.COMMENT_NEW.getMetadata()); + if (comment != null && comment.length() > 0) + issueService.createComment(repo.getOwner(), repo.getName(), + taskId, comment); + + // Handle state change + TaskAttribute operationAttribute = taskData.getRoot() + .getAttribute(TaskAttribute.OPERATION); + if (operationAttribute != null) { + PullRequestOperation operation = PullRequestOperation + .fromId(operationAttribute.getValue()); + if (operation != PullRequestOperation.LEAVE) + switch (operation) { + case REOPEN: + pr.setState(IssueService.STATE_OPEN); + break; + case CLOSE: + pr.setState(IssueService.STATE_CLOSED); + break; + default: + break; + } + } + prService.editPullRequest(repo, pr); + } + return new RepositoryResponse( + taskData.isNew() ? ResponseKind.TASK_CREATED + : ResponseKind.TASK_UPDATED, taskId); + } catch (IOException e) { + throw new CoreException(GitHub.createWrappedStatus(e)); + } + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestUtils.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestUtils.java new file mode 100644 index 00000000..5eb734f4 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/PullRequestUtils.java @@ -0,0 +1,145 @@ +/****************************************************************************** + * 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.core.pr; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; + +import org.eclipse.egit.core.Activator; +import org.eclipse.egit.core.RepositoryCache; +import org.eclipse.egit.github.core.PullRequest; +import org.eclipse.egit.github.core.PullRequestMarker; +import org.eclipse.jgit.lib.ConfigConstants; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.transport.RefSpec; +import org.eclipse.jgit.transport.RemoteConfig; +import org.eclipse.jgit.transport.URIish; +import org.eclipse.mylyn.internal.github.core.GitHub; + +/** + * Pull request utilities + */ +public abstract class PullRequestUtils { + + /** + * HEAD_SOURCE + */ + public static final String HEAD_SOURCE = '+' + Constants.R_HEADS + '*'; + + /** + * Get destination ref spec + * + * @param remote + * @return ref spec + */ + public static String getDesintationRef(RemoteConfig remote) { + return Constants.R_REMOTES + remote.getName() + "/*"; //$NON-NLS-1$ + } + + /** + * Get branch name for pull request + * + * @param request + * @return non-null/non-empty branch name + */ + public static String getBranchName(PullRequest request) { + return "pr-" + request.getNumber(); //$NON-NLS-1$ + } + + /** + * Get Git repository for pull request + * + * @param request + * @return repository or null if none found + */ + public static Repository getRepository(PullRequest request) { + org.eclipse.egit.github.core.Repository remoteRepo = request.getBase() + .getRepository(); + String id = remoteRepo.getOwner().getLogin() + '/' + + remoteRepo.getName() + Constants.DOT_GIT; + RepositoryCache cache = Activator.getDefault().getRepositoryCache(); + for (String path : Activator.getDefault().getRepositoryUtil() + .getConfiguredRepositories()) + try { + Repository repo = cache.lookupRepository(new File(path)); + RemoteConfig rc = new RemoteConfig(repo.getConfig(), + Constants.DEFAULT_REMOTE_NAME); + for (URIish uri : rc.getURIs()) + if (uri.toString().endsWith(id)) + return repo; + } catch (IOException e) { + GitHub.logError(e); + continue; + } catch (URISyntaxException e) { + GitHub.logError(e); + continue; + } + return null; + } + + /** + * Configure pull request topic branch to use head remote + * + * @param repo + * @param request + * @throws IOException + */ + public static void configureTopicBranch(Repository repo, PullRequest request) + throws IOException { + String branch = getBranchName(request); + PullRequestMarker head = request.getHead(); + String remote = head.getRepository().getOwner().getLogin(); + StoredConfig config = repo.getConfig(); + config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, branch, + ConfigConstants.CONFIG_KEY_MERGE, Constants.R_REMOTES + remote + + "/" + head.getRef()); //$NON-NLS-1$ + config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, branch, + ConfigConstants.CONFIG_KEY_REMOTE, remote); + config.save(); + } + + /** + * Add remote for the head of a pull request if it doesn't exist + * + * @param repo + * @param request + * @return remote config + * @throws IOException + * @throws URISyntaxException + */ + public static RemoteConfig addRemote(Repository repo, PullRequest request) + throws IOException, URISyntaxException { + StoredConfig config = repo.getConfig(); + org.eclipse.egit.github.core.Repository head = request.getHead() + .getRepository(); + String name = head.getOwner().getLogin(); + for (RemoteConfig candidate : RemoteConfig.getAllRemoteConfigs(config)) + if (name.equals(candidate.getName())) + return candidate; + + RemoteConfig remote = new RemoteConfig(config, name); + if (head.isPrivate()) + remote.addURI(new URIish(org.eclipse.egit.github.core.Repository + .createRemoteSshUrl(head))); + else + remote.addURI(new URIish(org.eclipse.egit.github.core.Repository + .createRemoteReadOnlyUrl(head))); + + remote.addFetchRefSpec(new RefSpec(HEAD_SOURCE + + ":" + getDesintationRef(remote))); //$NON-NLS-1$ + remote.update(config); + config.save(); + return remote; + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/messages.properties b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/messages.properties new file mode 100644 index 00000000..474d81f6 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/internal/github/core/pr/messages.properties @@ -0,0 +1,14 @@ +PullRequestAttribute_LabelClosedAt=Closed: +PullRequestAttribute_LabelComment=Comment: +PullRequestAttribute_LabelCreatedAt=Created: +PullRequestAttribute_LabelDescription=Description +PullRequestAttribute_LabelKey=Key +PullRequestAttribute_LabelMergedAt=Merged: +PullRequestAttribute_LabelModel=Model +PullRequestAttribute_LabelModifiedAt=Modified: +PullRequestAttribute_LabelReporter=Reporter +PullRequestAttribute_LabelStatus=Status +PullRequestAttribute_LabelSummary=Summary +PullRequestConnector_Label=GitHub Pull Requests +PullRequestConnector_LabelPullRequests=\ pull requests +PullRequestConnector_TaskFetching=Fetching pull requests |