# HG changeset patch # User Artem Tikhomirov # Date 1296271033 -3600 # Node ID dd4d2d0e42cd0db4571bf34b8f3d8a0a22cace2a # Parent 0c98048570005c6418ca18b8661607f8af7eaff4 Handler for StatusCommand to get notifications in the form of HgStatus object diff -r 0c9804857000 -r dd4d2d0e42cd TODO --- a/TODO Sat Jan 29 02:31:09 2011 +0100 +++ b/TODO Sat Jan 29 04:17:13 2011 +0100 @@ -26,10 +26,17 @@ + glob + pattern -+ Tests with JUnit ++ Tests with JUnit + - allow to specify repo location (system property) + - keep a .zip of repo along with tests * tags * Tags are read and can be queried (cmdline Log does) + +- keywords + +- newlines + Proposed: - LogCommand.revision(int... rev)+ to walk selected revisions only (list->sort(array) on execute, binary search) diff -r 0c9804857000 -r dd4d2d0e42cd src/org/tmatesoft/hg/core/StatusCommand.java --- a/src/org/tmatesoft/hg/core/StatusCommand.java Sat Jan 29 02:31:09 2011 +0100 +++ b/src/org/tmatesoft/hg/core/StatusCommand.java Sat Jan 29 04:17:13 2011 +0100 @@ -16,17 +16,16 @@ */ package org.tmatesoft.hg.core; -import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION; -import static org.tmatesoft.hg.repo.HgRepository.TIP; -import static org.tmatesoft.hg.repo.HgRepository.WORKING_COPY; +import static org.tmatesoft.hg.core.StatusCommand.HgStatus.Kind.*; +import static org.tmatesoft.hg.repo.HgRepository.*; import java.util.ConcurrentModificationException; -import org.tmatesoft.hg.core.LogCommand.FileRevision; import org.tmatesoft.hg.core.Path.Matcher; +import org.tmatesoft.hg.core.StatusCommand.HgStatus.Kind; import org.tmatesoft.hg.repo.HgRepository; +import org.tmatesoft.hg.repo.HgStatusCollector; import org.tmatesoft.hg.repo.HgStatusInspector; -import org.tmatesoft.hg.repo.HgStatusCollector; import org.tmatesoft.hg.repo.HgWorkingCopyStatusCollector; /** @@ -41,7 +40,7 @@ private int endRevision = WORKING_COPY; private boolean visitSubRepo = true; - private HgStatusInspector visitor; + private Handler handler; private final Mediator mediator = new Mediator(); public StatusCommand(HgRepository hgRepo) { @@ -143,14 +142,14 @@ * @throws IllegalArgumentException if handler is null * @throws ConcurrentModificationException if this command already runs (i.e. being used from another thread) */ - public void execute(final HgStatusInspector handler) { - if (handler == null) { + public void execute(Handler statusHandler) { + if (statusHandler == null) { throw new IllegalArgumentException(); } - if (visitor != null) { + if (handler != null) { throw new ConcurrentModificationException(); } - visitor = handler; + handler = statusHandler; HgStatusCollector sc = new HgStatusCollector(repo); // TODO from CommandContext // PathPool pathHelper = new PathPool(repo.getPathHelper()); // TODO from CommandContext try { @@ -170,10 +169,50 @@ } } finally { mediator.done(); - visitor = null; + handler = null; } } + public interface Handler { + void handleStatus(HgStatus s); + } + + public static class HgStatus { + public enum Kind { + Modified, Added, Removed, Unknown, Missing, Clean, Ignored + }; + private final Kind kind; + private final Path path; + private final Path origin; + + HgStatus(Kind kind, Path path) { + this(kind, path, null); + } + + HgStatus(Kind kind, Path path, Path copyOrigin) { + this.kind = kind; + this.path = path; + origin = copyOrigin; + } + + public Kind getKind() { + return kind; + } + + public Path getPath() { + return path; + } + + public Path getOriginalPath() { + return origin; + } + + public boolean isCopy() { + return origin != null; + } + } + + private class Mediator implements HgStatusInspector { boolean needModified; boolean needAdded; @@ -197,56 +236,56 @@ public void modified(Path fname) { if (needModified) { if (matcher == null || matcher.accept(fname)) { - visitor.modified(fname); + handler.handleStatus(new HgStatus(Modified, fname)); } } } public void added(Path fname) { if (needAdded) { if (matcher == null || matcher.accept(fname)) { - visitor.added(fname); + handler.handleStatus(new HgStatus(Added, fname)); } } } public void removed(Path fname) { if (needRemoved) { if (matcher == null || matcher.accept(fname)) { - visitor.removed(fname); + handler.handleStatus(new HgStatus(Removed, fname)); } } } public void copied(Path fnameOrigin, Path fnameAdded) { if (needCopies) { if (matcher == null || matcher.accept(fnameAdded)) { - visitor.copied(fnameOrigin, fnameAdded); + handler.handleStatus(new HgStatus(Kind.Added, fnameAdded, fnameOrigin)); } } } public void missing(Path fname) { if (needMissing) { if (matcher == null || matcher.accept(fname)) { - visitor.missing(fname); + handler.handleStatus(new HgStatus(Missing, fname)); } } } public void unknown(Path fname) { if (needUnknown) { if (matcher == null || matcher.accept(fname)) { - visitor.unknown(fname); + handler.handleStatus(new HgStatus(Unknown, fname)); } } } public void clean(Path fname) { if (needClean) { if (matcher == null || matcher.accept(fname)) { - visitor.clean(fname); + handler.handleStatus(new HgStatus(Clean, fname)); } } } public void ignored(Path fname) { if (needIgnored) { if (matcher == null || matcher.accept(fname)) { - visitor.ignored(fname); + handler.handleStatus(new HgStatus(Ignored, fname)); } } } diff -r 0c9804857000 -r dd4d2d0e42cd test/org/tmatesoft/hg/test/TestStatus.java --- a/test/org/tmatesoft/hg/test/TestStatus.java Sat Jan 29 02:31:09 2011 +0100 +++ b/test/org/tmatesoft/hg/test/TestStatus.java Sat Jan 29 04:17:13 2011 +0100 @@ -17,6 +17,7 @@ package org.tmatesoft.hg.test; import static org.hamcrest.CoreMatchers.equalTo; +import static org.tmatesoft.hg.core.StatusCommand.HgStatus.Kind.*; import static org.tmatesoft.hg.repo.HgRepository.TIP; import java.util.Collection; @@ -24,12 +25,16 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import org.junit.Assume; import org.junit.Rule; import org.junit.Test; import org.tmatesoft.hg.core.Path; import org.tmatesoft.hg.core.StatusCommand; +import org.tmatesoft.hg.core.StatusCommand.HgStatus; +import org.tmatesoft.hg.core.StatusCommand.HgStatus.Kind; import org.tmatesoft.hg.repo.HgLookup; import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.repo.HgStatusCollector; @@ -100,26 +105,47 @@ @Test public void testStatusCommand() throws Exception { final StatusCommand sc = new StatusCommand(repo).all(); - HgStatusCollector.Record r; + StatusCollector r; statusParser.reset(); eh.run("hg", "status", "-A"); - sc.execute(r = new HgStatusCollector.Record()); - report("hg status -A", r, statusParser); + sc.execute(r = new StatusCollector()); + report("hg status -A", r); // statusParser.reset(); int revision = 3; eh.run("hg", "status", "-A", "--rev", String.valueOf(revision)); - sc.base(revision).execute(r = new HgStatusCollector.Record()); - report("status -A --rev " + revision, r, statusParser); + sc.base(revision).execute(r = new StatusCollector()); + report("status -A --rev " + revision, r); // statusParser.reset(); eh.run("hg", "status", "-A", "--change", String.valueOf(revision)); - sc.base(TIP).revision(revision).execute(r = new HgStatusCollector.Record()); - report("status -A --change " + revision, r, statusParser); + sc.base(TIP).revision(revision).execute(r = new StatusCollector()); + report("status -A --change " + revision, r); // TODO check not -A, but defaults()/custom set of modifications } + private static class StatusCollector implements StatusCommand.Handler { + private final Map> map = new TreeMap>(); + + public void handleStatus(HgStatus s) { + List l = map.get(s.getKind()); + if (l == null) { + l = new LinkedList(); + map.put(s.getKind(), l); + } + l.add(s.getPath()); + } + + public List get(Kind k) { + List rv = map.get(k); + if (rv == null) { + return Collections.emptyList(); + } + return rv; + } + } + public void testRemovedAgainstNonTip() { /* status --rev N when a file added past revision N was removed ((both physically and in dirstate), but not yet committed @@ -143,14 +169,24 @@ } final long start2 = System.currentTimeMillis(); for (int i = 0; i < runs; i++) { - HgStatusCollector.Record r = new HgStatusCollector.Record(); + StatusCollector r = new StatusCollector(); new StatusCommand(repo).all().base(3).revision(80).execute(r); } final long end = System.currentTimeMillis(); System.out.printf("'hg status -A --rev 3:80', %d runs: Native client total %d (%d per run), Java client %d (%d)\n", runs, start2-start1, (start2-start1)/runs, end-start2, (end-start2)/runs); } - + private void report(String what, StatusCollector r) { + reportNotEqual(what + "#MODIFIED", r.get(Modified), statusParser.getModified()); + reportNotEqual(what + "#ADDED", r.get(Added), statusParser.getAdded()); + reportNotEqual(what + "#REMOVED", r.get(Removed), statusParser.getRemoved()); + reportNotEqual(what + "#CLEAN", r.get(Clean), statusParser.getClean()); + reportNotEqual(what + "#IGNORED", r.get(Ignored), statusParser.getIgnored()); + reportNotEqual(what + "#MISSING", r.get(Missing), statusParser.getMissing()); + reportNotEqual(what + "#UNKNOWN", r.get(Unknown), statusParser.getUnknown()); + // FIXME test copies + } + private void report(String what, HgStatusCollector.Record r, StatusOutputParser statusParser) { reportNotEqual(what + "#MODIFIED", r.getModified(), statusParser.getModified()); reportNotEqual(what + "#ADDED", r.getAdded(), statusParser.getAdded());