use of com.google.copybara.exception.ValidationException in project copybara by google.
the class GitHubPrOrigin method checkReviewApprovers.
/**
* Check that the PR has been approved by sufficient reviewers of the correct types, in accordance
* with the values provided in the `review_state` and `review_approvers` params
*/
private void checkReviewApprovers(GitHubApi api, String project, PullRequest prData, ImmutableListMultimap.Builder<String, String> labelsBuilder) throws ValidationException, RepoException {
if (reviewState == null) {
return;
}
ImmutableList<Review> reviews = api.getReviews(project, prData.getNumber());
ApproverState approverState = reviewState.shouldMigrate(reviews, reviewApprovers, prData.getHead().getSha());
if (!forceImport() && !approverState.shouldMigrate()) {
String rejected = "";
if (!approverState.rejectedReviews().isEmpty()) {
rejected = String.format("\nThe following reviews were ignored because they don't meet " + "the association requirement of %s:\n%s", Joiner.on(", ").join(reviewApprovers), approverState.rejectedReviews().entries().stream().map(e -> String.format("User %s - Association: %s", e.getKey(), e.getValue())).collect(joining("\n")));
}
throw new EmptyChangeException(String.format("Cannot migrate http://github.com/%s/pull/%d because it is missing the required" + " approvals (origin is configured as %s).%s", project, prData.getNumber(), reviewState, rejected));
}
Set<String> approvers = new HashSet<>();
Set<String> others = new HashSet<>();
for (Review review : reviews) {
if (reviewApprovers.contains(review.getAuthorAssociation())) {
approvers.add(review.getUser().getLogin());
} else {
others.add(review.getUser().getLogin());
}
}
labelsBuilder.putAll(GITHUB_PR_REVIEWER_APPROVER, approvers);
labelsBuilder.putAll(GITHUB_PR_REVIEWER_OTHER, others);
}
use of com.google.copybara.exception.ValidationException in project copybara by google.
the class GitHubPrOrigin method checkRequiredStatusContextNames.
/**
* Check that the PR has a state of "success" for each status whose context is in the list
* provided in the `required_status_context_names` param
*/
private void checkRequiredStatusContextNames(GitHubApi api, String project, PullRequest prData) throws ValidationException, RepoException {
Set<String> requiredStatusContextNames = getRequiredStatusContextNames();
if (forceImport() || requiredStatusContextNames.isEmpty()) {
return;
}
try (ProfilerTask ignore = generalOptions.profiler().start("github_api_get_combined_status")) {
CombinedStatus combinedStatus = api.getCombinedStatus(project, prData.getHead().getSha());
Set<String> requiredButNotPresent = Sets.newHashSet(requiredStatusContextNames);
List<Status> successStatuses = combinedStatus.getStatuses().stream().filter(e -> e.getState() == State.SUCCESS).collect(Collectors.toList());
requiredButNotPresent.removeAll(Collections2.transform(successStatuses, Status::getContext));
if (!requiredButNotPresent.isEmpty()) {
throw new EmptyChangeException(String.format("Cannot migrate http://github.com/%s/pull/%d because the following ci labels " + "have not been passed: %s", project, prData.getNumber(), requiredButNotPresent));
}
}
}
use of com.google.copybara.exception.ValidationException in project copybara by google.
the class GitHubPrOrigin method newReader.
@Override
public Reader<GitRevision> newReader(Glob originFiles, Authoring authoring) throws ValidationException {
return new ReaderImpl(url, originFiles, authoring, gitOptions, gitOriginOptions, generalOptions, /*includeBranchCommitLogs=*/
false, submoduleStrategy, firstParent, partialFetch, patchTransformation, describeVersion, /*configPath=*/
null, /*workflowName=*/
null) {
/**
* Disable rebase since this is controlled by useMerge field.
*/
@Override
protected void maybeRebase(GitRepository repo, GitRevision ref, Path workdir) throws RepoException, CannotResolveRevisionException {
}
@Override
public Optional<Baseline<GitRevision>> findBaseline(GitRevision startRevision, String label) throws RepoException, ValidationException {
if (!baselineFromBranch) {
return super.findBaseline(startRevision, label);
}
return findBaselinesWithoutLabel(startRevision, /*limit=*/
1).stream().map(e -> new Baseline<>(e.getSha1(), e)).findFirst();
}
@Override
public ImmutableList<GitRevision> findBaselinesWithoutLabel(GitRevision startRevision, int limit) throws RepoException, ValidationException {
String baseline = Iterables.getLast(startRevision.associatedLabels().get(GITHUB_BASE_BRANCH_SHA1), null);
checkNotNull(baseline, "%s label should be present in %s", GITHUB_BASE_BRANCH_SHA1, startRevision);
GitRevision baselineRev = getRepository().resolveReference(baseline);
// Don't skip the first change as it is already the baseline
BaselinesWithoutLabelVisitor<GitRevision> visitor = new BaselinesWithoutLabelVisitor<>(originFiles, limit, /*skipFirst=*/
false);
visitChanges(baselineRev, visitor);
return visitor.getResult();
}
@Override
public Endpoint getFeedbackEndPoint(Console console) throws ValidationException {
gitHubOptions.validateEndpointChecker(endpointChecker);
return new GitHubEndPoint(gitHubOptions.newGitHubApiSupplier(url, endpointChecker, ghHost), url, console, ghHost);
}
/**
* Deal with the case of useMerge. We have a new commit (the merge) and first-parent from that
* commit doesn't work for this case.
*/
@Override
public ChangesResponse<GitRevision> changes(@Nullable GitRevision fromRef, GitRevision toRef) throws RepoException, ValidationException {
checkCondition(toRef.associatedLabels().containsKey(GITHUB_PR_USE_MERGE), "Cannot determine whether 'use_merge' was set.");
if (toRef.associatedLabel(GITHUB_PR_USE_MERGE).contains("false")) {
return super.changes(fromRef, toRef);
}
GitLogEntry merge = Iterables.getOnlyElement(getRepository().log(toRef.getSha1()).withLimit(1).run());
// Fast-forward merge
if (merge.getParents().size() == 1) {
return super.changes(fromRef, toRef);
}
// HEAD of the Pull Request
GitRevision gitRevision = merge.getParents().get(1);
ChangesResponse<GitRevision> prChanges = super.changes(fromRef, gitRevision);
// origin_files
if (prChanges.isEmpty()) {
return prChanges;
}
try {
return ChangesResponse.forChanges(ImmutableList.<Change<GitRevision>>builder().addAll(prChanges.getChanges()).add(change(merge.getCommit())).build());
} catch (EmptyChangeException e) {
throw new RepoException("Error getting the merge commit information: " + merge, e);
}
}
};
}
use of com.google.copybara.exception.ValidationException in project copybara by google.
the class GitRepository method lsRemote.
private static ImmutableMap<String, String> lsRemote(Path cwd, String url, Collection<String> refs, GitEnvironment gitEnv, int maxLogLines, Collection<String> flags) throws RepoException, ValidationException {
ImmutableMap.Builder<String, String> result = ImmutableMap.builder();
List<String> args = Lists.newArrayList("ls-remote");
args.addAll(flags);
try {
args.add(validateUrl(url));
} catch (ValidationException e) {
throw new RepoException("Invalid url: " + url, e);
}
args.addAll(refs);
CommandOutputWithStatus output;
try {
output = executeGit(cwd, args, gitEnv, false, maxLogLines);
} catch (BadExitStatusWithOutputException e) {
String errMsg = String.format("Error running ls-remote for '%s' and refs '%s': Exit code %s, Output:\n%s", url, refs, e.getOutput().getTerminationStatus().getExitCode(), e.getOutput().getStderr());
if (e.getOutput().getStderr().contains("Please make sure you have the correct access rights")) {
throw new ValidationException(errMsg, e);
}
throw new RepoException(errMsg, e);
} catch (CommandException e) {
throw new RepoException(String.format("Error running ls-remote for '%s' and refs '%s'", url, refs), e);
}
if (output.getTerminationStatus().success()) {
for (String line : Splitter.on('\n').split(output.getStdout())) {
if (line.isEmpty()) {
continue;
}
Matcher matcher = LS_REMOTE_OUTPUT_LINE.matcher(line);
if (!matcher.matches()) {
throw new RepoException("Unexpected format for ls-remote output: " + line);
}
result.put(matcher.group(2), matcher.group(1));
if (DEFAULT_BRANCH_PATTERN.matches(line)) {
// we have a ref: line, indicating that we were looking for a symbolic ref. bail.
break;
}
}
}
return result.buildOrThrow();
}
use of com.google.copybara.exception.ValidationException in project copybara by google.
the class GitRepository method listSubmodules.
/**
* Find submodules information for the current repository.
*
* @param currentRemoteUrl remote url associated with the repository. It will be used to
* resolve relative URLs (for example: url = ../foo).
*/
Iterable<Submodule> listSubmodules(String currentRemoteUrl) throws RepoException {
ImmutableList.Builder<Submodule> result = ImmutableList.builder();
for (String submoduleName : getSubmoduleNames()) {
String path = getSubmoduleField(submoduleName, "path");
if (path == null) {
throw new RepoException("Path is required for submodule " + submoduleName);
}
String url = getSubmoduleField(submoduleName, "url");
if (url == null) {
throw new RepoException("Url is required for submodule " + submoduleName);
}
String branch = getSubmoduleField(submoduleName, "branch");
if (branch != null && branch.equals(".")) {
branch = "HEAD";
}
FileUtil.checkNormalizedRelative(path);
// If the url is relative, construct a url using the parent module remote url.
if (url.startsWith("../")) {
url = siblingUrl(currentRemoteUrl, submoduleName, url.substring(3));
} else if (url.startsWith("./")) {
url = siblingUrl(currentRemoteUrl, submoduleName, url.substring(2));
}
try {
result.add(new Submodule(validateUrl(url), submoduleName, branch, path));
} catch (ValidationException e) {
throw new RepoException("Invalid url: " + url, e);
}
}
return result.build();
}
Aggregations