/* * Copyright (C) 2016 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.copybara.git; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.copybara.GeneralOptions; import com.google.copybara.LabelFinder; import com.google.copybara.exception.RepoException; import com.google.copybara.exception.ValidationException; import com.google.re2j.Matcher; import com.google.re2j.Pattern; import javax.annotation.Nullable; /** * Integrate label for GitHub PR * * <p>Format like: "https://github.com/google/copybara/pull/12345 from mikelalcon:master SHA-1" * * <p>Where SHA-1 is optional: If present it means to integrate the specific SHA-1. Otherwise the * head of the PR is used. */ class GitHubPRIntegrateLabel implements IntegrateLabel { private static final Pattern LABEL_PATTERN = Pattern.compile( "https://github.com/([a-zA-Z0-9_/-]+)/pull/([0-9]+) from ([^\\s\\r\\n]*)(?: ([0-9a-f]{7,40}))?"); private final GitRepository repository; private final GeneralOptions generalOptions; private final String projectId; private final long prNumber; private final String originBranch; @Nullable private final String sha1; GitHubPRIntegrateLabel(GitRepository repository, GeneralOptions generalOptions, String projectId, long prNumber, String originBranch, @Nullable String sha1) { this.repository = Preconditions.checkNotNull(repository); this.generalOptions = Preconditions.checkNotNull(generalOptions); this.projectId = Preconditions.checkNotNull(projectId); this.prNumber = prNumber; this.originBranch = Preconditions.checkNotNull(originBranch); this.sha1 = sha1; } @Nullable static GitHubPRIntegrateLabel parse(String str, GitRepository repository, GeneralOptions generalOptions) { Matcher matcher = LABEL_PATTERN.matcher(str); return matcher.matches() ? new GitHubPRIntegrateLabel(repository, generalOptions, matcher.group(1), Long.parseLong(matcher.group(2)), matcher.group(3), matcher.group(4)) : null; } @Override public String toString() { return String.format("https://github.com/%s/pull/%d from %s%s", projectId, prNumber, originBranch, sha1 != null ? " " + sha1 : ""); } @Override public String mergeMessage(ImmutableList<LabelFinder> labelsToAdd) { return IntegrateLabel.withLabels(String.format("Merge pull request #%d from %s", prNumber, originBranch), labelsToAdd); } @Override public GitRevision getRevision() throws RepoException, ValidationException { String pr = "https://github.com/" + projectId + "/pull/" + prNumber; String repoUrl = "https://github.com/" + projectId; GitRevision gitRevision = GitRepoType.GITHUB.resolveRef(repository, repoUrl, pr, generalOptions, /*describeVersion=*/ false, /*partialFetch*/ false); if (sha1 == null) { return gitRevision; } if (sha1.equals(gitRevision.getSha1())) { return gitRevision; } generalOptions.console().warnFmt( "Pull Request %s has more changes after %s (PR HEAD is %s)." + " Not all changes might be migrated", pr, sha1, gitRevision.getSha1()); return repository.resolveReferenceWithContext(sha1, gitRevision.contextReference(), repoUrl); } public String getProjectId() { return projectId; } public long getPrNumber() { return prNumber; } public String getOriginBranch() { return originBranch; } }