changeset 655:5a40adf2ca9e

implement CommitsInfoBuilder API
author eugene.petrenko@gmail.com
date Mon, 30 Sep 2013 15:11:25 +0200
parents 3daa8e36f8f1
children 32d2a04206c8
files mercurial-server/src/META-INF/build-server-plugin-mercurial.xml mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCommitsInfoBuilderSupport.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CommitsInfoBuilderSupportTest.java
diffstat 3 files changed, 171 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-server/src/META-INF/build-server-plugin-mercurial.xml	Mon Sep 30 15:11:01 2013 +0200
+++ b/mercurial-server/src/META-INF/build-server-plugin-mercurial.xml	Mon Sep 30 15:11:25 2013 +0200
@@ -12,4 +12,6 @@
   <bean id="commandSettingsFactory" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.ServerCommandSettingsFactory"/>
   <bean id="cleaner" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialCleaner"/>
   <bean id="mergeSupport" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialMergeSupport"/>
+
+  <bean class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialCommitsInfoBuilderSupport"/>
 </beans>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCommitsInfoBuilderSupport.java	Mon Sep 30 15:11:25 2013 +0200
@@ -0,0 +1,82 @@
+package jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.ChangeSet;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.ChangeSetRevision;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot;
+import jetbrains.buildServer.vcs.*;
+import jetbrains.vcs.api.CommitInfo;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.command.LogCommand.ZERO_PARENT_ID;
+
+/**
+ * Created 30.09.13 13:05
+ *
+ * @author Eugene Petrenko (eugene.petrenko@jetbrains.com)
+ */
+public class MercurialCommitsInfoBuilderSupport implements CommitsInfoBuilder, MercurialServerExtension {
+  private final MercurialVcsSupport mySupport;
+  private final HgVcsRootFactory myHgVcsRootFactory;
+
+  public MercurialCommitsInfoBuilderSupport(@NotNull MercurialVcsSupport vcs,
+                                            @NotNull HgVcsRootFactory vcsRootFactory) {
+    vcs.addExtension(this);
+    mySupport = vcs;
+    myHgVcsRootFactory = vcsRootFactory;
+  }
+
+  @NotNull
+  public List<CommitInfo> collectCommits(@NotNull VcsRoot root,
+                                         @NotNull CheckoutRules rules,
+                                         @NotNull RepositoryStateData headState) throws VcsException {
+    final HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root);
+    final ServerHgRepo repo = mySupport.createRepo(hgRoot);
+    mySupport.syncRepository(hgRoot);
+
+    final Map<String, CommitDataBean> commitToBean = new HashMap<String, CommitDataBean>();
+
+    //this could be implemented better with newer version of HG
+    //currently we have a process per head and next we merge commits via Java's in-memory map
+    for (String commitId : headState.getBranchRevisions().values()) {
+      commitToBean.putAll(processChanges(repo, commitId));
+    }
+
+    //collect tags info
+    Map<String, String> tags = repo.tags().call();
+    for (Map.Entry<String, String> e : tags.entrySet()) {
+      CommitDataBean bean = commitToBean.get(e.getValue());
+      if (bean != null) bean.addTag(e.getKey());
+    }
+
+    return new ArrayList<CommitInfo>(commitToBean.values());
+  }
+
+  @NotNull
+  private Map<String, CommitDataBean> processChanges(@NotNull ServerHgRepo repo, @NotNull final String head) throws VcsException {
+    final List<ChangeSet> tip = repo.logNoFiles()
+            .fromRevision("0")
+            .toRevision(head)
+            .showCommitsFromAllBranches()
+            .call();
+
+    final Map<String, CommitDataBean> result = new HashMap<String, CommitDataBean>();
+    for (ChangeSet set : tip) {
+      final CommitDataBean bean = new CommitDataBean(set.getId(), set.getFullVersion(), set.getTimestamp());
+      for (ChangeSetRevision p : set.getParents()) {
+        final String commitId = p.getId();
+
+        if (ZERO_PARENT_ID.equals(commitId)) continue;
+        bean.addParentRevision(commitId);
+      }
+      bean.addBranch(set.getBranch());
+      result.put(bean.getVersion(), bean);
+    }
+
+    return result;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CommitsInfoBuilderSupportTest.java	Mon Sep 30 15:11:25 2013 +0200
@@ -0,0 +1,87 @@
+package jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import jetbrains.buildServer.TestLogger;
+import jetbrains.buildServer.util.CollectionsUtil;
+import jetbrains.buildServer.vcs.CheckoutRules;
+import jetbrains.buildServer.vcs.RepositoryStateData;
+import jetbrains.buildServer.vcs.VcsException;
+import jetbrains.buildServer.vcs.VcsRoot;
+import jetbrains.vcs.api.CommitInfo;
+import junit.framework.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialSupportBuilder.mercurialSupport;
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.copyRepository;
+import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot;
+
+/**
+ * Created 30.09.13 13:07
+ *
+ * @author Eugene Petrenko (eugene.petrenko@jetbrains.com)
+ */
+public class CommitsInfoBuilderSupportTest extends BaseMercurialTestCase {
+  private File myRemoteRepo;
+  private MercurialVcsSupport myVcs;
+  private MercurialCommitsInfoBuilderSupport mySupport;
+
+  @Override
+  @BeforeMethod
+  public void setUp() throws Exception {
+    super.setUp();
+    ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder()
+            .cachesDir(myTempFiles.createTempDir())
+            .build();
+    MercurialSupportBuilder mercurialBuilder = mercurialSupport().withConfig(pluginConfig);
+    myVcs = mercurialBuilder.build();
+    mySupport = new MercurialCommitsInfoBuilderSupport(myVcs, mercurialBuilder.getHgRootFactory());
+    myRemoteRepo = myTempFiles.createTempDir();
+    copyRepository(new File("mercurial-tests/testData/rep2"), myRemoteRepo);
+  }
+
+  @Test
+  public void simpleTest() throws IOException, VcsException {
+    TestLogger.enableMainAndVCSLoggerDebug();
+
+    VcsRoot root = vcsRoot().withUrl(myRemoteRepo).build();
+
+    final String v = "4780519e01aa"; ///30
+
+    final List<CommitInfo> commitInfos = mySupport.collectCommits(root, CheckoutRules.DEFAULT, RepositoryStateData.createVersionState("default", CollectionsUtil.asMap("default", v)));
+    Assert.assertFalse(commitInfos.isEmpty());
+
+    for (CommitInfo commitInfo : commitInfos) {
+      System.out.println(commitInfo);
+    }
+
+    final Set<String> branches = new TreeSet<String>();
+    final Set<String> tags = new TreeSet<String>();
+    final Set<String> commits = new TreeSet<String>();
+    final Set<String> parents = new TreeSet<String>();
+    for (CommitInfo commitInfo : commitInfos) {
+      branches.addAll(commitInfo.getBranches());
+      tags.addAll(commitInfo.getTags());
+
+      //commit should be returned once
+      Assert.assertTrue(commits.add(commitInfo.getVersion()));
+      parents.addAll(commitInfo.getParentRevisions());
+    }
+
+    Assert.assertEquals(branches, new TreeSet<String>(Arrays.asList("default", "personal-branch", "test", "topic")));
+    Assert.assertEquals(tags, new TreeSet<String>(Arrays.asList("t1")));
+
+    //check all parent commits are included into the set
+    Assert.assertTrue(commits.containsAll(parents));
+
+    //head should be head
+    Assert.assertFalse(parents.contains(v));
+  }
+
+}