changeset 379:55c2c88a2d82 Eluru-6.5.x

TW-17630, TW-18815 fix encoding for hg log command Mercurial stores commit messages in UTF-8. During commit it tries to guess a system encoding and transcode message from system encoding to UTF-8. When it prints to output it transcodes from UTF-8 to the system encoding and replace characters which cannot be represented in the system encoding with the symbol of '?'. Default console encoding on windows is cp437, and it cannot represent non-latin symbols, see http://mercurial.selenic.com/wiki/CharacterEncodingOnWindows for details. The fix is to not use a console to run hg, and tell mercurial to do the output in UTF-8.
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Wed, 15 Feb 2012 12:07:12 +0400
parents dbdee21f2893
children 3bc8125671b8 3b799724b82b
files mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java
diffstat 4 files changed, 21 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java	Tue Feb 14 19:38:59 2012 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java	Wed Feb 15 12:07:12 2012 +0400
@@ -16,7 +16,6 @@
 package jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
 
 import com.intellij.execution.configurations.GeneralCommandLine;
-import com.intellij.openapi.util.SystemInfo;
 import jetbrains.buildServer.util.StringUtil;
 import jetbrains.buildServer.vcs.VcsException;
 import org.jetbrains.annotations.NotNull;
@@ -63,35 +62,10 @@
 
   protected GeneralCommandLine createCL() {
     GeneralCommandLine cl = new MercurialCommandLine(getPrivateData());
-    setupExecutable(cl);
+    cl.setExePath(getSettings().getHgCommandPath());
     return cl;
   }
 
-  /**
-   * Since mercurial 1.7 on Windows the only file inside '<mercurial_install_dir>/bin' is 'hg.cmd'
-   * which run hg.exe placed in the parent dir. GeneralCommandLine will not find hg.cmd, in the
-   * case when $PATH contains <mercurial_install_dir>/bin and doesn't contain <mercurial_install_dir>
-   * and hg executable is set to 'hg'. To fix it - run hg using windows shell which expand
-   * hg to hg.cmd correctly.
-   */
-  private void setupExecutable(GeneralCommandLine cli) {
-    if (SystemInfo.isWindows && getSettings().getHgCommandPath().equals("hg")) {
-      setupCmd(cli);
-    } else {
-      setupHg(cli);
-    }
-  }
-
-  private void setupCmd(GeneralCommandLine cli) {
-    cli.setExePath("cmd");
-    cli.addParameter("/c");
-    cli.addParameter("hg");
-  }
-
-  private void setupHg(GeneralCommandLine cli) {
-    cli.setExePath(getSettings().getHgCommandPath());
-  }
-
   protected CommandResult runCommand(@NotNull GeneralCommandLine cli) throws VcsException {
     return CommandUtil.runCommand(cli, getPrivateData());
   }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java	Tue Feb 14 19:38:59 2012 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java	Wed Feb 15 12:07:12 2012 +0400
@@ -41,4 +41,8 @@
   public int getExitCode() {
     return myDelegate.getExitCode();
   }
+
+  public byte[] getByteOut() {
+    return myDelegate.getByteOut();
+  }
 }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java	Tue Feb 14 19:38:59 2012 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java	Wed Feb 15 12:07:12 2012 +0400
@@ -25,6 +25,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
@@ -63,6 +64,7 @@
 
   public List<ChangeSet> execute() throws VcsException {
     GeneralCommandLine cli = createCommandLine();
+    cli.addParameters("--encoding", "UTF-8");
     cli.addParameter("log");
     cli.addParameter("--style=" + myTemplate.getAbsolutePath());
     if (myBranchName != null) {
@@ -80,10 +82,19 @@
       cli.addParameter(myLimit.toString());
     }
     CommandResult res = runCommand(cli);
+    String output = getStdout(res);
     try {
-      return parseChangeSetsXml(res.getStdout());
+      return parseChangeSetsXml(output);
     } catch (Exception e) {
-      throw new VcsException("Error while parsing log output:\n" + res.getStdout(), e);
+      throw new VcsException("Error while parsing log output:\n" + output, e);
+    }
+  }
+
+  private String getStdout(CommandResult res) throws VcsException {
+    try {
+      return new String(res.getByteOut(), "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new VcsException("Error while reading output", e);
     }
   }
 
@@ -104,8 +115,8 @@
 
   private String makeValidXml(@NotNull final String xml) {
     String trimmed = xml.trim();
-    if (xml.trim().endsWith("</log>"))
-      return xml;
+    if (trimmed.endsWith("</log>"))
+      return trimmed;
     else
       return trimmed + "</log>";
   }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Tue Feb 14 19:38:59 2012 +0400
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Wed Feb 15 12:07:12 2012 +0400
@@ -120,9 +120,7 @@
 
   private File createLogTemplate(@NotNull final File templateFileDir) throws IOException {
     File template = new File(templateFileDir, LOG_TEMPLATE_NAME);
-    if (!template.exists()) {
-      FileUtil.copyResource(MercurialVcsSupport.class, "/buildServerResources/log.template", template);
-    }
+    FileUtil.copyResource(MercurialVcsSupport.class, "/buildServerResources/log.template", template);
     return template;
   }