# HG changeset patch
# User eugene.petrenko@gmail.com
# Date 1380546685 -7200
# Node ID 5a40adf2ca9e68ad258a5d00e3fe551c61c05676
# Parent 3daa8e36f8f1d8b6a3669fa50543010f2dbe3317
implement CommitsInfoBuilder API
diff -r 3daa8e36f8f1 -r 5a40adf2ca9e mercurial-server/src/META-INF/build-server-plugin-mercurial.xml
--- 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 @@
+
+
diff -r 3daa8e36f8f1 -r 5a40adf2ca9e mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCommitsInfoBuilderSupport.java
--- /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 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 commitToBean = new HashMap();
+
+ //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 tags = repo.tags().call();
+ for (Map.Entry e : tags.entrySet()) {
+ CommitDataBean bean = commitToBean.get(e.getValue());
+ if (bean != null) bean.addTag(e.getKey());
+ }
+
+ return new ArrayList(commitToBean.values());
+ }
+
+ @NotNull
+ private Map processChanges(@NotNull ServerHgRepo repo, @NotNull final String head) throws VcsException {
+ final List tip = repo.logNoFiles()
+ .fromRevision("0")
+ .toRevision(head)
+ .showCommitsFromAllBranches()
+ .call();
+
+ final Map result = new HashMap();
+ 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;
+ }
+}
diff -r 3daa8e36f8f1 -r 5a40adf2ca9e mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CommitsInfoBuilderSupportTest.java
--- /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 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 branches = new TreeSet();
+ final Set tags = new TreeSet();
+ final Set commits = new TreeSet();
+ final Set parents = new TreeSet();
+ 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(Arrays.asList("default", "personal-branch", "test", "topic")));
+ Assert.assertEquals(tags, new TreeSet(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));
+ }
+
+}