Package com.google.devtools.moe.client.directives

Source Code of com.google.devtools.moe.client.directives.MagicDirective$MagicOptions

// Copyright 2011 The MOE Authors All Rights Reserved.

package com.google.devtools.moe.client.directives;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.devtools.moe.client.AppContext;
import com.google.devtools.moe.client.MoeOptions;
import com.google.devtools.moe.client.MoeProblem;
import com.google.devtools.moe.client.Ui;
import com.google.devtools.moe.client.database.Db;
import com.google.devtools.moe.client.database.Equivalence;
import com.google.devtools.moe.client.database.FileDb;
import com.google.devtools.moe.client.logic.BookkeepingLogic;
import com.google.devtools.moe.client.logic.DetermineMigrationsLogic;
import com.google.devtools.moe.client.logic.OneMigrationLogic;
import com.google.devtools.moe.client.migrations.Migration;
import com.google.devtools.moe.client.migrations.MigrationConfig;
import com.google.devtools.moe.client.parser.Expression;
import com.google.devtools.moe.client.parser.RepositoryExpression;
import com.google.devtools.moe.client.project.InvalidProject;
import com.google.devtools.moe.client.project.ProjectContext;
import com.google.devtools.moe.client.repositories.Revision;
import com.google.devtools.moe.client.testing.DummyDb;
import com.google.devtools.moe.client.writer.DraftRevision;
import com.google.devtools.moe.client.writer.Writer;
import com.google.devtools.moe.client.writer.WritingError;

import org.kohsuke.args4j.Option;

import java.util.List;

/**
* Update the MOE db then perform all migration(s) specified in the MOE config. Repeated
* invocations, then, will result in a state of all pending migrations performed, and all performed
* migrations and new equivalences stored in the db.
*
*/
public class MagicDirective implements Directive {

  private final MagicOptions options = new MagicOptions();

  public MagicDirective() {}

  @Override
  public MagicOptions getFlags() {
    return options;
  }

  @Override
  public int perform() {
    ProjectContext context;
    try {
      context = AppContext.RUN.contextFactory.makeProjectContext(options.configFilename);
    } catch (InvalidProject e) {
      AppContext.RUN.ui.error(e, "Error creating project");
      return 1;
    }

    Db db;
    if (options.dbLocation.equals("dummy")) {
      db = new DummyDb(true);
    } else {
      // TODO(user): also allow for url dbLocation types
      try {
        db = FileDb.makeDbFromFile(options.dbLocation);
      } catch (MoeProblem e) {
        AppContext.RUN.ui.error(e, "Error creating DB");
        return 1;
      }
    }

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

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

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

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

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

      List<Migration> migrations =
          DetermineMigrationsLogic.determineMigrations(context, migrationConfig, db);

      if (migrations.isEmpty()) {
        AppContext.RUN.ui.info("No pending revisions to migrate for " + migrationName);
        continue;
      }

      Equivalence 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 " + toRe + ": " + e);
      }

      DraftRevision dr = null;
      Revision lastMigratedRevision = null;
      if (lastEq != null) {
        lastMigratedRevision = lastEq.getRevisionForRepository(migrationConfig.getFromRepository());
      }

      for (Migration m : migrations) {
        // 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());

        Ui.Task oneMigrationTask = AppContext.RUN.ui.pushTask(
            "perform_individual_migration",
            String.format("Performing individual migration '%s'", m.toString()));
        dr = OneMigrationLogic.migrate(m, context, toWriter, referenceToCodebase);
        lastMigratedRevision = m.fromRevisions.get(m.fromRevisions.size() - 1);
        AppContext.RUN.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();
      AppContext.RUN.ui.popTaskAndPersist(migrationTask, toWriter.getRoot());
    }

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

    return 0;
  }

  static class MagicOptions extends MoeOptions {
    @Option(name = "--config_file", required = true,
            usage = "Location of MOE config file")
    String configFilename = "";
    @Option(name = "--db", required = true,
            usage = "Location of MOE database")
    String dbLocation = "";
    @Option(name = "--migration", required = false,
            usage = "Migrations to perform; can include multiple --migration options")
    List<String> migrations = Lists.newArrayList();
  }
}
TOP

Related Classes of com.google.devtools.moe.client.directives.MagicDirective$MagicOptions

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.