Пример #1
0
 @Override
 public void printPushMessage() {
   Ui ui = AppContext.RUN.ui;
   ui.info("=====");
   ui.info("MOE changes have been committed to a clone at " + getRoot());
   ui.info("Changes may have created a new head. Merge heads if needed, then push to remote.");
   ui.info("For example:");
   ui.info("hg heads");
   ui.info("hg merge  # if more than one head");
   ui.info("hg commit -m 'MOE merge'");
   ui.info("hg push");
   ui.info("=====");
 }
Пример #2
0
  @Override
  protected int performDirectiveBehavior() {
    Db db = dbFactory.load(dbLocation);

    List<String> migrationNames =
        ImmutableList.copyOf(
            migrations.isEmpty() ? context().migrationConfigs().keySet() : migrations);

    Set<String> skipRevisions = ImmutableSet.copyOf(this.skipRevisions);

    if (bookkeeper.bookkeep(db, context()) != 0) {
      // Bookkeeping has failed, so fail here as well.
      return 1;
    }

    ImmutableList.Builder<String> migrationsMadeBuilder = ImmutableList.builder();

    for (String migrationName : migrationNames) {
      Task migrationTask =
          ui.pushTask("perform_migration", "Performing migration '%s'", migrationName);

      MigrationConfig migrationConfig = context().migrationConfigs().get(migrationName);
      if (migrationConfig == null) {
        ui.error("No migration found with name %s", migrationName);
        continue;
      }

      RepositoryType fromRepo = context.getRepository(migrationConfig.getFromRepository());
      List<Migration> migrations =
          migrator.findMigrationsFromEquivalency(fromRepo, migrationConfig, db);

      if (migrations.isEmpty()) {
        ui.info("No pending revisions to migrate for %s", migrationName);
        continue;
      }

      RepositoryEquivalence lastEq = migrations.get(0).sinceEquivalence();
      // toRe represents toRepo at the revision of last equivalence with fromRepo.
      RepositoryExpression toRe = new RepositoryExpression(migrationConfig.getToRepository());
      if (lastEq != null) {
        toRe =
            toRe.atRevision(
                lastEq.getRevisionForRepository(migrationConfig.getToRepository()).revId());
      }

      Writer toWriter;
      try {
        toWriter = toRe.createWriter(context());
      } catch (WritingError e) {
        throw new MoeProblem("Couldn't create local repo %s: %s", toRe, e);
      }

      DraftRevision dr = null;
      int currentlyPerformedMigration = 1; // To display to users.
      for (Migration migration : migrations) {

        // First check if we should even do this migration at all.
        int skipped = 0;
        for (Revision revision : migration.fromRevisions()) {
          if (skipRevisions.contains(revision.toString())) {
            skipped++;
          }
        }
        if (skipped > 0) {
          if (skipped != migration.fromRevisions().size()) {
            throw new MoeProblem(
                "Cannot skip subset of revisions in a single migration: " + migration);
          }
          ui.info(
              String.format(
                  "Skipping %s/%s migration `%s`",
                  currentlyPerformedMigration++, migrations.size(), migration));
          continue;
        }

        // For each migration, the reference to-codebase for inverse translation is the Writer,
        // since it contains the latest changes (i.e. previous migrations) to the to-repository.
        Expression referenceToCodebase =
            new RepositoryExpression(migrationConfig.getToRepository())
                .withOption("localroot", toWriter.getRoot().getAbsolutePath());

        Task oneMigrationTask =
            ui.pushTask(
                "perform_individual_migration",
                "Performing %s/%s migration '%s'",
                currentlyPerformedMigration++,
                migrations.size(),
                migration);

        Revision mostRecentFromRev =
            migration.fromRevisions().get(migration.fromRevisions().size() - 1);
        Codebase fromCodebase;
        try {
          String toProjectSpace =
              context.config().getRepositoryConfig(migration.toRepository()).getProjectSpace();
          fromCodebase =
              new RepositoryExpression(migration.fromRepository())
                  .atRevision(mostRecentFromRev.revId())
                  .translateTo(toProjectSpace)
                  .withReferenceToCodebase(referenceToCodebase)
                  .createCodebase(context);

        } catch (CodebaseCreationError e) {
          throw new MoeProblem(e.getMessage());
        }

        RepositoryType fromRepoType = context().getRepository(migrationConfig.getFromRepository());
        ScrubberConfig scrubber =
            context
                .config()
                .findScrubberConfig(migration.fromRepository(), migration.toRepository());
        dr =
            migrator.migrate(
                migration,
                fromRepoType,
                fromCodebase,
                mostRecentFromRev,
                migrationConfig.getMetadataScrubberConfig(),
                scrubber,
                toWriter,
                referenceToCodebase);

        ui.popTask(oneMigrationTask, "");
      }

      // TODO(user): Add properly formatted one-DraftRevison-per-Migration message for svn.
      migrationsMadeBuilder.add(
          String.format(
              "%s in repository %s", dr.getLocation(), migrationConfig.getToRepository()));
      toWriter.printPushMessage();
      ui.popTaskAndPersist(migrationTask, toWriter.getRoot());
    }

    List<String> migrationsMade = migrationsMadeBuilder.build();
    if (migrationsMade.isEmpty()) {
      ui.info("No migrations made.");
    } else {
      ui.info("Created Draft Revisions:\n" + Joiner.on("\n").join(migrationsMade));
    }

    return 0;
  }