use of com.google.copybara.exception.EmptyChangeException in project copybara by google.
the class WorkflowTest method testIterativeModeProducesNoop.
@Test
public void testIterativeModeProducesNoop() throws Exception {
assertThat(checkIterativeModeWithError(new EmptyChangeException("This was an empty change!"))).hasMessage("Iterative workflow produced no changes in the destination for resolved ref: 3");
console().assertThat().onceInLog(MessageType.WARNING, "Migration of origin revision '2' resulted in an empty change.*").onceInLog(MessageType.WARNING, "Migration of origin revision '3' resulted in an empty change.*");
}
use of com.google.copybara.exception.EmptyChangeException in project copybara by google.
the class Main method runInternal.
/**
* Runs the command and returns the {@link ExitCode}.
*
* <p>This method is also responsible for the exception handling/logging.
*/
private CommandResult runInternal(String[] args, Console console, FileSystem fs) {
CommandEnv commandEnv = null;
CopybaraCmd subcommand = null;
try {
ModuleSet moduleSet = newModuleSet(environment, fs, console);
final MainArguments mainArgs = new MainArguments();
Options options = moduleSet.getOptions();
jCommander = new JCommander(ImmutableList.builder().addAll(options.getAll()).add(mainArgs).build());
jCommander.setProgramName("copybara");
String version = getVersion();
logger.atInfo().log("Copybara version: %s", version);
jCommander.parse(args);
ConfigLoaderProvider configLoaderProvider = newConfigLoaderProvider(moduleSet);
ImmutableMap<String, CopybaraCmd> commands = Maps.uniqueIndex(getCommands(moduleSet, configLoaderProvider, jCommander), CopybaraCmd::name);
// generating the usage info.
for (Map.Entry<String, CopybaraCmd> cmd : commands.entrySet()) {
jCommander.addCommand(cmd.getKey(), cmd.getValue());
}
CommandWithArgs cmdToRun = mainArgs.parseCommand(commands, commands.get("migrate"));
subcommand = cmdToRun.getSubcommand();
initEnvironment(options, cmdToRun.getSubcommand(), ImmutableList.copyOf(args));
GeneralOptions generalOptions = options.get(GeneralOptions.class);
Path baseWorkdir = mainArgs.getBaseWorkdir(generalOptions, generalOptions.getFileSystem());
commandEnv = new CommandEnv(baseWorkdir, options, cmdToRun.getArgs());
generalOptions.console().progressFmt("Running %s", subcommand.name());
// TODO(malcon): Remove this after 2019-09-15, once tested that temp features work.
logger.atInfo().log("Temporary features test: %s", options.get(GeneralOptions.class).isTemporaryFeature("TEST_TEMP_FEATURES", true));
ExitCode exitCode = subcommand.run(commandEnv);
return new CommandResult(exitCode, subcommand, commandEnv);
} catch (CommandLineException | ParameterException e) {
printCauseChain(Level.WARNING, console, args, e);
console.error("Try 'copybara help'.");
return new CommandResult(ExitCode.COMMAND_LINE_ERROR, subcommand, commandEnv);
} catch (RepoException e) {
printCauseChain(Level.SEVERE, console, args, e);
// have to do this hack.
if (e.getCause() instanceof InterruptedException) {
return new CommandResult(ExitCode.INTERRUPTED, subcommand, commandEnv);
}
return new CommandResult(ExitCode.REPOSITORY_ERROR, subcommand, commandEnv);
} catch (EmptyChangeException e) {
// This is not necessarily an error. Maybe the tool was run previously and there are no new
// changes to import.
console.warn(e.getMessage());
return new CommandResult(ExitCode.NO_OP, subcommand, commandEnv);
} catch (ValidationException e) {
printCauseChain(Level.WARNING, console, args, e);
return new CommandResult(ExitCode.CONFIGURATION_ERROR, subcommand, commandEnv);
} catch (IOException e) {
handleUnexpectedError(console, e.getMessage(), args, e);
return new CommandResult(ExitCode.ENVIRONMENT_ERROR, subcommand, commandEnv);
} catch (RuntimeException e) {
// This usually indicates a serious programming error that will require Copybara team
// intervention. Print stack trace without concern for presentation.
e.printStackTrace();
handleUnexpectedError(console, "Unexpected error (please file a bug against copybara): " + e.getMessage(), args, e);
return new CommandResult(ExitCode.INTERNAL_ERROR, subcommand, commandEnv);
}
}
use of com.google.copybara.exception.EmptyChangeException in project copybara by google.
the class GitHubPrOrigin method checkRequiredCheckRuns.
/**
* Check that the PR has a conclusion of "success" for each check_run whose name is in the list
* provided in the `required_check_runs` param
*/
private void checkRequiredCheckRuns(GitHubApi api, String project, PullRequest prData) throws ValidationException, RepoException {
Set<String> requiredCheckRuns = getRequiredCheckRuns();
if (forceImport() || requiredCheckRuns.isEmpty()) {
return;
}
try (ProfilerTask ignore = generalOptions.profiler().start("github_api_get_combined_status")) {
CheckRuns checkRuns = api.getCheckRuns(project, prData.getHead().getSha());
Set<String> requiredButNotPresent = Sets.newHashSet(requiredCheckRuns);
List<CheckRun> passedCheckRuns = checkRuns.getCheckRuns().stream().filter(e -> e.getConclusion().equals("success")).collect(Collectors.toList());
requiredButNotPresent.removeAll(Collections2.transform(passedCheckRuns, CheckRun::getName));
if (!requiredButNotPresent.isEmpty()) {
throw new EmptyChangeException(String.format("Cannot migrate http://github.com/%s/pull/%d because the following check runs " + "have not been passed: %s", project, prData.getNumber(), requiredButNotPresent));
}
}
}
use of com.google.copybara.exception.EmptyChangeException 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.EmptyChangeException 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));
}
}
}
Aggregations