# HG changeset patch # User Dmitry Neverov # Date 1412500534 -7200 # Node ID 39ff04730cccc277fed6330ee465e9ace59fe072 # Parent a421a669588c3f4039b1d7991b1d2bae2b6f9f51 Report more vcs operation progress Instead of setting progress in each operation, create HgRepo via OpeationContext which adds progress to command settings. diff -r a421a669588c -r 39ff04730ccc mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java --- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java Sun Oct 05 11:15:34 2014 +0200 @@ -21,6 +21,7 @@ import java.io.File; import java.util.Set; +import static com.intellij.openapi.util.text.StringUtil.isEmpty; import static java.util.Collections.emptySet; /** @@ -56,6 +57,7 @@ final MercurialCommandLine cl = new MercurialCommandLine(getPrivateData()); cl.setExePath(myHgPath); cl.setEnvParams(myCommandSettings.getHgEnv()); + cl.setDescription(getDescription()); //include global arguments if any cl.addParameters(myCommandSettings.getGlobalArguments()); @@ -73,7 +75,15 @@ @NotNull final CommandSettings commandSettings) throws VcsException { if (!myCommandSettings.getUseCommandlineViaFileWrapper()) { - return CommandUtil.runCommand(cli, commandSettings.setPrivateData(getPrivateData())); + String commandDescription = cli.getDescription(); + if (!isEmpty(commandDescription)) + commandSettings.getProgress().reportProgress(commandDescription); + try { + return CommandUtil.runCommand(cli, commandSettings.setPrivateData(getPrivateData())); + } finally { + if (!isEmpty(commandDescription)) + commandSettings.getProgress().reportProgress(commandDescription + " finished"); + } } return CommandUtil.runWrappedCommand(cli, commandSettings); @@ -93,4 +103,9 @@ protected String getHgPath() { return myHgPath; } + + @NotNull + protected String getDescription() { + return ""; + } } diff -r a421a669588c -r 39ff04730ccc mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BookmarksCommand.java --- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BookmarksCommand.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BookmarksCommand.java Sun Oct 05 11:15:34 2014 +0200 @@ -38,4 +38,10 @@ protected String getBranchesCommand() { return "bookmarks"; } + + @NotNull + @Override + protected String getDescription() { + return "hg bookmarks"; + } } diff -r a421a669588c -r 39ff04730ccc mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BranchesCommand.java --- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BranchesCommand.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BranchesCommand.java Sun Oct 05 11:15:34 2014 +0200 @@ -64,4 +64,10 @@ protected String getBranchesCommand() { return "branches"; } + + @NotNull + @Override + protected String getDescription() { + return "hg branches"; + } } diff -r a421a669588c -r 39ff04730ccc mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommand.java --- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommand.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommand.java Sun Oct 05 11:15:34 2014 +0200 @@ -112,17 +112,31 @@ MercurialCommandLine cli = createCommandLine(tempDir); int cmdSize = cli.getCommandLineLength() + 42; + List pathsForDescription = new ArrayList(2); do { String path = paths.poll(); + if (pathsForDescription.size() < 2) + pathsForDescription.add(path); cli.addParameter(path); cmdSize += path.length() + 3; //quotes + space } while (cmdSize < myCommandSettings.getMaxCommandLineSize() && !paths.isEmpty()); + cli.setDescription(getDescription(pathsForDescription)); runCommand(cli, myCommandSettings.setCheckForFailure(checkFailure)); } } @NotNull + private String getDescription(List pathsForDescription) { + StringBuilder description = new StringBuilder(); + description.append("hg cat -r ").append(myRevId).append(" "); + for (String p : pathsForDescription) { + description.append(p).append(" "); + } + return description.toString(); + } + + @NotNull private MercurialCommandLine createCommandLine(@NotNull final File tempDir) { final MercurialCommandLine cli = createCommandLine(); addHttpAuthParams(cli); diff -r a421a669588c -r 39ff04730ccc mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CloneCommand.java --- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CloneCommand.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CloneCommand.java Sun Oct 05 11:15:34 2014 +0200 @@ -29,7 +29,6 @@ private boolean myUsePullProtocol = true; private boolean myUseUncompressedTransfer = false; private boolean myTraceback; - private ProgressParser.ProgressConsumer myProgressConsumer; public CloneCommand(@NotNull CommandSettings commandSettings, @NotNull String hgPath, @@ -77,11 +76,6 @@ return this; } - public CloneCommand withProgressConsumer(ProgressParser.ProgressConsumer progressConsumer) { - myProgressConsumer = progressConsumer; - return this; - } - public void call() throws VcsException { myWorkingDir.mkdirs(); MercurialCommandLine cli = createCommandLine(); @@ -104,12 +98,11 @@ } CommandSettings settings = myCommandSettings.setTimeout(24 * 3600); // some repositories are quite large, we set timeout to 24 hours - if (myProgressConsumer != null) { + if (settings.getProgressConsumer() != null) { cli.addParameters("--config", "extensions.progress="); cli.addParameters("--config", "progress.format=topic number"); cli.addParameters("--config", "progress.delay=0"); cli.addParameters("--config", "progress.assume-tty=True"); - settings.setProgressConsumer(myProgressConsumer); } String repositoryUrl = myAuthSettings.getRepositoryUrlWithCredentials(myRepository); diff -r a421a669588c -r 39ff04730ccc mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandSettings.java --- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandSettings.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandSettings.java Sun Oct 05 11:15:34 2014 +0200 @@ -16,8 +16,10 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialProgress; import jetbrains.buildServer.buildTriggers.vcs.mercurial.OS; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -35,8 +37,8 @@ private int myLogOutputLimit = -1; private int myExceptionOutputLimit = 5000; private List myGlobalArguments = new ArrayList(0); - private ProgressParser.ProgressConsumer myProgressConsumer; private boolean myUseCommandlineViaFileWrapper = false; + private MercurialProgress myProgress = MercurialProgress.NO_OP; public final int getMaxCommandLineSize() { return myUseCommandlineViaFileWrapper ? Integer.MAX_VALUE : OS.getMaxCommandLineSize(); @@ -135,11 +137,23 @@ myExceptionOutputLimit = limit; } + @Nullable public ProgressParser.ProgressConsumer getProgressConsumer() { - return myProgressConsumer; + if (myProgress == MercurialProgress.NO_OP) + return null; + return new ProgressParser.ProgressConsumer() { + public void consume(float progress, @NotNull String stage) { + myProgress.reportProgress(progress, stage); + } + }; } - public void setProgressConsumer(ProgressParser.ProgressConsumer progressConsumer) { - myProgressConsumer = progressConsumer; + @NotNull + public MercurialProgress getProgress() { + return myProgress; + } + + public void setProgress(@NotNull MercurialProgress progress) { + myProgress = progress; } } diff -r a421a669588c -r 39ff04730ccc mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java --- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java Sun Oct 05 11:15:34 2014 +0200 @@ -209,4 +209,19 @@ .inLocalRepository() .call(); } + + @NotNull + @Override + protected String getDescription() { + StringBuilder result = new StringBuilder(); + result.append("hg log "); + if (myRevsets != null) { + result.append(myRevsets); + } else { + String from = myFromId != null ? myFromId : "0"; + String to = myToId != null ? myToId : "tip"; + result.append(from).append(":").append(to); + } + return result.toString(); + } } \ No newline at end of file diff -r a421a669588c -r 39ff04730ccc mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/MercurialCommandLine.java --- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/MercurialCommandLine.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/MercurialCommandLine.java Sun Oct 05 11:15:34 2014 +0200 @@ -32,6 +32,7 @@ private String myWorkingDirectory; private final Set myPrivateData; private Charset myCharset; + private String myDescription = ""; public MercurialCommandLine(@NotNull final Set privateData) { myPrivateData = privateData; @@ -160,4 +161,13 @@ return cmd; } + + @NotNull + public String getDescription() { + return myDescription; + } + + public void setDescription(@NotNull String description) { + myDescription = description; + } } diff -r a421a669588c -r 39ff04730ccc mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PullCommand.java --- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PullCommand.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PullCommand.java Sun Oct 05 11:15:34 2014 +0200 @@ -33,7 +33,6 @@ private int myTimeout; private boolean myTraceback; private boolean myProfile; - private ProgressParser.ProgressConsumer myProgressConsumer; public PullCommand(@NotNull CommandSettings commandSettings, @NotNull String hgPath, @@ -67,11 +66,6 @@ return this; } - public PullCommand withProgressConsumer(ProgressParser.ProgressConsumer progressConsumer) { - myProgressConsumer = progressConsumer; - return this; - } - public void call() throws VcsException { ensureRepositoryIsNotLocked(); MercurialCommandLine cli = createCommandLine(); @@ -83,23 +77,16 @@ cli.addParameter("--profile"); CommandSettings settings = myCommandSettings.setTimeout(myTimeout); - if (myProgressConsumer != null) { + if (settings.getProgressConsumer() != null) { cli.addParameters("--config", "extensions.progress="); cli.addParameters("--config", "progress.format=topic number"); cli.addParameters("--config", "progress.delay=0"); cli.addParameters("--config", "progress.assume-tty=True"); - myProgressConsumer.consume(-1f, "hg pull " + myAuthSettings.getRepositoryUrlWithHiddenPassword(myPullUrl)); - settings.setProgressConsumer(myProgressConsumer); } String pullUrl = myAuthSettings.getRepositoryUrlWithCredentials(myPullUrl); cli.addParameter(pullUrl); - try { - runCommand(cli, settings); - } finally { - if (myProgressConsumer != null) - myProgressConsumer.consume(-1f, "hg pull " + myAuthSettings.getRepositoryUrlWithHiddenPassword(myPullUrl) + " finished"); - } + runCommand(cli, settings); } private void ensureRepositoryIsNotLocked() { @@ -112,4 +99,10 @@ private File getRepositoryLock() { return new File(getWorkDirectory(), ".hg" + File.separator + "store" + File.separator + "lock"); } + + @NotNull + @Override + protected String getDescription() { + return "hg pull " + myAuthSettings.getRepositoryUrlWithHiddenPassword(myPullUrl); + } } diff -r a421a669588c -r 39ff04730ccc mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/TagsCommand.java --- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/TagsCommand.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/TagsCommand.java Sun Oct 05 11:15:34 2014 +0200 @@ -43,4 +43,10 @@ raw.remove("tip"); return raw; } + + @NotNull + @Override + protected String getDescription() { + return "hg tags"; + } } diff -r a421a669588c -r 39ff04730ccc mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContext.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContext.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CollectChangesContext.java Sun Oct 05 11:15:34 2014 +0200 @@ -19,7 +19,6 @@ import com.intellij.openapi.util.Pair; import gnu.trove.TLongObjectHashMap; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; -import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.ProgressParser; import jetbrains.buildServer.util.Hash; import jetbrains.buildServer.util.graph.BFSVisitorAdapter; import jetbrains.buildServer.util.graph.DAG; @@ -39,7 +38,6 @@ public class CollectChangesContext extends OperationContext { private final Set myUninterestingRevisions; - private final RepositoryStateData myToState; private final Map> myDags = new HashMap>(); private Set mySyncedDirs = new HashSet(); private Map> myProcessedSubrepoChanges = new HashMap>();//subrepo url -> processed changes intervals @@ -47,41 +45,34 @@ private Map myRepos = new HashMap(); private boolean myIncludeFromRevisions = false;//by default don't include them, they should be included only for subrepos private TLongObjectHashMap myStringPool = new TLongObjectHashMap(); - private ProgressParser.ProgressConsumer myProgressConsumer; public CollectChangesContext(@NotNull MercurialVcsSupport vcs, @NotNull RepoFactory repoFactory, @NotNull MercurialProgress progress, - @NotNull RepositoryStateData fromState, - @NotNull RepositoryStateData toState) { - this(vcs, repoFactory, progress, new HashSet(fromState.getBranchRevisions().values()), toState); + @NotNull RepositoryStateData fromState) { + this(vcs, repoFactory, progress, new HashSet(fromState.getBranchRevisions().values())); } public CollectChangesContext(@NotNull MercurialVcsSupport vcs, @NotNull RepoFactory repoFactory, @NotNull MercurialProgress progress, - @NotNull String fromVersion, - @NotNull String toVersion) { - this(vcs, repoFactory, progress, setOf(fromVersion), RepositoryStateData.createSingleVersionState(toVersion)); + @NotNull String fromVersion) { + this(vcs, repoFactory, progress, setOf(fromVersion)); } public CollectChangesContext(@NotNull MercurialVcsSupport vcs, @NotNull RepoFactory repoFactory, @NotNull MercurialProgress progress, - @NotNull Collection fromVersions, - @NotNull RepositoryStateData toState) { + @NotNull Collection fromVersions) { super(vcs, repoFactory, progress); - myToState = toState; myUninterestingRevisions = new HashSet(fromVersions); } - public void syncRepository(@NotNull HgVcsRoot root, @Nullable ProgressParser.ProgressConsumer progressConsumer) throws VcsException { + public void syncRepository(@NotNull HgVcsRoot root) throws VcsException { File dir = myVcs.getWorkingDir(root); if (mySyncedDirs.contains(dir)) return; - SyncSettings settings = new SyncSettings(VcsCallable.NO_OP); - settings.setProgressConsumer(progressConsumer); - myVcs.syncRepository(root, settings); + super.syncRepository(root); mySyncedDirs.add(dir); } @@ -116,6 +107,13 @@ return repo; } + @NotNull + @Override + public ServerHgRepo createRepo(@NotNull HgVcsRoot root) throws VcsException { + File workingDir = myVcs.getWorkingDir(root); + return createRepo(root, workingDir); + } + public boolean isReportedModification(@NotNull ModificationData m) { Set revisions = getReportedRootRevisions(m); return revisions.contains(m.getVersion()); @@ -196,15 +194,15 @@ public Collection getFromRevisionsForBranch(@NotNull HgVcsRoot root, @NotNull String fromRevision, @NotNull String toRevision, - @Nullable ProgressParser.ProgressConsumer progressConsumer) throws VcsException { - syncRepository(root, progressConsumer); + @NotNull RepositoryStateData toState) throws VcsException { + syncRepository(root); ServerHgRepo repo = createRepo(root, myVcs.getWorkingDir(root)); if (!repo.supportRevsets()) return singleton(fromRevision); Set fromRevisions = new HashSet(); - if (myToState.getBranchRevisions().size() > 1) { + if (toState.getBranchRevisions().size() > 1) { VcsRootKey rootKey = VcsRootKey.create(root); DAG dag = myDags.get(rootKey); if (dag == null) { @@ -304,13 +302,4 @@ } } } - - @Nullable - public ProgressParser.ProgressConsumer getProgressConsumer() { - return myProgressConsumer; - } - - public void setProgressConsumer(ProgressParser.ProgressConsumer progressConsumer) { - myProgressConsumer = progressConsumer; - } } diff -r a421a669588c -r 39ff04730ccc mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java Sun Oct 05 11:15:34 2014 +0200 @@ -56,15 +56,14 @@ @NotNull public RepositoryStateData getCurrentState(@NotNull VcsRoot root) throws VcsException { + final OperationContext context = new OperationContext(myVcs, myRepoFactory, createMercurialProgess()); final HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); VcsCallable> cmd = new VcsCallable>() { public Map call() throws VcsException { - return getHeads(hgRoot); + return getHeads(hgRoot, context); } }; - SyncSettings> settings = new SyncSettings>(cmd); - settings.setProgressConsumer(createProgressConsumer()); - Map revisions = myVcs.syncRepository(hgRoot, settings); + Map revisions = context.syncRepository(hgRoot, cmd); String defaultBranchName = hgRoot.getBranchName(); if (revisions.get(defaultBranchName) == null && !hgRoot.isIgnoreMissingDefaultBranch()) { throw new VcsException("Cannot find revision of the default branch '" + @@ -74,12 +73,18 @@ } @NotNull - public Map getHeads(@NotNull final HgVcsRoot hgRoot) throws VcsException { + public Map getHeads(@NotNull HgVcsRoot hgRoot) throws VcsException { boolean includeTags = myConfig.useTagsAsBranches() && hgRoot.useTagsAsBranches(); return myVcs.createRepo(hgRoot).getBranchRevisions(myConfig.bookmarksEnabled(), includeTags); } @NotNull + public Map getHeads(@NotNull HgVcsRoot hgRoot, @NotNull OperationContext context) throws VcsException { + boolean includeTags = myConfig.useTagsAsBranches() && hgRoot.useTagsAsBranches(); + return context.createRepo(hgRoot).getBranchRevisions(myConfig.bookmarksEnabled(), includeTags); + } + + @NotNull public List collectChanges(@NotNull VcsRoot fromRoot, @NotNull RepositoryStateData fromState, @NotNull VcsRoot toRoot, @@ -96,8 +101,7 @@ @NotNull CheckoutRules rules) throws VcsException { List changes = new ArrayList(); HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); - CollectChangesContext ctx = new CollectChangesContext(myVcs, myRepoFactory, createMercurialProgess(), fromState, toState); - ctx.setProgressConsumer(createProgressConsumer()); + CollectChangesContext ctx = new CollectChangesContext(myVcs, myRepoFactory, createMercurialProgess(), fromState); for (Map.Entry entry : toState.getBranchRevisions().entrySet()) { String branch = entry.getKey(); String toRevision = entry.getValue(); @@ -107,7 +111,7 @@ if (toRevision.equals(fromRevision) || fromRevision == null) continue; - Collection fromRevisions = ctx.getFromRevisionsForBranch(hgRoot, fromRevision, toRevision, ctx.getProgressConsumer()); + Collection fromRevisions = ctx.getFromRevisionsForBranch(hgRoot, fromRevision, toRevision, toState); List branchChanges = collectChanges(ctx, root, fromRevisions, toRevision, rules); for (ModificationData change : branchChanges) { if (!ctx.isReportedModification(change)) { @@ -128,9 +132,8 @@ @Nullable String toRootRevision, @NotNull CheckoutRules checkoutRules) throws VcsException { HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(toRoot); - SyncSettings settings = new SyncSettings(VcsCallable.NO_OP); - settings.setProgressConsumer(createProgressConsumer()); - myVcs.syncRepository(hgRoot, settings); + CollectChangesContext context = new CollectChangesContext(myVcs, myRepoFactory, createMercurialProgess(), fromRootRevision); + context.syncRepository(hgRoot); String toRevision = toRootRevision; if (toRevision == null) { RepositoryStateData state = myVcs.getCollectChangesPolicy().getCurrentState(toRoot); @@ -139,7 +142,7 @@ String mergeBase = getMergeBase(hgRoot, fromRootRevision, toRevision); if (mergeBase == null) return Collections.emptyList(); - return collectChanges(toRoot, mergeBase, toRootRevision, checkoutRules); + return collectChanges(context, toRoot, mergeBase, toRootRevision, checkoutRules); } @@ -149,14 +152,21 @@ @NotNull CheckoutRules checkoutRules) throws VcsException { if (currentVersion == null) return emptyList(); - CollectChangesContext ctx = new CollectChangesContext(myVcs, myRepoFactory, createMercurialProgess(), fromVersion, currentVersion); - ctx.setProgressConsumer(createProgressConsumer()); + CollectChangesContext ctx = new CollectChangesContext(myVcs, myRepoFactory, createMercurialProgess(), fromVersion); + return collectChanges(ctx, root, fromVersion, currentVersion, checkoutRules); + } + + + private List collectChanges(@NotNull CollectChangesContext ctx, + @NotNull VcsRoot root, + @NotNull String fromVersion, + @Nullable String currentVersion, + @NotNull CheckoutRules checkoutRules) throws VcsException { List changes = collectChanges(ctx, root, asList(fromVersion), currentVersion, checkoutRules); changes.addAll(getSubrepoChanges(ctx, root, changes)); return changes; } - @Nullable private String getMergeBase(@NotNull HgVcsRoot root, @NotNull String revision1, @NotNull String revision2) throws VcsException { String result = myVcs.createRepo(root).mergeBase() @@ -190,7 +200,7 @@ @Nullable String currentVersion, @NotNull CheckoutRules checkoutRules) throws VcsException { HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); - ctx.syncRepository(hgRoot, ctx.getProgressConsumer()); + ctx.syncRepository(hgRoot); List result = new ArrayList(); List csets = getChangesets(ctx, hgRoot, fromVersion, currentVersion); //When commit has no changes in subrepo configuration we can reuse @@ -212,17 +222,16 @@ if (toVersion == null) return emptyList(); List fromCommits = new ArrayList(); - for (String fromVersion : fromVersions) { - fromCommits.add(new ChangeSetRevision(fromVersion).getId()); + for (String fromVersion : fromVersions) { + fromCommits.add(new ChangeSetRevision(fromVersion).getId()); } String toCommit = new ChangeSetRevision(toVersion).getId(); try { - ServerHgRepo repo = myVcs.createRepo(ctx, root); + ServerHgRepo repo = ctx.createRepo(root); List csets = repo.collectChanges(root) .fromRevision(fromCommits) .toRevision(toCommit) .includeFromRevision(ctx.includeFromRevisions()) - .withProgressConsumer(ctx.getProgressConsumer()) .call(); if (!ctx.includeFromRevisions()) { Iterator iter = csets.iterator(); @@ -326,7 +335,7 @@ List configChanges = new ArrayList(); HgVcsRoot mainRoot = myHgVcsRootFactory.createHgRoot(m.getVcsRoot()); - ServerHgRepo repo = myVcs.createRepo(ctx, mainRoot); + ServerHgRepo repo = ctx.createRepo(mainRoot); for (HgSubrepoConfigChange c : repo.getSubrepoConfigChanges(m)) { if (!(c.subrepoUrlChanged() || c.subrepoAdded() || c.subrepoRemoved())) {//report only changes in revisions, because we collect changes only for such changes //map url and path, relative to the main repository @@ -359,7 +368,7 @@ Map attributes = new HashMap(); if (detectSubrepoChanges(mainHgRoot)) { try { - ServerHgRepo repo = myVcs.createRepo(ctx, mainHgRoot); + ServerHgRepo repo = ctx.createRepo(mainHgRoot); SubrepoRevisionAttributesBuilder attrBuilder = new SubrepoRevisionAttributesBuilder(); for (SubRepo s : repo.getSubrepositories(m).values()) { attrBuilder.addSubrepo(new SubrepoConfig(mainRoot) @@ -404,50 +413,4 @@ return MercurialProgress.NO_OP; } } - - @Nullable - private ProgressParser.ProgressConsumer createProgressConsumer() { - try { - final VcsOperationProgress progress = myProgressProvider.getProgress(); - return new VcsOperationProgressConsumer(progress); - } catch (IllegalStateException e) { - return null; - } - } - - private static class VcsOperationProgressConsumer implements ProgressParser.ProgressConsumer { - private final VcsOperationProgress myProgress; - private String myPrevMessage; - private int myPrevPercents; - public VcsOperationProgressConsumer(@NotNull VcsOperationProgress progress) { - myProgress = progress; - } - - public void consume(float progressPercents, @NotNull String stage) { - if (progressPercents < 0) { - resetPrevProgress(); - myProgress.reportProgress(stage); - } else { - int percents = (int) Math.floor(progressPercents * 100); - if (!isDuplicate(stage, percents)) { - myProgress.reportProgress(stage + " " + percents + "%"); - updatePrevProgress(stage, percents); - } - } - } - - private void resetPrevProgress() { - myPrevMessage = null; - myPrevPercents = -1; - } - - private boolean isDuplicate(@NotNull String message, int percents) { - return message.equals(myPrevMessage) && percents == myPrevPercents; - } - - private void updatePrevProgress(@NotNull String message, int percents) { - myPrevMessage = message; - myPrevPercents = percents; - } - } } diff -r a421a669588c -r 39ff04730ccc mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialFetchService.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialFetchService.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialFetchService.java Sun Oct 05 11:15:34 2014 +0200 @@ -16,7 +16,6 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.ProgressParser; import jetbrains.buildServer.vcs.CheckoutRules; import jetbrains.buildServer.vcs.FetchService; import jetbrains.buildServer.vcs.VcsException; @@ -27,30 +26,21 @@ private final MercurialVcsSupport myVcs; private final HgVcsRootFactory myHgVcsRootFactory; + private final RepoFactory myRepoFactory; public MercurialFetchService(@NotNull MercurialVcsSupport vcs, - @NotNull HgVcsRootFactory hgVcsRootFactory) { + @NotNull HgVcsRootFactory hgVcsRootFactory, + @NotNull RepoFactory repoFactory) { myVcs = vcs; myHgVcsRootFactory = hgVcsRootFactory; + myRepoFactory = repoFactory; vcs.addExtension(this); } public void fetchRepository(@NotNull VcsRoot root, @NotNull CheckoutRules rules, @NotNull FetchRepositoryCallback callback) throws VcsException { - SyncSettings settings = new SyncSettings(VcsCallable.NO_OP); - settings.setProgressConsumer(new FetchProgressConsumer(callback)); - myVcs.syncRepository(myHgVcsRootFactory.createHgRoot(root)); - } - - private class FetchProgressConsumer implements ProgressParser.ProgressConsumer { - private final FetchRepositoryCallback myCallback; - private FetchProgressConsumer(@NotNull FetchRepositoryCallback callback) { - myCallback = callback; - } - - public void consume(float progress, @NotNull String stage) { - myCallback.update(progress, stage); - } + OperationContext ctx = new OperationContext(myVcs, myRepoFactory, new MercurialFetchCallbackProgress(callback)); + ctx.syncRepository(myHgVcsRootFactory.createHgRoot(root)); } } diff -r a421a669588c -r 39ff04730ccc mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialModificationInfoBuilder.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialModificationInfoBuilder.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialModificationInfoBuilder.java Sun Oct 05 11:15:34 2014 +0200 @@ -51,8 +51,7 @@ final CollectChangesContext ctx = new CollectChangesContext(myVcs, myRepoFactory, MercurialProgress.NO_OP, - Collections.emptyList(), - RepositoryStateData.createVersionState("", Collections.emptyMap())); + Collections.emptyList()); //TODO: it's better if we call log command once (or by chunks) instead of simple for-each for (String commitId : revisions) { diff -r a421a669588c -r 39ff04730ccc mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Sun Oct 05 11:15:34 2014 +0200 @@ -553,13 +553,17 @@ } public T syncRepository(@NotNull HgVcsRoot root, @NotNull SyncSettings settings) throws VcsException { + return syncRepository(root, settings, null); + } + + public T syncRepository(@NotNull HgVcsRoot root, @NotNull SyncSettings settings, @Nullable OperationContext context) throws VcsException { boolean customWorkingDir = root.getCustomWorkingDir() != null; File workingDir = getWorkingDir(root); int attemptsLeft = 3; VcsException lastError = null; while (attemptsLeft-- > 0) { try { - return syncRepositoryOnce(root, settings, workingDir); + return syncRepositoryOnce(root, settings, workingDir, context); } catch (UnrelatedRepositoryException e) { if (customWorkingDir) throw new VcsException(e.getMessage() + ". VCS root uses a custom clone dir, manual recovery is required.", e); @@ -580,9 +584,9 @@ } - private T syncRepositoryOnce(@NotNull HgVcsRoot root, @NotNull SyncSettings settings, @NotNull File workingDir) throws VcsException { + private T syncRepositoryOnce(@NotNull HgVcsRoot root, @NotNull SyncSettings settings, @NotNull File workingDir, @Nullable OperationContext context) throws VcsException { lockWorkDir(workingDir, settings.getProgressConsumer()); - HgRepo repo = createRepo(root); + HgRepo repo = context != null ? context.createRepo(root) : createRepo(root); try { if (!repo.isValidRepository()) repo.init().call(); @@ -591,7 +595,6 @@ resetBookmarks(repo); repo.pull().fromRepository(root.getRepository()) .withTimeout(myConfig.getPullTimeout()) - .withProgressConsumer(settings.getProgressConsumer()) .withProfile(myConfig.runWithProfile(root)) .call(); return settings.getCmd().call(); @@ -779,11 +782,6 @@ } @NotNull - public ServerHgRepo createRepo(@NotNull CollectChangesContext ctx, @NotNull HgVcsRoot root) throws VcsException { - return ctx.createRepo(root, getWorkingDir(root)); - } - - @NotNull public ServerHgRepo createRepo(@NotNull HgVcsRoot root, @NotNull File customDir) throws VcsException { return myRepoFactory.createRepo(root, customDir); } diff -r a421a669588c -r 39ff04730ccc mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java Sun Oct 05 11:15:34 2014 +0200 @@ -54,6 +54,22 @@ @NotNull public ServerHgRepo createRepo(@NotNull HgVcsRoot root, @NotNull File workingDir) throws VcsException { - return myRepoFactory.createRepo(root, workingDir); + return myRepoFactory.createRepo(root, workingDir, myProgress); + } + + + public void syncRepository(@NotNull HgVcsRoot root) throws VcsException { + syncRepository(root, VcsCallable.NO_OP); + } + + public T syncRepository(@NotNull HgVcsRoot root, @NotNull VcsCallable cmd) throws VcsException { + SyncSettings settings = new SyncSettings(cmd); + return myVcs.syncRepository(root, settings, this); + } + + + @NotNull + public ServerHgRepo createRepo(@NotNull HgVcsRoot root) throws VcsException { + return myRepoFactory.createRepo(root, myVcs.getWorkingDir(root), myProgress); } } diff -r a421a669588c -r 39ff04730ccc mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RepoFactory.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RepoFactory.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RepoFactory.java Sun Oct 05 11:15:34 2014 +0200 @@ -16,10 +16,7 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.AuthSettings; -import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommandSettingsFactory; -import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommandSettingsForRoot; -import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.*; import jetbrains.buildServer.vcs.VcsException; import org.jetbrains.annotations.NotNull; @@ -58,7 +55,29 @@ return create(workingDir, myHgPathProvider.getHgPath(root), root.getAuthSettings(), myCommandSettingsFactory.forRoot(root), myConfig); } + @NotNull + public ServerHgRepo createRepo(@NotNull HgVcsRoot root, @NotNull File workingDir, @NotNull MercurialProgress progress) throws VcsException { + CommandSettingsFactory settingsFactory = myCommandSettingsFactory.forRoot(root); + return create(workingDir, myHgPathProvider.getHgPath(root), root.getAuthSettings(), new FactoryWithProgess(settingsFactory, progress), myConfig); + } + public void dispose() { } + private static class FactoryWithProgess implements CommandSettingsFactory { + private final CommandSettingsFactory myDelegate; + private final MercurialProgress myProgress; + public FactoryWithProgess(@NotNull CommandSettingsFactory delegate, @NotNull MercurialProgress progress) { + myDelegate = delegate; + myProgress = progress; + } + + @NotNull + public CommandSettings create() { + CommandSettings commandSettings = myDelegate.create(); + commandSettings.setProgress(myProgress); + return commandSettings; + } + } + } diff -r a421a669588c -r 39ff04730ccc mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesCommand.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesCommand.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesCommand.java Sun Oct 05 11:15:34 2014 +0200 @@ -29,7 +29,6 @@ protected List myFromRevisions; protected String myToRevision; protected boolean myIncludeFromRevision; - protected ProgressParser.ProgressConsumer myProgressConsumer; @NotNull public abstract List call(@NotNull List fromCommits, @NotNull String toCommit) throws VcsException; @@ -46,11 +45,6 @@ return this; } - public CollectChangesCommand withProgressConsumer(ProgressParser.ProgressConsumer progressConsumer) { - myProgressConsumer = progressConsumer; - return this; - } - public CollectChangesCommand includeFromRevision(boolean doInclude) { myIncludeFromRevision = doInclude; return this; diff -r a421a669588c -r 39ff04730ccc mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesWithRevsets.java --- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesWithRevsets.java Sun Oct 05 09:32:01 2014 +0200 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesWithRevsets.java Sun Oct 05 11:15:34 2014 +0200 @@ -52,16 +52,9 @@ revsets.append(" + ").append(from); } } - try { - if (myProgressConsumer != null) - myProgressConsumer.consume(-1f, "hg log " + revsets); - return myRepo.log(myRoot) - .showCommitsFromAllBranches() - .withRevsets(revsets.toString()) - .call(); - } finally { - if (myProgressConsumer != null) - myProgressConsumer.consume(-1f, "hg log " + revsets + " finished"); - } + return myRepo.log(myRoot) + .showCommitsFromAllBranches() + .withRevsets(revsets.toString()) + .call(); } }