changeset 421:83aff5760c25 Faradi-7.0.x

Speedup changes calculation Add log template which doesn't log changed files, use it with mercurial which doesn't support revsets
author Dmitry Neverov <dmitry.neverov@gmail.com>
date Fri, 27 Apr 2012 07:15:04 +0400
parents 743dc1646555
children ef53ca83df1b 4a76645fe087
files mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java mercurial-server/resources/buildServerResources/log.no.files.template mercurial-server/resources/buildServerResources/log.template mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RepoFactory.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgRepo.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesNoRevsets.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java
diffstat 7 files changed, 81 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java	Wed Apr 25 17:56:34 2012 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java	Fri Apr 27 07:15:04 2012 +0400
@@ -219,6 +219,8 @@
   private List<ModifiedFile> getModifiedFiles(@NotNull final Element logEntry) {
     List<ModifiedFile> result = new ArrayList<ModifiedFile>();
     Element paths = logEntry.getChild("paths");
+    if (paths == null)
+      return result;
     for (Object o : paths.getChildren("path")) {
       Element path = (Element) o;
       result.add(getModifiedFile(path));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-server/resources/buildServerResources/log.no.files.template	Fri Apr 27 07:15:04 2012 +0400
@@ -0,0 +1,6 @@
+header = '<?xml version="1.0"?>\n<log>\n'
+footer = '</log>\n'
+
+changeset = '<logentry revision="{rev}" shortnode="{node|short}">\n{parents}<author original="{author|xmlescape}"/>\n<date>{date|date|xmlescape}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n</logentry>\n'
+
+parent = '<parent revision="{rev}" node="{node}" shortnode="{node|short}"/>\n'
--- a/mercurial-server/resources/buildServerResources/log.template	Wed Apr 25 17:56:34 2012 +0400
+++ b/mercurial-server/resources/buildServerResources/log.template	Fri Apr 27 07:15:04 2012 +0400
@@ -1,17 +1,11 @@
 header = '<?xml version="1.0"?>\n<log>\n'
 footer = '</log>\n'
 
-changeset = '<logentry revision="{rev}" node="{node}" shortnode="{node|short}">\n{branches}{tags}{parents}<author original="{author|xmlescape}" email="{author|email|xmlescape}">{author|person|xmlescape}</author>\n<date>{date|date|xmlescape}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{file_adds}{file_dels}{file_mods}</paths>\n{file_copies}</logentry>\n'
+changeset = '<logentry revision="{rev}" shortnode="{node|short}">\n{parents}<author original="{author|xmlescape}"/>\n<date>{date|date|xmlescape}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{file_adds}{file_dels}{file_mods}</paths>\n</logentry>\n'
 
 file_add  = '<path action="A">{file_add|xmlescape}</path>\n'
 file_mod  = '<path action="M">{file_mod|xmlescape}</path>\n'
 file_del  = '<path action="R">{file_del|xmlescape}</path>\n'
 
-start_file_copies = '<copies>\n'
-file_copy = '<copy source="{source|xmlescape}">{name|xmlescape}</copy>\n'
-end_file_copies = '</copies>\n'
+parent = '<parent revision="{rev}" shortnode="{node|short}"/>\n'
 
-parent = '<parent revision="{rev}" node="{node}" shortnode="{node|short}"/>\n'
-branch = '<branch>{branch|xmlescape}</branch>\n'
-tag = '<tag>{tag|xmlescape}</tag>\n'
-extra = '<extra key="{key|xmlescape}">{value|xmlescape}</extra>\n'
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RepoFactory.java	Wed Apr 25 17:56:34 2012 +0400
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RepoFactory.java	Fri Apr 27 07:15:04 2012 +0400
@@ -18,15 +18,17 @@
 
   private final ServerPluginConfig myConfig;
   private File myLogTemplate;
+  private File myLogNoFilesTemplate;
 
   public RepoFactory(@NotNull ServerPluginConfig config) throws IOException {
     myConfig = config;
     myLogTemplate = createLogTemplate();
+    myLogNoFilesTemplate = createLogNoFilesTemplate();
   }
 
   @NotNull
   public ServerHgRepo create(@NotNull File workingDir, @NotNull String hgPath, @NotNull AuthSettings authSettings) throws VcsException {
-    return new ServerHgRepo(myConfig, workingDir, hgPath, authSettings).withLogTemplate(getTemplate());
+    return new ServerHgRepo(myConfig, workingDir, hgPath, authSettings).withLogTemplates(getTemplate(), getLogNoFilesTemplate());
   }
 
   public void dispose() {
@@ -44,9 +46,26 @@
     }
   }
 
+  private File getLogNoFilesTemplate() throws VcsException {
+    if (myLogNoFilesTemplate.isFile() && myLogNoFilesTemplate.exists())
+      return myLogNoFilesTemplate;
+    try {
+      myLogNoFilesTemplate = createLogNoFilesTemplate();
+      return myLogNoFilesTemplate;
+    } catch (IOException e) {
+      throw new VcsException("Cannot create mercurial log template", e);
+    }
+  }
+
   private File createLogTemplate() throws IOException {
     File template = createTempFile("teamcity", "hg.log.template");
     FileUtil.copyResource(RepoFactory.class, "/buildServerResources/log.template", template);
     return template;
   }
+
+  private File createLogNoFilesTemplate() throws IOException {
+    File template = createTempFile("teamcity", "hg.short.log.template");
+    FileUtil.copyResource(RepoFactory.class, "/buildServerResources/log.no.files.template", template);
+    return template;
+  }
 }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgRepo.java	Wed Apr 25 17:56:34 2012 +0400
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgRepo.java	Fri Apr 27 07:15:04 2012 +0400
@@ -14,14 +14,16 @@
   private final static HgVersion REVSET_HG_VERSION = new HgVersion(1, 7, 0);
   private final ServerPluginConfig myConfig;
   private File myLogTemplate;
+  private File myLogNoFilesTemplate;
 
   public ServerHgRepo(@NotNull ServerPluginConfig config, @NotNull File workingDir, @NotNull String hgPath, @NotNull AuthSettings authSettings) {
     super(workingDir, hgPath, authSettings);
     myConfig = config;
   }
 
-  public ServerHgRepo withLogTemplate(@NotNull File logTemplate) {
+  public ServerHgRepo withLogTemplates(@NotNull File logTemplate, @NotNull File logNoFilesTemplate) {
     myLogTemplate = logTemplate;
+    myLogNoFilesTemplate = logNoFilesTemplate;
     return this;
   }
 
@@ -40,13 +42,13 @@
   @NotNull
   public CollectChangesCommand collectChanges() throws VcsException {
     if (myConfig.dontUseRevsets())
-      return new CollectChangesNoRevsets(this);
+      return new CollectChangesNoRevsets(this, myLogNoFilesTemplate);
 
     HgVersion hgVersion = getHgVersion();
     if (hgVersion.isEqualsOrGreaterThan(REVSET_HG_VERSION)) {
       return new CollectChangesWithRevsets(this);
     } else {
-      return new CollectChangesNoRevsets(this);
+      return new CollectChangesNoRevsets(this, myLogNoFilesTemplate);
     }
   }
 
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesNoRevsets.java	Wed Apr 25 17:56:34 2012 +0400
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesNoRevsets.java	Fri Apr 27 07:15:04 2012 +0400
@@ -8,6 +8,7 @@
 import jetbrains.buildServer.vcs.VcsException;
 import org.jetbrains.annotations.NotNull;
 
+import java.io.File;
 import java.util.*;
 
 /**
@@ -16,9 +17,11 @@
 public class CollectChangesNoRevsets extends CollectChangesCommand {
 
   private ServerHgRepo myRepo;
+  private File myLogNoFilesTemplate;
 
-  public CollectChangesNoRevsets(@NotNull ServerHgRepo repo) {
+  public CollectChangesNoRevsets(@NotNull ServerHgRepo repo, @NotNull File logNoFilesTemplate) {
     myRepo = repo;
+    myLogNoFilesTemplate = logNoFilesTemplate;
   }
 
   @Override
@@ -28,6 +31,25 @@
 
   @NotNull
   public List<ChangeSet> call(@NotNull final String fromCommit, @NotNull final String toCommit) throws VcsException {
+    Pair<List<ChangeSet>, Integer> commitsWithoutFiles = getCommitsWithoutFiles(fromCommit, toCommit);
+    List<ChangeSet> csetsWithoutFiles = commitsWithoutFiles.first;
+    Integer minRevNum = commitsWithoutFiles.second;
+    if (csetsWithoutFiles.isEmpty())
+      return csetsWithoutFiles;
+    List<ChangeSet> commitsWithFiles = getRevisionsBetween(minRevNum, toCommit);
+    Map<String, ChangeSet> csetMap = getChangesetMap(commitsWithFiles);
+    List<ChangeSet> result = new ArrayList<ChangeSet>();
+    for (ChangeSet cset : csetsWithoutFiles) {
+      ChangeSet csetWithFiles = csetMap.get(cset.getId());
+      if (csetWithFiles != null)
+        result.add(csetWithFiles);
+    }
+    return result;
+  }
+
+
+  @NotNull
+  private Pair<List<ChangeSet>, Integer> getCommitsWithoutFiles(@NotNull String fromCommit, @NotNull String toCommit) throws VcsException {
     List<ChangeSet> csets = getRevisionsReachableFrom(toCommit);
     Map<String, ChangeSet> csetsMap = getChangesetMap(csets);
     if (csetsMap.containsKey(fromCommit)) {
@@ -35,17 +57,21 @@
       DAGIterator<String> iter = dag.iterator(toCommit);
       iter.markUninteresting(fromCommit);
       List<ChangeSet> result = new ArrayList<ChangeSet>();
+      int minRevNum = Integer.MAX_VALUE;
       while (iter.hasNext()) {
         String commit = iter.next();
         ChangeSet cset = csetsMap.get(commit);
         if (cset == null)
           throw new IllegalStateException("Cannot find cset for id " + commit + ", csets map: " + csetsMap);
+        int revNum = cset.getRevNumber();
+        if (revNum < minRevNum)
+          minRevNum = revNum;
         result.add(cset);
       }
       Collections.reverse(result);
-      return result;
+      return Pair.create(result, minRevNum);
     } else {
-      return Collections.emptyList();
+      return new Pair<List<ChangeSet>, Integer>(Collections.<ChangeSet>emptyList(), Integer.MAX_VALUE);
     }
   }
 
@@ -64,6 +90,16 @@
             .fromRevision(revision)
             .toRevision("0")
             .showCommitsFromAllBranches()
+            .withTemplate(myLogNoFilesTemplate)
+            .call();
+  }
+
+
+  private List<ChangeSet> getRevisionsBetween(int fromRevNum, @NotNull String toCommit) throws VcsException {
+    return myRepo.log()
+            .fromRevision(toCommit)
+            .toRevision(String.valueOf(fromRevNum))
+            .showCommitsFromAllBranches()
             .call();
   }
 
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java	Wed Apr 25 17:56:34 2012 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java	Fri Apr 27 07:15:04 2012 +0400
@@ -12,7 +12,7 @@
   private boolean myUsePullProtocol = true;
   private String myHgPath;
   private File myCachesDir;
-
+  private boolean myDontUseRevsets = false;
 
   @NotNull
   public ServerPluginConfig build() {
@@ -38,7 +38,7 @@
       }
 
       public boolean dontUseRevsets() {
-        return false;
+        return myDontUseRevsets;
       }
     };
   }
@@ -58,4 +58,9 @@
     myCachesDir = cachesDir;
     return this;
   }
+
+  public ServerPluginConfigBuilder dontUseRevsets() {
+    myDontUseRevsets = true;
+    return this;
+  }
 }