eu.solven.cleanthat.git_abstraction.GithubRepositoryFacade Maven / Gradle / Ivy
package eu.solven.cleanthat.git_abstraction;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.Optional;
import java.util.stream.Stream;
import org.kohsuke.github.GHCommit;
import org.kohsuke.github.GHIssueState;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHRef;
import org.kohsuke.github.GHRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.solven.cleanthat.codeprovider.git.GitRepoBranchSha1;
import eu.solven.cleanthat.github.CleanthatRefFilterProperties;
/**
* Enable a Facade over RewiewRequestProvider
*
* @author Benoit Lacelle
*
*/
public class GithubRepositoryFacade {
private static final Logger LOGGER = LoggerFactory.getLogger(GithubRepositoryFacade.class);
final GHRepository repository;
public GithubRepositoryFacade(GHRepository repository) {
this.repository = repository;
}
public Stream findAnyPrHeadMatchingRef(String ref) throws IOException {
return repository.getPullRequests(GHIssueState.OPEN).stream().filter(pr -> {
return ref.equals(GithubFacade.toFullGitRef(pr.getHead()));
});
}
public Optional findFirstPrBaseMatchingRef(String ref) throws IOException {
return repository.getPullRequests(GHIssueState.OPEN).stream().filter(pr -> {
return ref.equals(GithubFacade.toFullGitRef(pr.getBase()));
}).findAny();
}
public Optional> openPrIfNoneExists(GitRepoBranchSha1 base, GitRepoBranchSha1 head, String title, String body)
throws IOException {
String repoName = getRepoName();
if (!base.getRepoName().equals(repoName)) {
throw new IllegalArgumentException(
"The base (" + base + ") is not a ref of current repo (" + repoName + ")");
} else if (!head.getRepoName().equals(repoName)) {
// TODO We would need the head username to build a headRef like 'username:branch'
// This way rely on the match Github allows a single fork per username/organisation
throw new UnsupportedOperationException(
"The head (" + head + ") has a different repository than current repo (" + repoName + ")");
}
String baseFullRef = base.getRef();
if (!baseFullRef.startsWith(CleanthatRefFilterProperties.BRANCHES_PREFIX)) {
throw new IllegalArgumentException("The base has to be a branch. ref=" + baseFullRef);
}
String headRef = head.getRef();
Optional existingPr = repository.getPullRequests(GHIssueState.ALL).stream().filter(pr -> {
return baseFullRef.equals(GithubFacade.toFullGitRef(pr.getBase()))
&& headRef.equals(GithubFacade.toFullGitRef(pr.getHead()));
}).findAny();
if (existingPr.isEmpty()) {
String baseBranchName = baseFullRef.substring(CleanthatRefFilterProperties.BRANCHES_PREFIX.length());
// We create only Draft PR for now
// Maintainers are of-course allowed to modify CleanThat PR
GHPullRequest pr = repository.createPullRequest(title, baseBranchName, headRef, body, true, true);
return Optional.of(pr.getNumber());
} else {
LOGGER.info("Existing PR: {}", existingPr.get());
return Optional.empty();
}
}
public String getRepoName() {
return repository.getName();
}
public void removeRef(GitRepoBranchSha1 ref) throws IOException {
if (!ref.getRepoName().equals(ref.getRepoName())) {
throw new IllegalArgumentException("Inconsistent repo: " + ref.getRepoName() + "and " + ref.getRepoName());
}
GHRef remoteRef = getRef(ref.getRef());
URL remoteRefUrl = remoteRef.getUrl();
String currentSha = remoteRef.getObject().getSha();
String initialSha = ref.getSha();
if (currentSha.equals(initialSha)) {
LOGGER.info("About to delete {}", remoteRefUrl);
remoteRef.delete();
LOGGER.info("Deleted {}", remoteRefUrl);
} else {
LOGGER.info("We skip removal of {} as its current sha ({}) differs from the sha at creation ({})",
remoteRefUrl,
currentSha,
initialSha);
}
}
/**
*
* @param refName
* a refName, starting with 'refs/'
* @return
* @throws IOException
*/
public GHRef getRef(String refName) throws IOException {
if (!refName.startsWith(CleanthatRefFilterProperties.REFS_PREFIX)) {
throw new IllegalArgumentException("Invalid ref: " + refName);
}
// repository.getRef expects a ref name without the leading 'refs/'
String githubRefName = refName.substring(CleanthatRefFilterProperties.REFS_PREFIX.length());
return repository.getRef(githubRefName);
}
public GHRepository getRepository() {
return repository;
}
public GHCommit getCommit(String sha1) {
try {
return repository.getCommit(sha1);
} catch (IOException e) {
throw new UncheckedIOException(
"Issue fetching commit for sha1=" + sha1 + " (repo=" + repository.getHtmlUrl() + ")",
e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy