changeset 782:44b15b5a87e8

VCS-41 use archive to build an incremental patch
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Wed, 16 Apr 2014 22:45:46 +0200
parents 2afd4572bc92
children f0327df85b9d
files mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ArchiveCommand.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java
diffstat 2 files changed, 79 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ArchiveCommand.java	Wed Apr 16 17:38:38 2014 +0200
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ArchiveCommand.java	Wed Apr 16 22:45:46 2014 +0200
@@ -92,16 +92,18 @@
     cli.addParameter("archive");
     setType(cli);
     setRevision(cli);
+    addIncludeRules(cli);
     setDestination(cli);
-    addIncludeRules(cli);
     return cli;
   }
 
   private void addIncludeRules(@NotNull MercurialCommandLine cli) {
     if (myIncludeRules.isEmpty())
       return;
-    cli.addParameter("-I");
-    cli.addParameters(myIncludeRules);
+    for (String include : myIncludeRules) {
+      cli.addParameter("-I");
+      cli.addParameter(include);
+    }
   }
 
   private void setDestination(GeneralCommandLine cli) {
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Wed Apr 16 17:38:38 2014 +0200
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Wed Apr 16 22:45:46 2014 +0200
@@ -233,21 +233,28 @@
       }
     }
 
-    File parentDir = repo.cat().files(notDeletedFiles).atRevision(toVer).call();
+    File parentDir = null;
     try {
-      for (FileStatus f: modifiedFiles) {
-        String mappedPath = checkoutRules.map(f.getPath());
-        if (mappedPath == null) continue; // skip
-        final File virtualFile = new File(mappedPath);
-        if (f.getStatus() == Status.REMOVED) {
-          builder.deleteFile(virtualFile, true);
-        } else {
-          File realFile = new File(parentDir, f.getPath());
-          FileInputStream is = new FileInputStream(realFile);
-          try {
-            builder.changeOrCreateBinaryFile(virtualFile, null, is, realFile.length());
-          } finally {
-            is.close();
+      if (root.useArchiveForPatch()) {
+        parentDir = HgFileUtil.createTempDir();
+        File archFile = new File(parentDir, "arch.tar");
+        buildIncrementalPatchWithArchive(builder, repo, toVer, checkoutRules, modifiedFiles, notDeletedFiles, archFile);
+      } else {
+        parentDir = repo.cat().files(notDeletedFiles).atRevision(toVer).call();
+        for (FileStatus f: modifiedFiles) {
+          String mappedPath = checkoutRules.map(f.getPath());
+          if (mappedPath == null) continue; // skip
+          final File virtualFile = new File(mappedPath);
+          if (f.getStatus() == Status.REMOVED) {
+            builder.deleteFile(virtualFile, true);
+          } else {
+            File realFile = new File(parentDir, f.getPath());
+            FileInputStream is = new FileInputStream(realFile);
+            try {
+              builder.changeOrCreateBinaryFile(virtualFile, null, is, realFile.length());
+            } finally {
+              is.close();
+            }
           }
         }
       }
@@ -259,7 +266,50 @@
       builder.deleteDirectory(new File(""), true);//clean patch
       buildFullPatch(root, toVer, builder, checkoutRules);
     } finally {
-      deleteDir(parentDir, Loggers.VCS);
+      if (parentDir != null)
+        deleteDir(parentDir, Loggers.VCS);
+    }
+  }
+
+  private void buildIncrementalPatchWithArchive(@NotNull PatchBuilder builder,
+                                                @NotNull HgRepo repo,
+                                                @NotNull ChangeSet toVer,
+                                                @NotNull CheckoutRules checkoutRules,
+                                                @NotNull List<FileStatus> modifiedFiles,
+                                                @NotNull List<String> notDeletedFiles,
+                                                @NotNull File archiveFile) throws VcsException, IOException {
+    ArchiveCommand archive = repo.archive().revision(toVer).type("tar").destination(archiveFile);
+    int i = 0;
+    while (i < notDeletedFiles.size()) {
+      String mappedPath = checkoutRules.map(notDeletedFiles.get(i));
+      if (mappedPath == null) {
+        i++;
+        continue;
+      }
+      if (archive.addIncludeRule(notDeletedFiles.get(i))) {
+        i++;
+        continue;
+      }
+      //archive command is full, call it
+      archive.call();
+      buildPatchFromArchive(builder, archiveFile, checkoutRules, new ExcludeHgArchival());
+      FileUtil.delete(archiveFile);
+      archive = repo.archive().revision(toVer).type("tar").destination(archiveFile);
+    }
+    if (!notDeletedFiles.isEmpty()) {
+      archive.call();
+      buildPatchFromArchive(builder, archiveFile, checkoutRules, new ExcludeHgArchival());
+      FileUtil.delete(archiveFile);
+    }
+
+    //delete removed files
+    for (FileStatus f: modifiedFiles) {
+      if (f.getStatus() == Status.REMOVED) {
+        String mappedPath = checkoutRules.map(f.getPath());
+        if (mappedPath == null)
+          continue; // skip
+        builder.deleteFile(new File(mappedPath), true);
+      }
     }
   }
 
@@ -344,11 +394,7 @@
           if (root.useArchiveForPatch()) {
             File archive = new File(tempDir, "arch.tar");
             repo.archive().revision(toVer).type("tar").destination(archive).call();
-            buildPatchFromArchive(builder, archive, checkoutRules, new FileFilter() {
-              public boolean accept(File f) {
-                return !f.getName().equals(".hg_archival.txt");
-              }
-            });
+            buildPatchFromArchive(builder, archive, checkoutRules, new ExcludeHgArchival());
           } else {
             repo.archive().revision(toVer).destination(tempDir).call();
             buildPatchFromDirectory(builder, tempDir, checkoutRules, myAcceptAllFilter);
@@ -359,11 +405,7 @@
         if (root.useArchiveForPatch()) {
           File archive = new File(tempDir, "arch.tar");
           repo.archive().revision(toVer).type("tar").destination(archive).call();
-          buildPatchFromArchive(builder, archive, checkoutRules, new FileFilter() {
-            public boolean accept(File f) {
-              return !f.getName().equals(".hg_archival.txt");
-            }
-          });
+          buildPatchFromArchive(builder, archive, checkoutRules, new ExcludeHgArchival());
         } else {
           repo.archive().revision(toVer).destination(tempDir).call();
           buildPatchFromDirectory(builder, tempDir, checkoutRules, myAcceptAllFilter);
@@ -733,4 +775,11 @@
     }
     return super.getVcsCustomExtension(extensionClass);
   }
+
+
+  private static class ExcludeHgArchival implements FileFilter {
+    public boolean accept(File f) {
+      return !f.getName().equals(".hg_archival.txt");
+    }
+  }
 }