changeset 29:798e750e4f26

first version of agent side checkout
author Pavel.Sher
date Wed, 23 Jul 2008 15:23:05 +0400
parents a7cab5083ada
children 007c63ae45b0
files mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialAgentSideVcsSupport.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java
diffstat 3 files changed, 96 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialAgentSideVcsSupport.java	Wed Jul 23 09:32:14 2008 +0400
+++ b/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialAgentSideVcsSupport.java	Wed Jul 23 15:23:05 2008 +0400
@@ -17,17 +17,101 @@
 
 import jetbrains.buildServer.agent.BuildProgressLogger;
 import jetbrains.buildServer.agent.vcs.CheckoutOnAgentVcsSupport;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.*;
+import jetbrains.buildServer.util.FileUtil;
 import jetbrains.buildServer.vcs.IncludeRule;
 import jetbrains.buildServer.vcs.VcsException;
 import jetbrains.buildServer.vcs.VcsRoot;
+import org.jetbrains.annotations.NotNull;
 
 import java.io.File;
+import java.io.IOException;
 
 public class MercurialAgentSideVcsSupport implements CheckoutOnAgentVcsSupport {
-  public void updateSources(final BuildProgressLogger buildProgressLogger, final File file, final VcsRoot vcsRoot, final String s, final IncludeRule includeRule) throws VcsException {
+  public void updateSources(@NotNull final BuildProgressLogger logger, @NotNull final File workingDir, @NotNull final VcsRoot vcsRoot, @NotNull final String version, final IncludeRule includeRule) throws VcsException {
+    if (includeRule.getTo() != null) {
+      throw new VcsException("Include rule with mapping is not supported: " + includeRule.toString());
+    }
+
+    Settings settings = new Settings(workingDir, vcsRoot);
+    settings.setWorkingDir(workingDir);
+    if (settings.hasCopyOfRepository()) {
+      // execute pull command
+      logger.message("Repository in working directory found, start pulling changes");
+      PullCommand pc = new PullCommand(settings);
+      pc.execute();
+      logger.message("Changes successfully pulled");
+    } else {
+      // execute clone command
+      logger.message("No repository in working directory found, start cloning repository to temporary folder");
+      File parentDir = cloneRepository(settings, version);
+      logger.message("Repository successfly cloned to: " + parentDir.getAbsolutePath());
+      logger.message("Moving repository to working directory: " + workingDir.getAbsolutePath());
+      if (!moveDir(parentDir, workingDir)) {
+        File hgDir = new File(workingDir, ".hg");
+        if (hgDir.isDirectory()) {
+          FileUtil.delete(hgDir);
+        }
+        throw new VcsException("Failed to move directory content: " + parentDir.getAbsolutePath() + " to: " + workingDir.getAbsolutePath());
+      }
+
+      logger.message("Repository successfully moved to working directory: " + workingDir.getAbsolutePath());
+
+      logger.message("Updating working directory from the local repository copy");
+      UpdateCommand uc = new UpdateCommand(settings);
+      uc.execute();
+      logger.message("Working directory updated successfully");
+    }
   }
 
+  private File cloneRepository(final Settings settings, final String version) throws VcsException {
+    File tempDir = null;
+    try {
+      tempDir = new File(FileUtil.createTempDirectory("hg", "clone"), "hg");
+    } catch (IOException e) {
+      throw new VcsException("Failed to create temp directory: " + e.getLocalizedMessage());
+    }
+
+    CloneCommand cc = new CloneCommand(settings);
+    cc.setDestDir(tempDir.getAbsolutePath());
+
+    ChangeSet cs = new ChangeSet(version);
+    cc.setToId(cs.getId());
+
+    cc.setUpdateWorkingDir(false);
+    cc.execute();
+    return tempDir;
+  }
+
+  @NotNull
   public String getName() {
     return Constants.VCS_NAME;
   }
+
+  /**
+   * Moves files from one directory to another with all subdirectories.
+   * Removes old directory if it became empty.
+   */
+  private static boolean moveDir(File oldDir, File newDir) {
+    // both old and new directories exist
+    boolean moveSuccessful = true;
+    final File[] files = oldDir.listFiles();
+    if (files != null) {
+      for (File file: files) {
+        if (file.isFile()) {
+          if (!file.renameTo(new File(newDir, file.getName()))) {
+            moveSuccessful = false;
+          }
+        } else if (!moveDir(file, new File(newDir, file.getName()))) {
+          moveSuccessful = false;
+        }
+      }
+    }
+
+    if (moveSuccessful) {
+      FileUtil.deleteIfEmpty(oldDir);
+    }
+
+    return moveSuccessful;
+  }
 }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java	Wed Jul 23 09:32:14 2008 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java	Wed Jul 23 15:23:05 2008 +0400
@@ -85,6 +85,15 @@
     return getDefaultWorkDir(myWorkFolderParentDir, myRepository);
   }
 
+  /**
+   * Returns true if current working directory contains copy of repository (contains .hg directory)
+   * @return see above
+   */
+  public boolean hasCopyOfRepository() {
+    // need better way to check that repository copy is ok
+    return getWorkingDir().isDirectory() && new File(getWorkingDir(), ".hg").isDirectory();
+  }
+
   public static String DEFAULT_WORK_DIR_PREFIX = "hg_";
 
   private static File getDefaultWorkDir(@NotNull File workFolderParentDir, @NotNull String repPath) {
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Wed Jul 23 09:32:14 2008 +0400
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Wed Jul 23 15:23:05 2008 +0400
@@ -54,7 +54,6 @@
  * <p>Checkout on agent mode is not yet supported too.
  */
 public class MercurialVcsSupport extends VcsSupport implements CollectChangesByIncludeRule {
-  private ServerPaths myServerPaths;
   private ConcurrentMap<String, Lock> myWorkDirLocks= new ConcurrentHashMap<String, Lock>();
   private static final int OLD_WORK_DIRS_CLEANUP_PERIOD = 600;
   private VcsManager myVcsManager;
@@ -64,7 +63,6 @@
                              @NotNull ServerPaths paths,
                              @NotNull SBuildServer server) {
     vcsManager.registerVcsSupport(this);
-    myServerPaths = paths;
     myVcsManager = vcsManager;
     server.getExecutor().scheduleAtFixedRate(new Runnable() {
       public void run() {
@@ -369,7 +367,7 @@
     File workDir = settings.getWorkingDir();
     lockWorkDir(workDir);
     try {
-      if (hasRepositoryCopy(workDir)) {
+      if (settings.hasCopyOfRepository()) {
         // update
         PullCommand pull = new PullCommand(settings);
         pull.execute();
@@ -406,13 +404,8 @@
     return lock;
   }
 
-  private boolean hasRepositoryCopy(final File workDir) {
-    // need better way to check that repository copy is ok
-    return workDir.isDirectory() && new File(workDir, ".hg").isDirectory();
-  }
-
   private void removeOldWorkFolders() {
-    File workFoldersParent = new File(myServerPaths.getCachesDir(), "mercurial");
+    File workFoldersParent = new File(myDefaultWorkFolderParent, "mercurial");
     if (!workFoldersParent.isDirectory()) return;
 
     Set<File> workDirs = new HashSet<File>();