Mercurial > hg > mercurial
changeset 299:e9e7d9fcf57d
Use customized xml output from the 'hg log' command instead of running 'hg status' for every commit
line wrap: on
line diff
--- a/mercurial-common/mercurial-common.iml Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial-common/mercurial-common.iml Thu Sep 08 12:56:56 2011 +0400 @@ -10,6 +10,7 @@ <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="library" exported="" name="TeamCityAPI-common" level="project" /> <orderEntry type="library" exported="" name="IDEA-openapi" level="project" /> + <orderEntry type="library" name="jdom" level="project" /> </component> </module>
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSet.java Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSet.java Thu Sep 08 12:56:56 2011 +0400 @@ -28,8 +28,8 @@ @NotNull private String myUser; @NotNull private Date myTimestamp; private String myDescription; - private boolean myContainsFiles; private List<ChangeSetRevision> myParents = new ArrayList<ChangeSetRevision>(); + private List<ModifiedFile> myModifiedFiles = new ArrayList<ModifiedFile>(); public ChangeSet(final int revNumber, @NotNull final String id) { super(revNumber, id); @@ -55,10 +55,6 @@ myDescription = description; } - public void setContainsFiles(final boolean containsFiles) { - myContainsFiles = containsFiles; - } - public void addParent(@NotNull ChangeSetRevision rev) { myParents.add(rev); } @@ -99,19 +95,19 @@ } /** - * Returns true if this change has changed files - * @return see above - */ - public boolean containsFiles() { - return myContainsFiles; - } - - - /** * Check if changeset is initial changeset (has no parents) * @return true if changeset is initial changeset */ public boolean isInitial() { - return getParents() == null; + return getParents().isEmpty(); + } + + public void setModifiedFiles(@NotNull final List<ModifiedFile> files) { + myModifiedFiles = files; + } + + @NotNull + public List<ModifiedFile> getModifiedFiles() { + return myModifiedFiles; } }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java Thu Sep 08 12:56:56 2011 +0400 @@ -104,7 +104,7 @@ removePrivateData(privateData, res); CommandUtil.checkCommandFailed(cmdStr, res); - Loggers.VCS.debug(res.getStdout()); + Loggers.VCS.debug("Command " + cmdStr + " output:\n" + res.getStdout()); return res; }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java Thu Sep 08 12:56:56 2011 +0400 @@ -16,12 +16,16 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.JDOMUtil; import jetbrains.buildServer.ExecResult; import jetbrains.buildServer.vcs.VcsException; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; import java.io.File; +import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -31,26 +35,20 @@ public class LogCommand extends VcsRootCommand { - private final static Logger LOG = Logger.getInstance(LogCommand.class.getName()); private final static String ZERO_PARENT_ID = "0000000000000000000000000000000000000000"; + private static final String DATE_FORMAT = "EEE MMM d HH:mm:ss yyyy Z"; private String myFromId; private String myToId; - private ArrayList<String> myPaths; private Integer myLimit = null; - private static final String CHANGESET_PREFIX = "changeset:"; - private static final String USER_PREFIX = "user:"; - private static final String PARENT_PREFIX = "parent:"; - private static final String DATE_PREFIX = "date:"; - private static final String DATE_FORMAT = "EEE MMM d HH:mm:ss yyyy Z"; - private static final String DESCRIPTION_PREFIX = "description:"; - private static final String FILES_PREFIX = "files:"; private String myBranchName; private boolean myCalculateParents = true; private String myRevsets; + private final File myTemplate; - public LogCommand(@NotNull Settings settings, @NotNull File workingDir) { + public LogCommand(@NotNull Settings settings, @NotNull File workingDir, @NotNull final File template) { super(settings, workingDir); + myTemplate = template; myBranchName = settings.getBranchName(); } @@ -62,10 +60,6 @@ myToId = id; } - public void setPaths(final List<String> relPaths) { - myPaths = new ArrayList<String>(relPaths); - } - public void setLimit(final int limit) { myLimit = limit; } @@ -86,8 +80,7 @@ GeneralCommandLine cli = createCommandLine(); cli.addParameter("log"); cli.addParameter("-v"); - cli.addParameter("--style"); - cli.addParameter("default"); + cli.addParameter("--style=" + myTemplate.getAbsolutePath()); if (myBranchName != null) { cli.addParameter("-b"); cli.addParameter(getSettings().getBranchName()); @@ -104,98 +97,122 @@ cli.addParameter("--limit"); cli.addParameter(myLimit.toString()); } - if (myPaths != null) { - for (String path: myPaths) { - cli.addParameter(path); - } - } ExecResult res = runCommand(cli); - List<ChangeSet> csets = parseChangeSets(res.getStdout()); - if (myCalculateParents) - assignTrivialParents(csets); - return csets; + try { + List<ChangeSet> changes = parseChangeSetsXml(res.getStdout()); + if (myCalculateParents) + assignTrivialParents(changes); + return changes; + } catch (Exception e) { + throw new VcsException("Error while parsing log output:\n" + res.getStdout(), e); + } } - public static List<ChangeSet> parseChangeSets(final String stdout) { - List<ChangeSet> result = new ArrayList<ChangeSet>(); - String[] lines = stdout.split("\n"); - ChangeSet current = null; - int lineNum = 0; - boolean insideDescription = false; - StringBuilder descr = new StringBuilder(); - while (lineNum < lines.length) { - String line = lines[lineNum]; - lineNum++; - if (line.startsWith(CHANGESET_PREFIX)) { - insideDescription = false; - if (current != null) { - current.setDescription(descr.toString().trim()); - descr.setLength(0); - } - - String revAndId = line.substring(CHANGESET_PREFIX.length()).trim(); - try { - current = new ChangeSet(revAndId); - result.add(current); - } catch (IllegalArgumentException e) { - LOG.warn("Unable to extract changeset id from the line: " + line); - } - - continue; - } - - if (current == null) continue; - - if (line.startsWith(USER_PREFIX)) { - current.setUser(line.substring(USER_PREFIX.length()).trim()); - continue; - } + private List<ChangeSet> parseChangeSetsXml(@NotNull final String xml) throws JDOMException, IOException, ParseException { + Document doc = JDOMUtil.loadDocument(xml); + Element log = doc.getRootElement(); + return parseLog(log); + } - if (line.startsWith(FILES_PREFIX)) { - current.setContainsFiles(true); - continue; - } - if (line.startsWith(PARENT_PREFIX)) { - String parentRev = line.substring(PARENT_PREFIX.length()).trim(); - current.addParent(new ChangeSetRevision(parentRev)); - continue; - } - - if (line.startsWith(DATE_PREFIX)) { - String date = line.substring(DATE_PREFIX.length()).trim(); - try { - Date parsedDate = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH).parse(date); - current.setTimestamp(parsedDate); - } catch (ParseException e) { - LOG.warn("Unable to parse date: " + date); - current = null; - } - - continue; - } - - if (line.startsWith(DESCRIPTION_PREFIX)) { - insideDescription = true; - continue; - } - - if (insideDescription) { - descr.append(line).append("\n"); - } + private List<ChangeSet> parseLog(@NotNull final Element logElement) throws ParseException { + List<ChangeSet> result = new ArrayList<ChangeSet>(); + for (Object o : logElement.getChildren("logentry")) { + Element entry = (Element) o; + result.add(parseLogEntry(entry)); } - - if (insideDescription) { - current.setDescription(descr.toString().trim()); - } - return result; } - private void assignTrivialParents(List<ChangeSet> csets) throws VcsException { + private ChangeSet parseLogEntry(@NotNull final Element logEntry) throws ParseException { + ChangeSet cset = new ChangeSet(getRevision(logEntry), getId(logEntry)); + addParents(cset, logEntry); + cset.setUser(getAuthor(logEntry)); + cset.setDescription(getDescription(logEntry)); + cset.setTimestamp(getDate(logEntry)); + cset.setModifiedFiles(getModifiedFiles(logEntry)); + return cset; + } + + + private int getRevision(@NotNull final Element logEntry) { + return Integer.parseInt(logEntry.getAttribute("revision").getValue()); + } + + + private String getId(@NotNull final Element logEntry) { + return logEntry.getAttribute("shortnode").getValue(); + } + + + private void addParents(@NotNull final ChangeSet cset, @NotNull final Element logEntry) { + List parents = logEntry.getChildren("parent"); + for (Object p : parents) { + Element parent = (Element) p; + ChangeSetRevision parentCset = getParent(parent); + cset.addParent(parentCset); + } + } + + + private ChangeSetRevision getParent(@NotNull final Element parent) { + return new ChangeSetRevision(getRevision(parent), getId(parent)); + } + + + private String getAuthor(@NotNull final Element logEntry) { + Element author = logEntry.getChild("author"); + return author.getAttribute("original").getValue(); + } + + + private String getDescription(@NotNull final Element logEntry) { + Element msg = logEntry.getChild("msg"); + return msg.getText(); + } + + + private Date getDate(@NotNull final Element logEntry) throws ParseException { + Element date = logEntry.getChild("date"); + return new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH).parse(date.getText()); + } + + + private List<ModifiedFile> getModifiedFiles(@NotNull final Element logEntry) { + List<ModifiedFile> result = new ArrayList<ModifiedFile>(); + Element paths = logEntry.getChild("paths"); + for (Object o : paths.getChildren("path")) { + Element path = (Element) o; + result.add(getModifiedFile(path)); + } + return result; + } + + + private ModifiedFile getModifiedFile(@NotNull final Element path) { + String filePath = path.getText(); + ModifiedFile.Status status = getStatus(path); + return new ModifiedFile(status, filePath); + } + + + private ModifiedFile.Status getStatus(@NotNull final Element path) { + String action = path.getAttribute("action").getValue(); + if (action.equals("A")) { + return ModifiedFile.Status.ADDED; + } else if (action.equals("M")) { + return ModifiedFile.Status.MODIFIED; + } else if (action.equals("R")) { + return ModifiedFile.Status.REMOVED; + } else { + return ModifiedFile.Status.UNKNOWN; + } + } + + private void assignTrivialParents(final @NotNull List<ChangeSet> csets) throws VcsException { for (ChangeSet cset : csets) { if (cset.getParents().isEmpty()) { int parentRevNumber = cset.getRevNumber() - 1; @@ -218,5 +235,4 @@ return output; } } - }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-server/resources/buildServerResources/log.template Thu Sep 08 12:56:56 2011 +0400 @@ -0,0 +1,17 @@ +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' + +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}" 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/CommandFactory.java Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CommandFactory.java Thu Sep 08 12:56:56 2011 +0400 @@ -1,27 +1,33 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.LogCommand; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.MergeBaseCommand; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.Settings; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.VersionCommand; import jetbrains.buildServer.serverSide.ServerPaths; +import jetbrains.buildServer.util.FileUtil; import jetbrains.buildServer.vcs.VcsException; import org.jetbrains.annotations.NotNull; import java.io.File; +import java.io.IOException; /** * @author dmitry.neverov */ -public class CommandFactory { +public final class CommandFactory { //hg version which supports revsets private final static HgVersion REVSET_HG_VERSION = new HgVersion(1, 7, 0); + private final static String LOG_TEMPLATE_NAME = "log.template"; private final File myDefaultWorkingDir; + private final File myLogTemplate; - public CommandFactory(@NotNull final ServerPaths paths) { + public CommandFactory(@NotNull final ServerPaths paths) throws IOException { myDefaultWorkingDir = new File(paths.getCachesDir(), "mercurial"); + myLogTemplate = createLogTemplate(paths.getPluginDataDirectory()); } @@ -30,9 +36,23 @@ VersionCommand versionCommand = new VersionCommand(settings, myDefaultWorkingDir); HgVersion hgVersion = versionCommand.execute(); if (hgVersion.isEqualsOrGreaterThan(REVSET_HG_VERSION)) - return new MergeBaseWithRevsets(settings, workingDir); + return new MergeBaseWithRevsets(settings, workingDir, this); else - return new MergeBaseNoRevsets(settings, workingDir); + return new MergeBaseNoRevsets(settings, workingDir, this); } + + @NotNull + public LogCommand createLog(@NotNull final Settings settings, @NotNull final File workingDir) { + return new LogCommand(settings, workingDir, myLogTemplate); + } + + + private File createLogTemplate(@NotNull final File templateFileDir) throws IOException { + File template = new File(templateFileDir, LOG_TEMPLATE_NAME); + if (!template.exists()) { + FileUtil.copyResource(CommandFactory.class, "/buildServerResources/log.template", template); + } + return template; + } }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Thu Sep 08 12:56:56 2011 +0400 @@ -119,13 +119,6 @@ } } - private Collection<ModifiedFile> computeModifiedFilesForMergeCommit(final Settings settings, final ChangeSet cur) throws VcsException { - File workingDir = getWorkingDir(settings); - ChangedFilesCommand cfc = new ChangedFilesCommand(settings, workingDir); - cfc.setRevId(cur.getId()); - return cfc.execute(); - } - private List<VcsChange> toVcsChanges(final List<ModifiedFile> modifiedFiles, String prevVer, String curVer, CheckoutRules rules) { List<VcsChange> files = new ArrayList<VcsChange>(); for (ModifiedFile mf: modifiedFiles) { @@ -518,7 +511,7 @@ if (mergeBase == null) return null; - LogCommand lc = new LogCommand(settings, getWorkingDir(settings)); + LogCommand lc = myCommandFactory.createLog(settings, getWorkingDir(settings)); lc.setFromRevId(new ChangeSetRevision(mergeBase).getId()); lc.setToRevId(new ChangeSetRevision(branchVersion).getId()); lc.showCommitsFromAllBranches(); @@ -561,7 +554,7 @@ @NotNull private String getMinusNthCommit(@NotNull Settings settings, int n) throws VcsException { - LogCommand log = new LogCommand(settings, getWorkingDir(settings)); + LogCommand log = myCommandFactory.createLog(settings, getWorkingDir(settings)); log.setFromRevId(settings.getBranchName()); if (n > 0) log.setLimit(n); @@ -581,10 +574,11 @@ // first obtain changes between specified versions List<ModificationData> result = new ArrayList<ModificationData>(); - if (currentVersion == null) return result; + if (currentVersion == null) + return result; File workingDir = getWorkingDir(settings); - LogCommand lc = new LogCommand(settings, workingDir); + LogCommand lc = myCommandFactory.createLog(settings, workingDir); String fromId = new ChangeSetRevision(fromVersion).getId(); lc.setFromRevId(fromId); lc.setToRevId(new ChangeSetRevision(currentVersion).getId()); @@ -593,32 +587,20 @@ return result; } - // invoke status command for each changeset and determine what files were modified in these changesets - StatusCommand st = new StatusCommand(settings, workingDir); ChangeSet prev = new ChangeSet(fromVersion); for (ChangeSet cur : changeSets) { - if (cur.getId().equals(fromId)) continue; // skip already reported changeset + if (cur.getId().equals(fromId)) + continue; // skip already reported changeset List<ChangeSetRevision> curParents = cur.getParents(); boolean mergeCommit = curParents.size() > 1; - List<ModifiedFile> modifiedFiles = new ArrayList<ModifiedFile>(); - if (mergeCommit) { - modifiedFiles.addAll(computeModifiedFilesForMergeCommit(settings, cur)); - } else { - if (!curParents.isEmpty()) - st.setFromRevId(curParents.get(0).getId()); - st.setToRevId(cur.getId()); - modifiedFiles.addAll(st.execute()); - } - - // changeset full version will be set into VcsChange structure and - // stored in database (note that getContent method will be invoked with this version) + List<ModifiedFile> modifiedFiles = cur.getModifiedFiles(); List<VcsChange> files = toVcsChanges(modifiedFiles, prev.getFullVersion(), cur.getFullVersion(), checkoutRules); - if (files.isEmpty() && !mergeCommit) continue; + if (files.isEmpty() && !mergeCommit) + continue; ModificationData md = new ModificationData(cur.getTimestamp(), files, cur.getDescription(), cur.getUser(), root, cur.getFullVersion(), cur.getId()); - if (mergeCommit) { + if (mergeCommit) md.setCanBeIgnored(false); - } result.add(md); prev = cur; }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MergeBaseNoRevsets.java Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MergeBaseNoRevsets.java Thu Sep 08 12:56:56 2011 +0400 @@ -15,20 +15,21 @@ * Implementation of merge-base for hg versions which don't have revsets * @author dmitry.neverov */ -public class MergeBaseNoRevsets implements MergeBaseCommand { +public final class MergeBaseNoRevsets implements MergeBaseCommand { private final Settings mySettings; private final File myWorkingDir; - + private final CommandFactory myCommandFactory; - public MergeBaseNoRevsets(@NotNull final Settings settings, @NotNull File workingDir) { + public MergeBaseNoRevsets(@NotNull final Settings settings, @NotNull final File workingDir, @NotNull final CommandFactory commandFactory) { mySettings = settings; myWorkingDir = workingDir; + myCommandFactory = commandFactory; } @Nullable - public String execute(@NotNull String revision1, @NotNull String revision2) { + public String execute(@NotNull final String revision1, @NotNull final String revision2) { if (revision1.equals(revision2)) return revision1; try { @@ -44,8 +45,8 @@ } - private List<ChangeSet> getRevisionsReachableFrom(@NotNull String revision) throws VcsException { - LogCommand log = new LogCommand(mySettings, myWorkingDir); + private List<ChangeSet> getRevisionsReachableFrom(@NotNull final String revision) throws VcsException { + LogCommand log = myCommandFactory.createLog(mySettings, myWorkingDir); log.setFromRevId(new ChangeSetRevision(revision).getId()); log.showCommitsFromAllBranches(); log.setToRevId("0");
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MergeBaseWithRevsets.java Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MergeBaseWithRevsets.java Thu Sep 08 12:56:56 2011 +0400 @@ -11,19 +11,21 @@ * Implementation of merge-base using hg revsets * @author dmitry.neverov */ -public class MergeBaseWithRevsets implements MergeBaseCommand { +public final class MergeBaseWithRevsets implements MergeBaseCommand { private final Settings mySettings; private final File myWorkingDir; + private final CommandFactory myCommandFactory; - public MergeBaseWithRevsets(@NotNull Settings settings, @NotNull File workingDir) { + public MergeBaseWithRevsets(@NotNull final Settings settings, @NotNull final File workingDir, @NotNull final CommandFactory commandFactory) { mySettings = settings; myWorkingDir = workingDir; + myCommandFactory = commandFactory; } - public String execute(@NotNull String revision1, @NotNull String revision2) throws VcsException { + public String execute(@NotNull final String revision1, @NotNull final String revision2) throws VcsException { try { - LogCommand log = new LogCommand(mySettings, myWorkingDir); + LogCommand log = myCommandFactory.createLog(mySettings, myWorkingDir); log.setRevsets("ancestor(" + new ChangeSetRevision(revision1).getId() + ", " + new ChangeSetRevision(revision2).getId() + ")"); log.showCommitsFromAllBranches(); log.setCalculateParents(false);
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java Thu Sep 08 12:56:56 2011 +0400 @@ -475,11 +475,11 @@ private void assertFiles(final List<String> expectedFiles, final ModificationData modificationData) { - List<String> actualFiles = new ArrayList<String>(); + Set<String> actualFiles = new HashSet<String>(); for (VcsChange vc: modificationData.getChanges()) { actualFiles.add(toFileStatus(vc.getType()) + " " + vc.getRelativeFileName()); } - Assert.assertEquals("Actual files: " + actualFiles.toString(), expectedFiles, actualFiles); + Assert.assertEquals("Actual files: " + actualFiles.toString(), new HashSet<String>(expectedFiles), actualFiles); } private String toFileStatus(VcsChange.Type type) {
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommandTest.java Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommandTest.java Thu Sep 08 12:56:56 2011 +0400 @@ -15,8 +15,12 @@ */ package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; +import jetbrains.buildServer.TempFiles; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialVcsSupport; +import jetbrains.buildServer.util.FileUtil; import jetbrains.buildServer.vcs.VcsException; import org.jetbrains.annotations.NotNull; +import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -26,13 +30,27 @@ @Test public class LogCommandTest extends BaseCommandTestCase { + + private TempFiles myTempFiles = new TempFiles(); + private File myTemplateFile; + + @BeforeMethod @Override protected void setUp() throws Exception { super.setUp(); setRepository("mercurial-tests/testData/rep1", true); + myTemplateFile = myTempFiles.createTempFile(); + FileUtil.copyResource(MercurialVcsSupport.class, "/buildServerResources/log.template", myTemplateFile); } + + @AfterMethod + public void tearDown() { + myTempFiles.cleanup(); + } + + public void testOneChangeSet() throws Exception { final String toId = "9875b412a788"; List<ChangeSet> changes = runLog(null, toId); @@ -83,10 +101,37 @@ "bbb", changes.get(0).getDescription()); } + + public void log_result_should_contain_changed_files() throws Exception { + final String fromId = "7209b1f1d793"; + final String toId = "b06a290a363b"; + List<ChangeSet> csets = runLog(fromId, toId); + assertEquals(3, csets.size()); + + List<ModifiedFile> files = csets.get(0).getModifiedFiles(); + assertEquals(1, files.size()); + ModifiedFile file = files.get(0); + assertEquals(ModifiedFile.Status.ADDED, file.getStatus()); + assertEquals("dir1/file4.txt", file.getPath()); + + files = csets.get(1).getModifiedFiles(); + assertEquals(1, files.size()); + file = files.get(0); + assertEquals(ModifiedFile.Status.REMOVED, file.getStatus()); + assertEquals("dir1/file4.txt", file.getPath()); + + files = csets.get(2).getModifiedFiles(); + assertEquals(1, files.size()); + file = files.get(0); + assertEquals(ModifiedFile.Status.MODIFIED, file.getStatus()); + assertEquals("dir1/file3.txt", file.getPath()); + } + + private List<ChangeSet> runLog(final String fromId, final String toId) throws IOException, VcsException { return runCommand(new CommandExecutor<List<ChangeSet>>() { public List<ChangeSet> execute(@NotNull final Settings settings, @NotNull File workingDir) throws VcsException { - LogCommand lc = new LogCommand(settings, workingDir); + LogCommand lc = new LogCommand(settings, workingDir, myTemplateFile); lc.setFromRevId(fromId); lc.setToRevId(toId); return lc.execute();
--- a/mercurial.ipr Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial.ipr Thu Sep 08 12:56:56 2011 +0400 @@ -53,6 +53,7 @@ <entry name="?*.tld" /> <entry name="?*.jsp" /> <entry name="?*.tag" /> + <entry name="?*.template" /> </wildcardResourcePatterns> <annotationProcessing enabled="false" useClasspath="true" /> </component> @@ -390,6 +391,13 @@ <JAVADOC /> <SOURCES /> </library> + <library name="jdom"> + <CLASSES> + <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/jdom.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + </library> <library name="JMock"> <CLASSES> <root url="jar://$PROJECT_DIR$/mercurial-tests/lib/hamcrest-library-1.1.jar!/" />
--- a/mercurial.xml Thu Sep 08 11:27:21 2011 +0400 +++ b/mercurial.xml Thu Sep 08 12:56:56 2011 +0400 @@ -36,6 +36,8 @@ <exclude name="**/*.orig/**"/> <exclude name="**/*.lib/**"/> <exclude name="**/*~/**"/> + <exclude name="**/__pycache__/**"/> + <exclude name="**/.bundle/**"/> </patternset> <patternset id="library.patterns"> <include name="*.zip"/> @@ -57,6 +59,7 @@ <include name="**/?*.tld"/> <include name="**/?*.jsp"/> <include name="**/?*.tag"/> + <include name="**/?*.template"/> </patternset> <!-- JDK definitions --> @@ -92,6 +95,10 @@ <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/util.jar"/> </path> + <path id="library.jdom.classpath"> + <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/jdom.jar"/> + </path> + <path id="library.jmock.classpath"> <pathelement location="${basedir}/mercurial-tests/lib/hamcrest-core-1.1.jar"/> <pathelement location="${basedir}/mercurial-tests/lib/hamcrest-library-1.1.jar"/> @@ -216,12 +223,14 @@ <path refid="${module.jdk.classpath.mercurial-common}"/> <path refid="library.teamcityapi-common.classpath"/> <path refid="library.idea-openapi.classpath"/> + <path refid="library.jdom.classpath"/> </path> <path id="mercurial-common.runtime.production.module.classpath"> <pathelement location="${mercurial-common.output.dir}"/> <path refid="library.teamcityapi-common.classpath"/> <path refid="library.idea-openapi.classpath"/> + <path refid="library.jdom.classpath"/> </path> <path id="mercurial-common.module.classpath"> @@ -229,12 +238,14 @@ <pathelement location="${mercurial-common.output.dir}"/> <path refid="library.teamcityapi-common.classpath"/> <path refid="library.idea-openapi.classpath"/> + <path refid="library.jdom.classpath"/> </path> <path id="mercurial-common.runtime.module.classpath"> <pathelement location="${mercurial-common.output.dir}"/> <path refid="library.teamcityapi-common.classpath"/> <path refid="library.idea-openapi.classpath"/> + <path refid="library.jdom.classpath"/> </path> @@ -313,6 +324,7 @@ <pathelement location="${mercurial-common.output.dir}"/> <path refid="library.teamcityapi-common.classpath"/> <path refid="library.idea-openapi.classpath"/> + <path refid="library.jdom.classpath"/> </path> <path id="mercurial-agent.module.classpath"> @@ -330,6 +342,7 @@ <pathelement location="${mercurial-common.output.dir}"/> <path refid="library.teamcityapi-common.classpath"/> <path refid="library.idea-openapi.classpath"/> + <path refid="library.jdom.classpath"/> </path> @@ -410,6 +423,7 @@ <path refid="library.log4j.classpath"/> <pathelement location="${mercurial-common.output.dir}"/> <path refid="library.teamcityapi-common.classpath"/> + <path refid="library.jdom.classpath"/> </path> <path id="mercurial-server.module.classpath"> @@ -429,6 +443,7 @@ <path refid="library.log4j.classpath"/> <pathelement location="${mercurial-common.output.dir}"/> <path refid="library.teamcityapi-common.classpath"/> + <path refid="library.jdom.classpath"/> </path> @@ -523,6 +538,7 @@ <path refid="library.log4j.classpath"/> <pathelement location="${mercurial-common.output.dir}"/> <path refid="library.teamcityapi-common.classpath"/> + <path refid="library.jdom.classpath"/> <path refid="library.junit.classpath"/> <path refid="library.testng.classpath"/> <path refid="library.jmock.classpath"/> @@ -558,6 +574,7 @@ <path refid="library.log4j.classpath"/> <pathelement location="${mercurial-common.output.dir}"/> <path refid="library.teamcityapi-common.classpath"/> + <path refid="library.jdom.classpath"/> <path refid="library.junit.classpath"/> <path refid="library.testng.classpath"/> <path refid="library.jmock.classpath"/>