changeset 586:aa515fa1f626

Clean patch uses subrepo mirrors on the server
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Mon, 15 Apr 2013 16:53:47 +0400
parents d1203382ce76
children e77ef6cd4ddb
files mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SubrepoPatchTest.java mercurial-tests/src/testng.xml mercurial-tests/testData/clean_patch_recursive_subrepos/after/.hgsub mercurial-tests/testData/clean_patch_recursive_subrepos/after/.hgsubstate mercurial-tests/testData/clean_patch_recursive_subrepos/after/a mercurial-tests/testData/clean_patch_recursive_subrepos/after/r2/.hgsub mercurial-tests/testData/clean_patch_recursive_subrepos/after/r2/.hgsubstate mercurial-tests/testData/clean_patch_recursive_subrepos/after/r2/c mercurial-tests/testData/clean_patch_recursive_subrepos/after/r2/r2/b
diffstat 11 files changed, 130 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Thu Apr 11 21:30:50 2013 +0400
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Mon Apr 15 16:53:47 2013 +0400
@@ -34,6 +34,7 @@
 import java.io.FileFilter;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.net.URISyntaxException;
 import java.util.*;
 
 import static java.util.Collections.emptyMap;
@@ -260,7 +261,8 @@
     File tempDir = HgFileUtil.createTempDir();
     try {
       HgRepo repo = createRepo(root);
-      if (repo.hasSubreposAtRevision(toVer)) {
+      Map<String, SubRepo> subrepos = repo.getSubrepositories(toVer);
+      if (!subrepos.isEmpty()) {
         Loggers.VCS.debug("Repository '" + root.getRepository() + "' has submodules at revision " + toVer.getId() + ", use 'hg clone' to build clean patch");
         File mirrorDir = getWorkingDir(root);
         HgRepo cloneOfTheMirror = createRepo(root, tempDir);
@@ -270,6 +272,7 @@
                 .useUncompressedTransfer(false)
                 .call();
         cloneOfTheMirror.setDefaultPath(root.getRepository());
+        cloneSubrepos(root, tempDir, subrepos);
         cloneOfTheMirror.update().toRevision(toVer).call();
         buildPatchFromDirectory(builder, tempDir, checkoutRules, myIgnoreDotHgFilter);
       } else {
@@ -282,6 +285,39 @@
     }
   }
 
+  private void cloneSubrepos(@NotNull HgVcsRoot mainRoot, @NotNull File mainRootDir, @NotNull Map<String, SubRepo> subrepos) throws VcsException, IOException {
+    for (Map.Entry<String, SubRepo> e : subrepos.entrySet()) {
+      String path = e.getKey();
+      SubRepo subrepoConfig = e.getValue();
+      if (subrepoConfig.vcsType() != SubRepo.VcsType.hg)
+        continue;
+      String parentRepositoryUrl = mainRoot.getRepository();
+      try {
+        String subrepoUrl = subrepoConfig.resolveUrl(parentRepositoryUrl);
+        HgVcsRoot subrepoRoot = mainRoot.withUrl(subrepoUrl);
+        HgRepo subrepo = createRepo(subrepoRoot);
+        if (!subrepo.containsRevision(subrepoConfig.revision()))
+          syncRepository(subrepoRoot);
+
+        File subrepoMirrorDir = getWorkingDir(subrepoRoot);
+        File subrepoDir = new File(mainRootDir, path);
+        HgRepo cloneOfSubrepoMirror = createRepo(subrepoRoot, subrepoDir);
+        cloneOfSubrepoMirror.doClone().fromRepository(subrepoMirrorDir)
+                .setUpdateWorkingDir(false)
+                .setUsePullProtocol(false)
+                .useUncompressedTransfer(false)
+                .call();
+        cloneOfSubrepoMirror.setDefaultPath(subrepoConfig.url());
+
+        Map<String, SubRepo> subSubrepos = subrepo.getSubrepositories(subrepoConfig.revision());
+        if (!subSubrepos.isEmpty())
+          cloneSubrepos(subrepoRoot, subrepoDir, subSubrepos);
+      } catch (URISyntaxException error) {
+        //ignore it, will try to clone from network during main repository update
+      }
+    }
+  }
+
   private void buildPatchFromDirectory(final PatchBuilder builder, final File repRoot, final CheckoutRules checkoutRules, @NotNull final FileFilter filter) throws IOException {
     buildPatchFromDirectory(repRoot, builder, repRoot, checkoutRules, filter);
   }
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java	Thu Apr 11 21:30:50 2013 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java	Mon Apr 15 16:53:47 2013 +0400
@@ -177,20 +177,6 @@
     checkPatchResult(output.toByteArray());
   }
 
-  public void test_clean_patch_with_subrepositories() throws Exception {
-    File r1 = new File(myPluginConfig.getCachesDir(), "r1");
-    File r3 = new File(myPluginConfig.getCachesDir(), "r3");
-    copyDir(new File("mercurial-tests/testData/subrepos/r1"), r1);
-    copyDir(new File("mercurial-tests/testData/subrepos/r3"), r3);
-    moveDirWithContent(new File(r1, "hg"), new File(r1, ".hg"));
-    moveDirWithContent(new File(r3, "hg"), new File(r3, ".hg"));
-
-    VcsRootImpl root = vcsRoot().withUrl(r1.getAbsolutePath()).build();
-
-    setName("clean_patch_with_subrepositories");
-    checkPatchResult(buildPatch(myVcs, root, null, "3:d350e7209906", CheckoutRules.DEFAULT).toByteArray());
-  }
-
   public void test_get_content() throws IOException, VcsException {
     VcsRootImpl vcsRoot = createVcsRoot(simpleRepo());
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SubrepoPatchTest.java	Mon Apr 15 16:53:47 2013 +0400
@@ -0,0 +1,81 @@
+package jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import com.intellij.openapi.diagnostic.Logger;
+import jetbrains.buildServer.log.Log4jFactory;
+import jetbrains.buildServer.vcs.CheckoutRules;
+import jetbrains.buildServer.vcs.impl.VcsRootImpl;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.File;
+
+import static com.intellij.openapi.util.io.FileUtil.delete;
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialSupportBuilder.mercurialSupport;
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.buildPatch;
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.copyRepository;
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot;
+
+@Test
+public class SubrepoPatchTest extends BaseMercurialTestCase {
+
+  static {
+    Logger.setFactory(new Log4jFactory());
+  }
+
+  private MercurialVcsSupport myVcs;
+  private File myRemoteRepo1;
+  private File myRemoteRepo2;
+  private File myRemoteRepo3;
+  private ServerPluginConfig myPluginConfig;
+
+  @BeforeMethod
+  public void setUp() throws Exception {
+    super.setUp();
+    File remoteRepoParentDir = myTempFiles.createTempDir();
+    myRemoteRepo1 = new File(remoteRepoParentDir, "r1");
+    myRemoteRepo2 = new File(remoteRepoParentDir, "r2");
+    myRemoteRepo3 = new File(remoteRepoParentDir, "r3");
+    copyRepository(new File("mercurial-tests/testData/subrepos/r1"), myRemoteRepo1);
+    copyRepository(new File("mercurial-tests/testData/subrepos/r2"), myRemoteRepo2);
+    copyRepository(new File("mercurial-tests/testData/subrepos/r3"), myRemoteRepo3);
+    myPluginConfig = new ServerPluginConfigBuilder()
+            .cachesDir(myTempFiles.createTempDir())
+            .detectSubrepoChanges(true)
+            .build();
+    myVcs = mercurialSupport().withConfig(myPluginConfig).build();
+  }
+
+  @Override
+  protected String getTestDataPath() {
+    return "mercurial-tests/testData";
+  }
+
+
+  public void clean_patch_should_use_subrepo_clones_on_the_server() throws Exception {
+    VcsRootImpl root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).withSubrepoChanges(true).build();
+
+    //this makes plugin to clone r1 and its subrepos2
+    myVcs.getCollectChangesPolicy().collectChanges(root, "e4eced2b7381", "d64d9799c143", CheckoutRules.DEFAULT);
+
+    //delete remote subrepo to make sure patch is build from the clone on the server
+    delete(myRemoteRepo3);
+
+    setName("clean_patch_with_subrepositories");
+    checkPatchResult(buildPatch(myVcs, root, null, "d350e7209906", CheckoutRules.DEFAULT).toByteArray());
+  }
+
+
+  public void clean_patch_should_use_subrepo_clones_on_the_server_recursive_case() throws Exception {
+    VcsRootImpl root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).withSubrepoChanges(true).build();
+
+    //this makes plugin to clone r1 and its subrepos2
+    myVcs.getCollectChangesPolicy().collectChanges(root, "e4eced2b7381", "d64d9799c143", CheckoutRules.DEFAULT);
+
+    //delete remote subrepos to make sure patch is build from the clone on the server
+    delete(myRemoteRepo2);
+    delete(myRemoteRepo3);
+
+    setName("clean_patch_recursive_subrepos");
+    checkPatchResult(buildPatch(myVcs, root, null, "d64d9799c143", CheckoutRules.DEFAULT).toByteArray());
+  }
+}
--- a/mercurial-tests/src/testng.xml	Thu Apr 11 21:30:50 2013 +0400
+++ b/mercurial-tests/src/testng.xml	Mon Apr 15 16:53:47 2013 +0400
@@ -27,6 +27,7 @@
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.RevisionFormatTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.HgFileUtilTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.SubrepoChangesTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.SubrepoPatchTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.HgRepoTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialXmlLogParserTest"/>
       <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.HgVcsRootFactoryTest"/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/clean_patch_recursive_subrepos/after/.hgsub	Mon Apr 15 16:53:47 2013 +0400
@@ -0,0 +1,1 @@
+r2 = ../r3
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/clean_patch_recursive_subrepos/after/.hgsubstate	Mon Apr 15 16:53:47 2013 +0400
@@ -0,0 +1,1 @@
+514c3e09cddf160486a96dedb196a39d9410972c r2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/clean_patch_recursive_subrepos/after/a	Mon Apr 15 16:53:47 2013 +0400
@@ -0,0 +1,1 @@
+a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/clean_patch_recursive_subrepos/after/r2/.hgsub	Mon Apr 15 16:53:47 2013 +0400
@@ -0,0 +1,1 @@
+r2 = ../r2
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/clean_patch_recursive_subrepos/after/r2/.hgsubstate	Mon Apr 15 16:53:47 2013 +0400
@@ -0,0 +1,1 @@
+ac0003deae69d799c0f86cb23585b32612de574d r2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/clean_patch_recursive_subrepos/after/r2/c	Mon Apr 15 16:53:47 2013 +0400
@@ -0,0 +1,3 @@
+c
+cc
+ccc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/testData/clean_patch_recursive_subrepos/after/r2/r2/b	Mon Apr 15 16:53:47 2013 +0400
@@ -0,0 +1,3 @@
+b
+bb
+bbb