blob: a23422fd95dcbef16709c780b5d603b6480fcbe6 [file] [log] [blame]
/******************************************************************************
* 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 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* 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.RepositoryCache;
import org.eclipse.egit.core.RepositoryUtil;
import org.eclipse.egit.github.core.PullRequest;
import org.eclipse.egit.github.core.PullRequestMarker;
import org.eclipse.egit.github.core.User;
import org.eclipse.egit.github.core.util.UrlUtils;
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 "pull-request-" + 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()
.getRepo();
String id = remoteRepo.getOwner().getLogin() + '/'
+ remoteRepo.getName() + Constants.DOT_GIT;
for (String path : RepositoryUtil.INSTANCE.getConfiguredRepositories())
try {
Repository repo = RepositoryCache.INSTANCE
.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);
String remote = request.getHead().getRepo().getOwner().getLogin();
StoredConfig config = repo.getConfig();
config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, branch,
ConfigConstants.CONFIG_KEY_MERGE, getHeadBranch(request));
config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, branch,
ConfigConstants.CONFIG_KEY_REMOTE, remote);
config.save();
}
/**
* Get owner of marker
*
* @param marker
* @return owner login name, may be null
*/
public static String getOwner(PullRequestMarker marker) {
if (marker == null)
return null;
org.eclipse.egit.github.core.Repository repo = marker.getRepo();
if (repo == null)
return null;
User owner = repo.getOwner();
return owner != null ? owner.getLogin() : null;
}
/**
* Are the given pull request's source and destination repositories the
* same?
*
* @param request
* @return true if same, false otherwise
*/
public static boolean isFromSameRepository(PullRequest request) {
if (request == null)
return false;
String headLogin = getOwner(request.getHead());
if (headLogin == null)
return false;
return headLogin.equals(getOwner(request.getBase()));
}
/**
* Get remote for given pull request
*
* @param repo
* @param request
* @return remote config
* @throws URISyntaxException
*/
public static RemoteConfig getRemote(Repository repo, PullRequest request)
throws URISyntaxException {
if (isFromSameRepository(request))
return getRemoteConfig(repo, Constants.DEFAULT_REMOTE_NAME);
else
return getRemoteConfig(repo, getOwner(request.getHead()));
}
/**
* Get remote config with given name
*
* @param repo
* @param name
* @return remote config
* @throws URISyntaxException
*/
public static RemoteConfig getRemoteConfig(Repository repo, String name)
throws URISyntaxException {
for (RemoteConfig candidate : RemoteConfig.getAllRemoteConfigs(repo
.getConfig()))
if (name.equals(candidate.getName()))
return candidate;
return null;
}
/**
* Add remote for the head of a pull request if it doesn't exist
*
* @param repo
* @param request
* @return remote configuration
* @throws IOException
* @throws URISyntaxException
*/
public static RemoteConfig addRemote(Repository repo, PullRequest request)
throws IOException, URISyntaxException {
RemoteConfig remote = getRemote(repo, request);
if (remote != null)
return remote;
StoredConfig config = repo.getConfig();
org.eclipse.egit.github.core.Repository head = request.getHead()
.getRepo();
remote = new RemoteConfig(config, head.getOwner().getLogin());
if (head.isPrivate())
remote.addURI(new URIish(UrlUtils.createRemoteSshUrl(head)));
else
remote.addURI(new URIish(UrlUtils.createRemoteReadOnlyUrl(head)));
remote.addFetchRefSpec(new RefSpec(HEAD_SOURCE
+ ":" + getDesintationRef(remote))); //$NON-NLS-1$
remote.update(config);
config.save();
return remote;
}
/**
* Is given branch name the currently checked out branch?
*
* @param name
* @param repo
* @return true if checked out branch, false otherwise
*/
public static boolean isCurrentBranch(String name, Repository repo) {
try {
return name.equals(Repository.shortenRefName(repo.getFullBranch()));
} catch (IOException e) {
return false;
}
}
/**
* Get head branch ref for outside repository pull requests
*
* @param request
* @return remote head branch ref name
*/
public static String getHeadBranch(PullRequest request) {
PullRequestMarker head = request.getHead();
return Constants.R_REMOTES + head.getRepo().getOwner().getLogin() + '/'
+ head.getRef();
}
}