diff mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java @ 511:f2666e817701

Detect changes in subrepos
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Thu, 15 Nov 2012 16:40:22 +0400
parents efba721f9a1d
children 4f5273a54927
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java	Mon Nov 12 21:20:00 2012 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java	Thu Nov 15 16:40:22 2012 +0400
@@ -1,5 +1,6 @@
 package jetbrains.buildServer.buildTriggers.vcs.mercurial;
 
+import com.intellij.openapi.util.Trinity;
 import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.*;
 import jetbrains.buildServer.log.Loggers;
 import jetbrains.buildServer.util.FileUtil;
@@ -10,6 +11,7 @@
 import java.io.IOException;
 import java.util.*;
 
+import static java.util.Collections.emptyList;
 import static java.util.Collections.emptyMap;
 import static jetbrains.buildServer.buildTriggers.vcs.mercurial.HgFileUtil.deleteDir;
 import static jetbrains.buildServer.util.FileUtil.isEmptyDir;
@@ -87,6 +89,10 @@
     return new VersionCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir);
   }
 
+  public ParentsCommand parents() {
+    return new ParentsCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir);
+  }
+
   public String path() {
     return myWorkingDir.getAbsolutePath();
   }
@@ -153,11 +159,79 @@
     return getSubrepositories(new ChangeSet(revision));
   }
 
+  public List<SubRepoConfigChange> getSubrepoConfigChanges(@NotNull String revision) throws VcsException {
+    if (containsSubrepoConfigChange(revision)) {
+      List<String> parents = parents().ofRevision(revision).call();
+      return getSubrepoConfigChanges(revision, parents.get(0));//what about merges?
+    }
+    return emptyList();
+  }
+
+  public List<SubRepoConfigChange> getSubrepoConfigChanges(@NotNull ChangeSet cset) {
+    if (containsSubrepoConfigChange(cset))
+      return getSubrepoConfigChanges(cset.getId(), cset.getParents().get(0).getId());
+    return emptyList();
+  }
+
+  private List<SubRepoConfigChange> getSubrepoConfigChanges(@NotNull String revision, @NotNull String parentRevision) {
+    Map<String, SubRepo> curSubrepos = getSubrepositories(revision);
+    Map<String, SubRepo> prevSubrepos = getSubrepositories(parentRevision);
+    return getSubrepoConfigChanges(prevSubrepos, curSubrepos);
+
+  }
+
+  private List<SubRepoConfigChange> getSubrepoConfigChanges(@NotNull Map<String, SubRepo> prevSubrepos,
+                                                            @NotNull Map<String, SubRepo> curSubrepos) {
+    List<SubRepoConfigChange> configChanges = new ArrayList<SubRepoConfigChange>();
+    for (Map.Entry<String, SubRepo> e : curSubrepos.entrySet()) {
+      SubRepo curSubrepo = e.getValue();
+      SubRepo prevSubrepo = prevSubrepos.remove(e.getKey());
+      if (prevSubrepo == null) {
+        configChanges.add(new SubRepoConfigChange(e.getKey(), null, curSubrepo));
+      } else {
+        String prevRevision = prevSubrepo.revision();
+        String currentRevision = curSubrepo.revision();
+        if (!currentRevision.equals(prevRevision))
+          configChanges.add(new SubRepoConfigChange(e.getKey(), prevSubrepo, curSubrepo));
+      }
+    }
+    for (Map.Entry<String, SubRepo> e : prevSubrepos.entrySet()) {
+      configChanges.add(new SubRepoConfigChange(e.getKey(), e.getValue(), null));
+    }
+    return configChanges;
+  }
+
+  private boolean containsSubrepoConfigChange(@NotNull ChangeSet cset) {
+    for (FileStatus f : cset.getModifiedFiles()) {
+      if (containsSubrepoConfigChange(f))
+        return true;
+    }
+    return false;
+  }
+
+  private boolean containsSubrepoConfigChange(@NotNull String revision) throws VcsException {
+    List<FileStatus> changedFiles = status()
+            .fromRevision(revision)
+            .toRevision(revision)
+            .showAllFiles()
+            .call();
+    for (FileStatus f : changedFiles) {
+      if (containsSubrepoConfigChange(f))
+        return true;
+    }
+    return false;
+  }
+
+  private boolean containsSubrepoConfigChange(@NotNull FileStatus f) {
+    return f.getPath().equals(".hgsubstate");
+  }
+
+  //path->subrepo
   public Map<String, SubRepo> getSubrepositories(@NotNull ChangeSet cset) {
     String revId = cset.getId();
     Map<String, SubRepo> subrepos = mySubreposCache.get(revId);
     if (subrepos != null)
-      return subrepos;
+      return new HashMap<String, SubRepo>(subrepos);
     CatCommand cc = cat();
     cc.setRevId(revId);
     File catDir = null;
@@ -167,7 +241,7 @@
       File hgsubstate = new File(catDir, ".hgsubstate");
       subrepos = readSubrepositories(hgsub, hgsubstate);
       mySubreposCache.put(revId, subrepos);
-      return subrepos;
+      return new HashMap<String, SubRepo>(subrepos);
     } catch (VcsException e) {
       return emptyMap();
     } finally {
@@ -190,15 +264,11 @@
           String path = entry.getKey();
           String url = entry.getValue();
           String revision = path2revision.get(path);
-          if (revision != null) {
+          if (revision != null)
             result.put(path, new SubRepo(this, path, url, revision));
-          } else {
-//              myLogger.warning("Cannot find revision for subrepository at path " + path + " skip it");
-          }
         }
         return result;
       } catch (IOException e) {
-//          myLogger.warning("Error while trying to read subrepositories " + e.getMessage());
         return emptyMap();
       }
     } else {
@@ -211,11 +281,8 @@
     Map<String, String> result = new HashMap<String, String>();
     for (String line : FileUtil.readFile(hgsub)) {
       String[] parts = line.split(" = ");
-      if (parts.length == 2) {
+      if (parts.length == 2)
         result.put(parts[0], parts[1]);
-      } else {
-//          myLogger.warning("Cannot parse the line '" + line + "' from .hgsub, skip it");
-      }
     }
     return result;
   }
@@ -226,11 +293,8 @@
     Map<String, String> result = new HashMap<String, String>();
     for (String line : FileUtil.readFile(hgsubstate)) {
       String[] parts = line.split(" ");
-      if (parts.length == 2) {
+      if (parts.length == 2)
         result.put(parts[1], parts[0]);
-      } else {
-//          myLogger.warning("Cannot parse the line '" + line + "' from .hgsubstate, skip it");
-      }
     }
     return result;
   }