Package com.google.devtools.moe.client.svn

Source Code of com.google.devtools.moe.client.svn.SvnWriter

// Copyright 2011 The MOE Authors All Rights Reserved.

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

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import com.google.devtools.moe.client.AppContext;
import com.google.devtools.moe.client.CommandRunner;
import com.google.devtools.moe.client.FileSystem;
import com.google.devtools.moe.client.MoeProblem;
import com.google.devtools.moe.client.Utils;
import com.google.devtools.moe.client.codebase.Codebase;
import com.google.devtools.moe.client.project.RepositoryConfig;
import com.google.devtools.moe.client.repositories.Revision;
import com.google.devtools.moe.client.repositories.RevisionMetadata;
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 java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;

/**
* {@link Writer} for svn.
*
* @author dbentley@google.com (Daniel Bentley)
*/
public class SvnWriter implements Writer {

  private final RepositoryConfig config;
  private final Revision revision;
  private final File rootDirectory;

  public SvnWriter(RepositoryConfig config, Revision revision, File tempDir) {
    this.config = config;
    this.revision = revision;
    this.rootDirectory = tempDir;
  }

  @Override
  public File getRoot() {
    return rootDirectory;
  }

  public void checkOut() {
    try {
      SvnRepository.runSvnCommand(
          ImmutableList.of(
              "co", "-r", revision.revId, config.getUrl(), rootDirectory.getAbsolutePath()), "");
    } catch (CommandRunner.CommandException e) {
      throw new MoeProblem("Could not check out from svn: " + e.stderr);
    }
  }

  // TODO(user): Handle separate_revisions! (an 'svn commit' per exported change)
  @Override
  public DraftRevision putCodebase(Codebase c) throws WritingError {
    c.checkProjectSpace(config.getProjectSpace());

    // Filter out files that either start with .svn or have .svn after a slash, plus the repo
    // config's ignore_file_res.
    List<String> ignoreFilePatterns = ImmutableList.<String>builder()
        .addAll(config.getIgnoreFileRes())
        .add("(^|.*/)\\.svn(/.*|$)")
        .build();

    Set<String> codebaseFiles = c.getRelativeFilenames();
    Set<String> writerFiles = Utils.filterByRegEx(
        Utils.makeFilenamesRelative(AppContext.RUN.fileSystem.findFiles(rootDirectory),
                                    rootDirectory),
        ignoreFilePatterns);
    Set<String> union = Sets.union(codebaseFiles, writerFiles);

    for (String filename : union) {
      putFile(filename, c);
    }

    return new SvnDraftRevision(rootDirectory);
  }

  @Override
  public DraftRevision putCodebase(Codebase c, RevisionMetadata rm) throws WritingError {
    DraftRevision dr = putCodebase(c);
    // Generate a shell script to commit repo with author and description
    String script = String.format("svn update%n" +
                                  "svn commit -m \"%s\"%n" +
                                  "svn propset -r HEAD svn:author \"%s\" --revprop",
                                  rm.description, rm.author);
    Utils.makeShellScript(script, rootDirectory.getAbsolutePath() + "/svn_commit.sh");

    AppContext.RUN.ui.info(String.format("To submit, run: cd %s && ./svn_commit.sh && cd -",
                                         rootDirectory.getAbsolutePath()));
    return dr;
  }

  /**
   * Put file from c into this writer. (Helper function.)
   *
   * @param relativeFilename  the filename to put
   * @param c  the Codebase to take the file from
   */
  void putFile(String relativeFilename, Codebase c) {
    try {
      FileSystem fs = AppContext.RUN.fileSystem;
      File dest = new File(rootDirectory.getAbsolutePath(), relativeFilename);
      File src = c.getFile(relativeFilename);
      boolean srcExists = fs.exists(src);
      boolean destExists = fs.exists(dest);

      boolean srcExecutable = fs.isExecutable(src);
      boolean destExecutable = fs.isExecutable(dest);

      if (!srcExists && !destExists) {
        throw new MoeProblem(
            String.format("Neither src nor dests exists. Unreachable code:%n%s%n%s%n%s",
                          relativeFilename, src, dest));
      }

      if (!srcExists) {
        SvnRepository.runSvnCommand(
            ImmutableList.of("rm", relativeFilename), rootDirectory.getAbsolutePath());
        // TODO(dbentley): handle newly-empty directories
        return;
      }

      try {
        fs.makeDirsForFile(dest);
        fs.copyFile(src, dest);
      } catch (IOException e) {
        throw new MoeProblem(e.getMessage());
      }

      if (!destExists) {
        SvnRepository.runSvnCommand(
            ImmutableList.of("add", "--parents", relativeFilename),
            rootDirectory.getAbsolutePath());
      }

      String mimeType = guessMimeType(relativeFilename);
      if (mimeType != null) {
        try {
          SvnRepository.runSvnCommand(
              ImmutableList.of("propset", "svn:mime-type", mimeType, relativeFilename),
              rootDirectory.getAbsolutePath());
        } catch (CommandRunner.CommandException e) {
          // If the mime type setting fails, it's not really a big deal.
          // Just log it and keep going.
          AppContext.RUN.ui.info(
              String.format("Error setting mime-type for %s", relativeFilename));
        }
      }

      if (destExecutable != srcExecutable) {
        if (srcExecutable) {
          SvnRepository.runSvnCommand(
              ImmutableList.of("propset", "svn:executable", "*", relativeFilename),
              rootDirectory.getAbsolutePath());
        } else {
          SvnRepository.runSvnCommand(
              ImmutableList.of("propdel", "svn:executable", relativeFilename),
              rootDirectory.getAbsolutePath());
        }
      }
    } catch (CommandRunner.CommandException e) {
      throw new MoeProblem("problem occurred while running svn: " + e.stderr);
    }
  }

  private String guessMimeType(String relativeFilename) {
    if (relativeFilename.endsWith(".js")) {
      return "text/javascript";
    } else if (relativeFilename.endsWith(".css")) {
      return "text/css";
    } else if (relativeFilename.endsWith(".html")) {
      return "text/html";
    } else if (relativeFilename.endsWith(".jpg")) {
      return "image/jpeg";
    } else if (relativeFilename.endsWith(".png")) {
      return "image/png";
    } else if (relativeFilename.endsWith(".gif")) {
      return "image/gif";
    }
    return null;
  }

  @Override
  public void printPushMessage() {
    // TODO(user): Figure out workflow for MOE migrations/local commits in svn.
  }
}
TOP

Related Classes of com.google.devtools.moe.client.svn.SvnWriter

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.