changeset 828:8d02c7b1f812

use HG extension to pass infinite commandline arguments list
author eugene.petrenko@jetbrains.com
date Fri, 30 May 2014 17:29:51 +0200
parents 194c8f8d6e4c
children 568bb3e7a8eb
files mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandSettings.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java mercurial-common/src/python/load-commands-command.py
diffstat 4 files changed, 123 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java	Fri May 30 17:23:17 2014 +0200
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java	Fri May 30 17:29:51 2014 +0200
@@ -41,7 +41,13 @@
   }
 
   protected final int getMaxCommandLineSize() {
-    return myCommandSettings.getMaxCommandLineSize();
+    return allowCommandlineViaFileWrapper()
+            ? Integer.MAX_VALUE
+            : myCommandSettings.getMaxCommandLineSize();
+  }
+
+  protected boolean allowCommandlineViaFileWrapper() {
+    return true;
   }
 
   public File getWorkDirectory() {
@@ -76,11 +82,11 @@
   protected final CommandResult runCommand(@NotNull final MercurialCommandLine cli,
                                            @NotNull final CommandSettings commandSettings) throws VcsException {
 
-    if (!myCommandSettings.getUseCommandlineViaFileWrapper()) {
+    if (!myCommandSettings.getUseCommandlineViaFileWrapper() || !allowCommandlineViaFileWrapper()) {
       return CommandUtil.runCommand(cli, commandSettings.setPrivateData(getPrivateData()));
     }
 
-    throw new VcsException("Not yet implemented");
+    return CommandUtil.runWrappedCommand(cli, commandSettings);
   }
 
   protected void setupExtensionsFromResource(@NotNull final MercurialCommandLine cli,
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandSettings.java	Fri May 30 17:23:17 2014 +0200
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandSettings.java	Fri May 30 17:29:51 2014 +0200
@@ -38,10 +38,8 @@
   private ProgressParser.ProgressConsumer myProgressConsumer;
   private boolean myUseCommandlineViaFileWrapper = false;
 
-  public int getMaxCommandLineSize() {
-    return getUseCommandlineViaFileWrapper()
-            ? Integer.MAX_VALUE
-            : OS.getMaxCommandLineSize();
+  public final int getMaxCommandLineSize() {
+    return OS.getMaxCommandLineSize();
   }
 
   public boolean getUseCommandlineViaFileWrapper() {
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java	Fri May 30 17:23:17 2014 +0200
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java	Fri May 30 17:29:51 2014 +0200
@@ -18,6 +18,8 @@
 import jetbrains.buildServer.ExecResult;
 import jetbrains.buildServer.LineAwareByteArrayOutputStream;
 import jetbrains.buildServer.SimpleCommandLineProcessRunner;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.HgFileUtil;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.OS;
 import jetbrains.buildServer.log.Loggers;
 import jetbrains.buildServer.util.FileUtil;
 import jetbrains.buildServer.util.StringUtil;
@@ -54,7 +56,56 @@
   }
 
   @NotNull
-  public static CommandResult runCommand(@NotNull MercurialCommandLine cli, @NotNull CommandSettings settings) throws VcsException {
+  public static CommandResult runWrappedCommand(@NotNull final MercurialCommandLine originalCommandLine,
+                                                @NotNull final CommandSettings settings) throws VcsException {
+
+    final File tempDir = createTempDir();
+    try {
+      final File commands = writeCommandArguments(originalCommandLine, tempDir);
+
+      final MercurialCommandLine fork = originalCommandLine.forkWithoutCommandlineArguments();
+      setupExtensionsFromResource(fork, tempDir, "load-commands-command.py");
+      fork.addParameters("CMD", commands.getAbsolutePath());
+
+      for (String arg : originalCommandLine.getArguments()) {
+        if (fork.getCommandLineLength() + arg.length() >= OS.getMaxCommandLineSize() - 5) {
+          fork.addParameter("...");
+          break;
+        }
+        fork.addParameter(arg);
+      }
+
+      return runCommand(fork, settings);
+    } finally {
+      FileUtil.delete(tempDir);
+    }
+  }
+
+  @NotNull
+  private static File writeCommandArguments(@NotNull MercurialCommandLine originalCommandLine,
+                                            @NotNull File tempDir) throws VcsException {
+    try {
+      final File commands = new File(tempDir, "command.args");
+      FileUtil.writeFile(commands, StringUtil.join("\n", originalCommandLine.getArguments()), "utf-8");
+      return commands;
+    } catch (IOException e) {
+      throw new VcsException("Failed to generate commands file. " + e.getMessage(), e);
+    }
+
+  }
+
+  @NotNull
+  private static File createTempDir() throws VcsException {
+    try {
+      return HgFileUtil.createTempDir();
+    } catch (IOException e) {
+      throw new VcsException("Failed to create temp file. " + e.getMessage(), e);
+    }
+  }
+
+  @NotNull
+  public static CommandResult runCommand(@NotNull final MercurialCommandLine cli,
+                                         @NotNull final CommandSettings settings) throws VcsException {
     final String command = removePrivateData(cli.getCommandLineString(), settings.getPrivateData());
     logRunCommand(cli, command, settings);
     CommandResult res = run(cli, settings.getTimeout(), command, settings.getPrivateData(), settings);
@@ -64,6 +115,7 @@
     return res;
   }
 
+  @NotNull
   private static CommandResult run(@NotNull final MercurialCommandLine cli,
                                    final int executionTimeout,
                                    @NotNull final String command,
@@ -84,6 +136,7 @@
       public Integer getOutputIdleSecondsTimeout() {
         return executionTimeout;
       }
+
       @Override
       public void onProcessFinished(@NotNull Process ps) {
         long duration = System.currentTimeMillis() - start;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial-common/src/python/load-commands-command.py	Fri May 30 17:29:51 2014 +0200
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+##
+##    Copyright 2000-2014 JetBrains
+##
+##     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.
+##
+##
+##  http://www.gnu.org/licenses/gpl-faq.html#GPLModuleLicense
+##  http://www.gnu.org/licenses/license-list.html#apache2
+##  http://en.wikipedia.org/wiki/Apache_License#GPL_compatibility
+##
+##
+"""
+load-commands-command
+"""
+
+import codecs
+from mercurial import dispatch
+
+def loadArguments(ui, params_file):
+  file_commands = []
+  ui.write("Parameters from the file (one by line):\n")
+  with codecs.open(params_file, "r", "utf-8") as f:
+    for _line in f:
+      line = _line.strip()
+      if len(line) <= 0:
+        continue
+
+      ui.write("  " + line + "\n")
+      file_commands.append(line)
+  return file_commands
+
+
+def load_commands_command(ui, repo, params_file, *pats, **opts):
+  ui.write("Staring command with arguments from " + params_file + "\n")
+  command_arguments = loadArguments(ui, params_file)
+
+  ui.write("\nRunning the command...\n\n")
+  return dispatch.dispatch(dispatch.request(command_arguments))
+
+#so here goes command registration and options
+cmdtable = {
+    "CMD": (load_commands_command, [ ], "params_file [foo]...")
+}
+
+testedwith = '2.2.2'
+buglink = "@jonnyzzz"
+