changeset 886:bf83331f51f0

Report agent-side checkout progress to build log This also fixes 'hg pull' timeouts problem. In order to support custom configs we started to use 'hg init', 'hg pull' sequence instead of 'hg clone'. Need that in order to modify repository configs after 'hg init', 'hg clone' doesn't give such an opportunity. The default pull timeout wasn't enough to pull a big repository from scratch. With progress reporting the default pull timeout (1 hour) should be enough, because it is an idle timeout.
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Wed, 15 Oct 2014 06:29:39 +0200
parents 39ebb1402c18
children 30e624f8c237
files mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentRepoFactory.java mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialBuildLogProgress.java mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialIncludeRuleUpdater.java mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SharingMercurialUpdater.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialProgress.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsOperationProgress.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialFetchCallbackProgress.java
diffstat 8 files changed, 130 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentRepoFactory.java	Sun Oct 05 21:05:15 2014 +0200
+++ b/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentRepoFactory.java	Wed Oct 15 06:29:39 2014 +0200
@@ -16,6 +16,8 @@
 
 package jetbrains.buildServer.buildTriggers.vcs.mercurial;
 
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommandSettings;
+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.vcs.VcsException;
@@ -43,8 +45,32 @@
   }
 
   @NotNull
+  public HgRepo createRepo(@NotNull HgVcsRoot root, @NotNull File workingDir, @NotNull MercurialProgress progress) throws VcsException {
+    CommandSettingsFactory settingsFactory = myCommandSettingsFactory.forRoot(root);
+    return new HgRepo(new FactoryWithProgess(settingsFactory, progress), workingDir, myHgPathProvider.getHgPath(root), root.getAuthSettings());
+  }
+
+
+  @NotNull
   public HgRepo createTempDirRepo(@NotNull HgVcsRoot root) {
     return new HgRepo(myCommandSettingsFactory.forRoot(root), myPluginConfig.getTempDir(),
             myHgPathProvider.getHgPath(root), root.getAuthSettings());
   }
+
+
+  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;
+    }
+  }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialBuildLogProgress.java	Wed Oct 15 06:29:39 2014 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import jetbrains.buildServer.agent.BuildProgressLogger;
+import org.jetbrains.annotations.NotNull;
+
+public class MercurialBuildLogProgress implements MercurialProgress {
+
+  private final BuildProgressLogger myLogger;
+  private String myPrevMessage;
+  private int myPrevPercents;
+
+  public MercurialBuildLogProgress(@NotNull BuildProgressLogger logger) {
+     myLogger = logger;
+  }
+
+  public void progressStarted(@NotNull String progressMessage) {
+    myLogger.message(progressMessage);
+  }
+
+  public void progressFinished(@NotNull String progressMessage) {
+    myLogger.message(progressMessage);
+  }
+
+  public void reportProgress(@NotNull String progressMessage) {
+    myLogger.message(progressMessage);
+  }
+
+  public void reportProgress(float percentage, @NotNull String stage) {
+    if (percentage < 0) {
+      resetPrevProgress();
+      reportProgress(stage);
+    } else {
+      int percents = (int) Math.floor(percentage * 100);
+      if (!isDuplicate(stage, percents)) {
+        myLogger.progressMessage(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;
+  }
+}
--- a/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialIncludeRuleUpdater.java	Sun Oct 05 21:05:15 2014 +0200
+++ b/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialIncludeRuleUpdater.java	Wed Oct 15 06:29:39 2014 +0200
@@ -56,6 +56,7 @@
   private final boolean myUseTraceback;
   private final boolean myProfile;
   private final List<MercurialExtension> myExtensions = new ArrayList<MercurialExtension>();
+  protected final MercurialProgress myProgress;
 
   public MercurialIncludeRuleUpdater(@NotNull AgentPluginConfig pluginConfig,
                                      @NotNull MirrorManager mirrorManager,
@@ -73,6 +74,7 @@
     myPullTimeout = pluginConfig.getPullTimeout(build);
     myUseTraceback = pluginConfig.runWithTraceback(build);
     myProfile = pluginConfig.runWithProfile(build);
+    myProgress = new MercurialBuildLogProgress(build.getBuildLogger());
   }
 
 
@@ -111,7 +113,7 @@
 
   protected void updateLocalMirror(@NotNull String repositoryUrl, @NotNull String revision) throws VcsException, IOException {
     File mirrorDir = myMirrorManager.getMirrorDir(repositoryUrl);
-    HgRepo mirrorRepo = myRepoFactory.createRepo(myRoot, mirrorDir);
+    HgRepo mirrorRepo = myRepoFactory.createRepo(myRoot, mirrorDir, myProgress);
     if (!mirrorRepo.isValidRepository()) {
       delete(mirrorDir);
       mirrorRepo.init().call();
@@ -135,7 +137,7 @@
 
   protected void updateRepository(@NotNull File workingDir) throws VcsException, IOException {
     String repositoryUrl = getDefaultPullUrl(myRoot, myUseLocalMirrors);
-    HgRepo repo = myRepoFactory.createRepo(myRoot, workingDir);
+    HgRepo repo = myRepoFactory.createRepo(myRoot, workingDir, myProgress);
     myLogger.message("Update repository " + workingDir.getAbsolutePath());
     disableSharing(workingDir);
     if (!repo.isValidRepository())
@@ -169,7 +171,7 @@
 
 
   private void updateWorkingDir(@NotNull File workingDir, @NotNull String toVersion, @NotNull String repositoryUrl) throws VcsException, IOException {
-    HgRepo repo = myRepoFactory.createRepo(myRoot, workingDir);
+    HgRepo repo = myRepoFactory.createRepo(myRoot, workingDir, myProgress);
     List<File> repos = new ArrayList<File>();
     updateSubrepositories(repo, toVersion, repositoryUrl, repos);
     doUpdateWorkingDir(repo, toVersion);
@@ -182,7 +184,7 @@
       return;
     for (File dir : dirs) {
       myLogger.message("Run purge in " + dir.getAbsolutePath());
-      HgRepo repo = myRepoFactory.createRepo(myRoot, dir);
+      HgRepo repo = myRepoFactory.createRepo(myRoot, dir, myProgress);
       repo.purge().withPolicy(purgePolicy).call();
       myLogger.message("Purge in " + dir.getAbsolutePath() + " is finished");
     }
@@ -208,7 +210,7 @@
         myLogger.message("The url of subrepoConfig was changed between revisions " + workingDirRevision + " and " + toVersion + " , delete the subrepoConfig");
         delete(subrepoConfigDir(repo, subrepoConfig));
       }
-      HgRepo subrepository = myRepoFactory.createRepo(myRoot, subrepoConfigDir(repo, subrepoConfig));
+      HgRepo subrepository = myRepoFactory.createRepo(myRoot, subrepoConfigDir(repo, subrepoConfig), myProgress);
       String subrepoUrl;
       try {
         subrepoUrl = subrepoConfig.resolveUrl(parentRepositoryUrl);
--- a/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SharingMercurialUpdater.java	Sun Oct 05 21:05:15 2014 +0200
+++ b/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SharingMercurialUpdater.java	Wed Oct 15 06:29:39 2014 +0200
@@ -38,7 +38,7 @@
 
   @Override
   protected void updateRepository(@NotNull File workingDir) throws VcsException, IOException {
-    HgRepo repo = myRepoFactory.createRepo(myRoot, workingDir);
+    HgRepo repo = myRepoFactory.createRepo(myRoot, workingDir, myProgress);
     if (repo.isEmpty() || !repo.isValidRepository())
       repo.init().call();
     repo.setDefaultPath(myRoot.getRepository());
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialProgress.java	Sun Oct 05 21:05:15 2014 +0200
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialProgress.java	Wed Oct 15 06:29:39 2014 +0200
@@ -20,11 +20,19 @@
 
 public interface MercurialProgress {
 
+  void progressStarted(@NotNull String progressMessage);
+
+  void progressFinished(@NotNull String progressMessage);
+
   void reportProgress(@NotNull String progressMessage);
 
   void reportProgress(float percentage, @NotNull String stage);
 
   static MercurialProgress NO_OP = new MercurialProgress() {
+    public void progressStarted(@NotNull String progressMessage) {
+    }
+    public void progressFinished(@NotNull String progressMessage) {
+    }
     public void reportProgress(@NotNull String progressMessage) {
     }
     public void reportProgress(float percentage, @NotNull String stage) {
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsOperationProgress.java	Sun Oct 05 21:05:15 2014 +0200
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsOperationProgress.java	Wed Oct 15 06:29:39 2014 +0200
@@ -29,6 +29,14 @@
     myProgress = progress;
   }
 
+  public void progressStarted(@NotNull String progressMessage) {
+    reportProgress(progressMessage);
+  }
+
+  public void progressFinished(@NotNull String progressMessage) {
+    reportProgress(progressMessage);
+  }
+
   public void reportProgress(@NotNull String progressMessage) {
     myProgress.reportProgress(progressMessage);
   }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java	Sun Oct 05 21:05:15 2014 +0200
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java	Wed Oct 15 06:29:39 2014 +0200
@@ -77,12 +77,12 @@
     if (!myCommandSettings.getUseCommandlineViaFileWrapper()) {
       String commandDescription = cli.getDescription();
       if (!isEmpty(commandDescription))
-        commandSettings.getProgress().reportProgress(commandDescription);
+        commandSettings.getProgress().progressStarted(commandDescription);
       try {
         return CommandUtil.runCommand(cli, commandSettings.setPrivateData(getPrivateData()));
       } finally {
         if (!isEmpty(commandDescription))
-          commandSettings.getProgress().reportProgress(commandDescription + " finished");
+          commandSettings.getProgress().progressFinished(commandDescription + " finished");
       }
     }
 
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialFetchCallbackProgress.java	Sun Oct 05 21:05:15 2014 +0200
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialFetchCallbackProgress.java	Wed Oct 15 06:29:39 2014 +0200
@@ -27,6 +27,14 @@
     myCallback = callback;
   }
 
+  public void progressStarted(@NotNull String progressMessage) {
+    reportProgress(progressMessage);
+  }
+
+  public void progressFinished(@NotNull String progressMessage) {
+    reportProgress(progressMessage);
+  }
+
   public void reportProgress(@NotNull String progressMessage) {
   }