Search in sources :

Example 91 with ValidationException

use of com.google.copybara.exception.ValidationException in project copybara by google.

the class PatchingOptionsTest method applyExcludedWithForcePatch.

@Test
public void applyExcludedWithForcePatch() throws Exception {
    forceUseGnuPatch();
    ValidationException e = assertThrows(ValidationException.class, () -> checkApplyExcluded());
    assertThat(e).hasMessageThat().contains("--patch-skip-version-check is incompatible with patch transformations that uses" + " excluded paths");
}
Also used : ValidationException(com.google.copybara.exception.ValidationException) Test(org.junit.Test)

Example 92 with ValidationException

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) {

        /**
         * 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 = startRevision.associatedLabels().get(GITHUB_BASE_BRANCH_SHA1);
            Preconditions.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() {
            return new GitHubEndPoint(githubOptions, url);
        }

        /**
         * 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 {
            if (!useMerge) {
                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);
            }
        }

        @Nullable
        @Override
        public String getGroupIdentity(GitRevision rev) throws RepoException {
            return rev.associatedLabels().get(GITHUB_PR_NUMBER_LABEL);
        }
    };
}
Also used : Path(java.nio.file.Path) Iterables(com.google.common.collect.Iterables) Origin(com.google.copybara.Origin) ValidationException.checkCondition(com.google.copybara.exception.ValidationException.checkCondition) RepoException(com.google.copybara.exception.RepoException) Collections2(com.google.common.collect.Collections2) SubmoduleStrategy(com.google.copybara.git.GitOrigin.SubmoduleStrategy) Matcher(java.util.regex.Matcher) ImmutableList(com.google.common.collect.ImmutableList) Change(com.google.copybara.Change) BaselinesWithoutLabelVisitor(com.google.copybara.BaselinesWithoutLabelVisitor) CannotResolveRevisionException(com.google.copybara.exception.CannotResolveRevisionException) Endpoint(com.google.copybara.Endpoint) Issue(com.google.copybara.git.github.api.Issue) Splitter(com.google.common.base.Splitter) GeneralOptions(com.google.copybara.GeneralOptions) Path(java.nio.file.Path) Nullable(javax.annotation.Nullable) ImmutableSetMultimap(com.google.common.collect.ImmutableSetMultimap) GitLogEntry(com.google.copybara.git.GitRepository.GitLogEntry) Label(com.google.copybara.git.github.api.Issue.Label) ProfilerTask(com.google.copybara.profiler.Profiler.ProfilerTask) Uninterruptibles(com.google.common.util.concurrent.Uninterruptibles) ImmutableMap(com.google.common.collect.ImmutableMap) EmptyChangeException(com.google.copybara.exception.EmptyChangeException) CharMatcher(com.google.common.base.CharMatcher) ValidationException(com.google.copybara.exception.ValidationException) ReaderImpl(com.google.copybara.git.GitOrigin.ReaderImpl) Set(java.util.Set) Console(com.google.copybara.util.console.Console) Sets(com.google.common.collect.Sets) GithubUtil.getProjectNameFromUrl(com.google.copybara.git.github.util.GithubUtil.getProjectNameFromUrl) TimeUnit(java.util.concurrent.TimeUnit) Authoring(com.google.copybara.authoring.Authoring) Glob(com.google.copybara.util.Glob) PullRequest(com.google.copybara.git.github.api.PullRequest) GithubUtil.asGithubUrl(com.google.copybara.git.github.util.GithubUtil.asGithubUrl) Optional(java.util.Optional) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) GithubUtil(com.google.copybara.git.github.util.GithubUtil) Collections(java.util.Collections) GithubPrUrl(com.google.copybara.git.github.util.GithubUtil.GithubPrUrl) ReaderImpl(com.google.copybara.git.GitOrigin.ReaderImpl) Change(com.google.copybara.Change) RepoException(com.google.copybara.exception.RepoException) BaselinesWithoutLabelVisitor(com.google.copybara.BaselinesWithoutLabelVisitor) EmptyChangeException(com.google.copybara.exception.EmptyChangeException) Nullable(javax.annotation.Nullable) GitLogEntry(com.google.copybara.git.GitRepository.GitLogEntry)

Example 93 with ValidationException

use of com.google.copybara.exception.ValidationException in project copybara by google.

the class WorkflowRunHelper method doMigrate.

private ImmutableList<DestinationEffect> doMigrate(O rev, @Nullable O lastRev, Console processConsole, Metadata metadata, Changes changes, @Nullable String destinationBaseline, @Nullable O changeIdentityRevision) throws IOException, RepoException, ValidationException {
    Path checkoutDir = workdir.resolve("checkout");
    try (ProfilerTask ignored = profiler().start("prepare_workdir")) {
        processConsole.progress("Cleaning working directory");
        if (Files.exists(workdir)) {
            FileUtil.deleteRecursively(workdir);
        }
        Files.createDirectories(checkoutDir);
    }
    processConsole.progress("Checking out the change");
    try (ProfilerTask ignored = profiler().start("origin.checkout", profiler().taskType(workflow.getOrigin().getType()))) {
        originReader.checkout(rev, checkoutDir);
    }
    // Remove excluded origin files.
    PathMatcher originFiles = workflow.getOriginFiles().relativeTo(checkoutDir);
    processConsole.progress("Removing excluded origin files");
    int deleted = FileUtil.deleteFilesRecursively(checkoutDir, FileUtil.notPathMatcher(originFiles));
    if (deleted != 0) {
        processConsole.info(String.format("Removed %d files from workdir that do not match origin_files", deleted));
    }
    Path originCopy = null;
    if (workflow.getReverseTransformForCheck() != null) {
        try (ProfilerTask ignored = profiler().start("reverse_copy")) {
            workflow.getConsole().progress("Making a copy or the workdir for reverse checking");
            originCopy = Files.createDirectories(workdir.resolve("origin"));
            FileUtil.copyFilesRecursively(checkoutDir, originCopy, FAIL_OUTSIDE_SYMLINKS);
        }
    }
    TransformWork transformWork = new TransformWork(checkoutDir, metadata, changes, workflow.getConsole(), new MigrationInfo(getOriginLabelName(), writer), resolvedRef).withLastRev(lastRev).withCurrentRev(rev);
    try (ProfilerTask ignored = profiler().start("transforms")) {
        workflow.getTransformation().transform(transformWork);
    }
    if (workflow.getReverseTransformForCheck() != null) {
        workflow.getConsole().progress("Checking that the transformations can be reverted");
        Path reverse;
        try (ProfilerTask ignored = profiler().start("reverse_copy")) {
            reverse = Files.createDirectories(workdir.resolve("reverse"));
            FileUtil.copyFilesRecursively(checkoutDir, reverse, FAIL_OUTSIDE_SYMLINKS);
        }
        try (ProfilerTask ignored = profiler().start("reverse_transform")) {
            workflow.getReverseTransformForCheck().transform(new TransformWork(reverse, new Metadata(transformWork.getMessage(), transformWork.getAuthor()), changes, workflow.getConsole(), new MigrationInfo(/*originLabel=*/
            null, null), resolvedRef));
        }
        String diff;
        try {
            diff = new String(DiffUtil.diff(originCopy, reverse, workflow.isVerbose(), workflow.getGeneralOptions().getEnvironment()), StandardCharsets.UTF_8);
        } catch (InsideGitDirException e) {
            throw new ValidationException("Cannot use 'reversible_check = True' because Copybara temporary directory (%s) is" + " inside a git directory (%s). Please remove the git repository or use %s flag.", e.getPath(), e.getGitDirPath(), OUTPUT_ROOT_FLAG);
        }
        if (!diff.trim().isEmpty()) {
            workflow.getConsole().error("Non reversible transformations:\n" + DiffUtil.colorize(workflow.getConsole(), diff));
            throw new ValidationException("Workflow '%s' is not reversible", workflow.getName());
        }
    }
    workflow.getConsole().progress("Checking that destination_files covers all files in transform result");
    new ValidateDestinationFilesVisitor(workflow.getDestinationFiles(), checkoutDir).verifyFilesToWrite();
    // TODO(malcon): Pass metadata object instead
    TransformResult transformResult = new TransformResult(checkoutDir, rev, transformWork.getAuthor(), transformWork.getMessage(), resolvedRef, workflow.getName(), changes, rawSourceRef);
    if (destinationBaseline != null) {
        transformResult = transformResult.withBaseline(destinationBaseline);
    }
    transformResult = transformResult.withAskForConfirmation(workflow.isAskForConfirmation()).withIdentity(workflow.getMigrationIdentity(changeIdentityRevision, transformWork));
    ImmutableList<DestinationEffect> result;
    try (ProfilerTask ignored = profiler().start("destination.write", profiler().taskType(workflow.getDestination().getType()))) {
        result = writer.write(transformResult, processConsole);
    }
    Verify.verifyNotNull(result, "Destination returned a null result.");
    Verify.verify(!result.isEmpty(), "Destination " + writer + " returned an empty set of effects");
    return result;
}
Also used : Path(java.nio.file.Path) ValidationException(com.google.copybara.exception.ValidationException) InsideGitDirException(com.google.copybara.util.InsideGitDirException) PathMatcher(java.nio.file.PathMatcher) ProfilerTask(com.google.copybara.profiler.Profiler.ProfilerTask)

Example 94 with ValidationException

use of com.google.copybara.exception.ValidationException in project copybara by google.

the class WorkflowRunHelper method migrate.

/**
 * Performs a full migration, including checking out files from the origin, deleting excluded
 * files, transforming the code, and writing to the destination. This writes to the destination
 * exactly once.
 *
 * @param rev revision to the version which will be written to the destination
 * @param lastRev last revision that was migrated
 * @param processConsole console to use to print progress messages
 * @param metadata metadata of the change to be migrated
 * @param changes changes included in this migration
 * @param destinationBaseline it not null, use this baseline in the destination
 * @param changeIdentityRevision the revision to be used for computing the change identity
 */
ImmutableList<DestinationEffect> migrate(O rev, @Nullable O lastRev, Console processConsole, Metadata metadata, Changes changes, @Nullable String destinationBaseline, @Nullable O changeIdentityRevision) throws IOException, RepoException, ValidationException {
    ImmutableList<DestinationEffect> effects = ImmutableList.of();
    boolean callPerMigrationHook = true;
    try {
        eventMonitor().onChangeMigrationStarted(new ChangeMigrationStartedEvent());
        effects = doMigrate(rev, lastRev, processConsole, metadata, changes, destinationBaseline, changeIdentityRevision);
        return effects;
    } catch (EmptyChangeException empty) {
        effects = ImmutableList.of(new DestinationEffect(Type.NOOP, empty.getMessage(), changes.getCurrent(), /*destinationRef=*/
        null, ImmutableList.of()));
        throw empty;
    } catch (ValidationException | IOException | RepoException | RuntimeException e) {
        effects = ImmutableList.of(new DestinationEffect(Type.ERROR, "Errors happened during the migration", changes.getCurrent(), /*destinationRef=*/
        null, ImmutableList.of(e.getMessage() != null ? e.getMessage() : e.toString())));
        callPerMigrationHook = e instanceof ValidationException;
        throw e;
    } finally {
        eventMonitor().onChangeMigrationFinished(new ChangeMigrationFinishedEvent(effects));
        if (callPerMigrationHook) {
            FinishHookContext finishHookContext = new FinishHookContext(getOriginReader().getFeedbackEndPoint(), getDestinationWriter().getFeedbackEndPoint(), effects, resolvedRef, new SkylarkConsole(getConsole()));
            try (ProfilerTask ignored = profiler().start("finish_hooks")) {
                for (Action action : workflow.getAfterMigrationActions()) {
                    try (ProfilerTask ignored2 = profiler().start(action.getName())) {
                        logger.log(Level.INFO, "Running after migration hook: " + action.getName());
                        action.run(finishHookContext);
                    }
                }
            }
        }
    }
}
Also used : Action(com.google.copybara.feedback.Action) ValidationException(com.google.copybara.exception.ValidationException) ChangeMigrationFinishedEvent(com.google.copybara.monitor.EventMonitor.ChangeMigrationFinishedEvent) FinishHookContext(com.google.copybara.feedback.FinishHookContext) IOException(java.io.IOException) RepoException(com.google.copybara.exception.RepoException) SkylarkConsole(com.google.copybara.transform.SkylarkConsole) ProfilerTask(com.google.copybara.profiler.Profiler.ProfilerTask) ChangeMigrationStartedEvent(com.google.copybara.monitor.EventMonitor.ChangeMigrationStartedEvent) EmptyChangeException(com.google.copybara.exception.EmptyChangeException)

Example 95 with ValidationException

use of com.google.copybara.exception.ValidationException in project copybara by google.

the class Copybara method validate.

/**
 * Validates that the configuration is correct and that there is a valid migration specified by
 * {@code migrationName}.
 *
 * <p>Note that, besides validating the specific migration, all the configuration will be
 * validated syntactically.
 */
public boolean validate(Options options, ConfigLoader<?> configLoader, String migrationName) throws IOException {
    Console console = options.get(GeneralOptions.class).console();
    ArrayList<Message> messages = new ArrayList<>();
    try {
        Config config = configLoader.loadConfig(options, console);
        messages.addAll(validateConfig(config, migrationName));
    } catch (ValidationException e) {
        // The validate subcommand should not throw Validation exceptions but log a result
        StringBuilder error = new StringBuilder(e.getMessage()).append("\n");
        Throwable cause = e.getCause();
        while (cause != null) {
            error.append("  CAUSED BY: ").append(cause.getMessage()).append("\n");
            cause = cause.getCause();
        }
        messages.add(Message.error(error.toString()));
    }
    messages.forEach(message -> message.printTo(console));
    boolean hasNoErrors = messages.stream().noneMatch(message -> message.getType() == MessageType.ERROR);
    if (hasNoErrors) {
        console.info(String.format("Configuration '%s' is valid.", configLoader.location()));
    } else {
        console.error(String.format("Configuration '%s' is invalid.", configLoader.location()));
    }
    return hasNoErrors;
}
Also used : ValidationException(com.google.copybara.exception.ValidationException) Message(com.google.copybara.util.console.Message) Config(com.google.copybara.config.Config) Console(com.google.copybara.util.console.Console) ArrayList(java.util.ArrayList)

Aggregations

ValidationException (com.google.copybara.exception.ValidationException)178 Test (org.junit.Test)125 Path (java.nio.file.Path)33 RepoException (com.google.copybara.exception.RepoException)29 NonReversibleValidationException (com.google.copybara.exception.NonReversibleValidationException)26 ImmutableList (com.google.common.collect.ImmutableList)21 IOException (java.io.IOException)19 Console (com.google.copybara.util.console.Console)16 EmptyChangeException (com.google.copybara.exception.EmptyChangeException)14 DummyRevision (com.google.copybara.testing.DummyRevision)14 Glob (com.google.copybara.util.Glob)14 ProfilerTask (com.google.copybara.profiler.Profiler.ProfilerTask)13 Nullable (javax.annotation.Nullable)13 Migration (com.google.copybara.config.Migration)11 TestingConsole (com.google.copybara.util.console.testing.TestingConsole)11 Iterables (com.google.common.collect.Iterables)10 Change (com.google.copybara.Change)10 CannotResolveRevisionException (com.google.copybara.exception.CannotResolveRevisionException)10 Collectors (java.util.stream.Collectors)10 WriterContext (com.google.copybara.WriterContext)9