# HG changeset patch
# User Pavel.Sher
# Date 1216215461 -14400
# Node ID 40b2cf04cd4bf4a583b4abea632066e21681a67c
# Parent d787c696225c92fb5feb2a011ca6a930259c619a
some comments added
diff -r d787c696225c -r 40b2cf04cd4b mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java
--- a/mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Wed Jul 16 01:48:22 2008 +0400
+++ b/mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Wed Jul 16 17:37:41 2008 +0400
@@ -20,6 +20,18 @@
import java.io.IOException;
import java.util.*;
+/**
+ * Mercurial VCS plugin for TeamCity works as follows:
+ *
+ * - clones repository to internal storage
+ *
- before any operation with working copy of repository pulls changes from the original repository
+ *
- executes corresponding hg command
+ *
+ *
+ * Working copy of repository is created in the $TEAMCITY_DATA_PATH/system/caches/mercurial folder.
+ *
Personal builds (remote runs) are not yet supported, they require corresponding functionality from the IDE.
+ *
Checkout on agent mode is not yet supported too.
+ */
public class MercurialVcsSupport extends VcsSupport implements CollectChangesByIncludeRule {
private ServerPaths myServerPaths;
@@ -40,6 +52,7 @@
final String fromVersion,
final String currentVersion,
final IncludeRule includeRule) throws VcsException {
+ // first obtain changes between specified versions
List result = new ArrayList();
Settings settings = new Settings(myServerPaths, root);
LogCommand lc = new LogCommand(settings);
@@ -50,6 +63,7 @@
return result;
}
+ // invoke status command for each changeset and determine what files were modified in these changesets
Iterator it = changeSets.iterator();
ChangeSet prev = it.next(); // skip first changeset (cause it was already reported)
StatusCommand st = new StatusCommand(settings);
@@ -58,6 +72,8 @@
st.setFromRevId(prev.getId());
st.setToRevId(cur.getId());
List modifiedFiles = st.execute();
+ // changeset full version will be set into VcsChange structure and
+ // stored in database (note than getContent method will be invoked with this version)
List files = toVcsChanges(modifiedFiles, prev.getFullVersion(), cur.getFullVersion(), includeRule);
if (files.isEmpty()) continue;
ModificationData md = new ModificationData(cur.getTimestamp(), files, cur.getSummary(), cur.getUser(), root, cur.getFullVersion(), cur.getFullVersion());
@@ -159,6 +175,7 @@
@NotNull
public String getCurrentVersion(final VcsRoot root) throws VcsException {
+ // we will return full version of the most recent change as current version
updateWorkingDirectory(root);
Settings settings = new Settings(myServerPaths, root);
TipCommand lc = new TipCommand(settings);
@@ -196,7 +213,7 @@
@Nullable
public Map getDefaultVcsProperties() {
- return null;
+ return Collections.singletonMap(Constants.HG_COMMAND_PATH_PROP, "hg");
}
public String getVersionDisplayName(final String version, final VcsRoot root) throws VcsException {
@@ -205,6 +222,9 @@
@NotNull
public Comparator getVersionComparator() {
+ // comparator is called when TeamCity needs to sort modifications in the order of their appearance,
+ // currently we sort changes by revision number, not sure however that this is a good idea,
+ // probably it would be better to sort them by timestamp (and to add timestamp into the version).
return new Comparator() {
public int compare(final String o1, final String o2) {
try {
@@ -230,6 +250,7 @@
}
}
+ // builds patch from version to version
private void buildIncrementalPatch(final Settings settings, @NotNull final ChangeSet fromVer, @NotNull final ChangeSet toVer, final PatchBuilder builder)
throws VcsException, IOException {
StatusCommand st = new StatusCommand(settings);
@@ -267,6 +288,7 @@
}
}
+ // builds patch by exporting files using specified version
private void buildFullPatch(final Settings settings, @NotNull final ChangeSet toVer, final PatchBuilder builder)
throws IOException, VcsException {
CloneCommand cl = new CloneCommand(settings);
@@ -311,6 +333,7 @@
}
}
+ // updates current working copy of repository by pulling changes from the repository specified in VCS root
private void updateWorkingDirectory(final VcsRoot root) throws VcsException {
Settings settings = new Settings(myServerPaths, root);
String workDir = settings.getWorkingDir();
@@ -330,6 +353,7 @@
}
private boolean hasRepositoryCopy(final File workDir) {
+ // need better way to check that repository copy is ok
return workDir.isDirectory() && new File(workDir, ".hg").isDirectory();
}
diff -r d787c696225c -r 40b2cf04cd4b mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSet.java
--- a/mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSet.java Wed Jul 16 01:48:22 2008 +0400
+++ b/mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSet.java Wed Jul 16 17:37:41 2008 +0400
@@ -4,6 +4,9 @@
import java.util.Date;
+/**
+ * Represents Mercurial change set
+ */
public class ChangeSet {
private int myRevNumber;
@NotNull private String myId;
@@ -16,6 +19,10 @@
myId = id;
}
+ /**
+ * Constructor for version in the form revnum:changeset_id
+ * @param fullVersion full changeset version as reported by hg log command
+ */
public ChangeSet(@NotNull final String fullVersion) {
try {
String[] parts = fullVersion.split(":");
@@ -38,30 +45,54 @@
mySummary = summary;
}
+ /**
+ * Returns changeset revision id
+ * @return changeset revision id
+ */
@NotNull
public String getId() {
return myId;
}
+ /**
+ * Returns changeset revision number
+ * @return changeset revision number
+ */
public int getRevNumber() {
return myRevNumber;
}
+ /**
+ * Returns full changeset version as reported by hg log command: revnum:revid
+ * @return full changeset version as reported by hg log
+ */
@NotNull
public String getFullVersion() {
return myRevNumber + ":" + myId;
}
+ /**
+ * Returns user who made changeset
+ * @return user who made changeset
+ */
@NotNull
public String getUser() {
return myUser;
}
+ /**
+ * Returns changeset timestamp
+ * @return changeset timestamp
+ */
@NotNull
public Date getTimestamp() {
return myTimestamp;
}
+ /**
+ * Returns changeset summary specified by user
+ * @return changeset summary
+ */
public String getSummary() {
return mySummary;
}
diff -r d787c696225c -r 40b2cf04cd4b mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ModifiedFile.java
--- a/mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ModifiedFile.java Wed Jul 16 01:48:22 2008 +0400
+++ b/mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ModifiedFile.java Wed Jul 16 17:37:41 2008 +0400
@@ -2,7 +2,13 @@
import org.jetbrains.annotations.NotNull;
+/**
+ * Represents repository modified file
+ */
public class ModifiedFile {
+ /**
+ * Type of modification
+ */
public static enum Status {
ADDED("added"),
MODIFIED("modified"),
@@ -28,11 +34,19 @@
myPath = path;
}
+ /**
+ * Returns type of modification
+ * @return type of modification
+ */
@NotNull
public Status getStatus() {
return myStatus;
}
+ /**
+ * Returns file path
+ * @return file path
+ */
@NotNull
public String getPath() {
return myPath;
diff -r d787c696225c -r 40b2cf04cd4b mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java
--- a/mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java Wed Jul 16 01:48:22 2008 +0400
+++ b/mercurial/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java Wed Jul 16 17:37:41 2008 +0400
@@ -7,6 +7,9 @@
import java.io.File;
+/**
+ * Represents Mercurial repository settings
+ */
public class Settings {
private String myRepository;
private String myHgCommandPath;
@@ -26,11 +29,19 @@
myRepository = repository;
}
+ /**
+ * Returns repository path
+ * @return repository path
+ */
@NotNull
public String getRepository() {
return myRepository;
}
+ /**
+ * Returns path to hg command
+ * @return path to hg command
+ */
@NotNull
public String getHgCommandPath() {
return myHgCommandPath;
@@ -44,6 +55,10 @@
myWorkingDir = workingDir;
}
+ /**
+ * Returns repository working directory where all mercurial commands should be invoked
+ * @return repository working directory
+ */
@NotNull
public String getWorkingDir() {
if (myWorkingDir != null) {