From 636f5cf38c859fb079da854f27cfe4ca553b2de7 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 13 Apr 2011 19:31:27 +0400 Subject: [PATCH] IDEA-67921 IDEA-65888 Mercurial installed via easy_install/pip on Windows. Root cause: the pipe symbol (|) used in changesets templates (--template) is interpreted by system in the case of such configuration and running via hg.bat). If Windows, surround the template by double-quotes. It breaks UNIX version, however, so don't do it for UNIX. Refactored all usages of --template to go through HgChangesetUtil.makeTemplate() using common separators and quoting if needed. --- .../hg4idea/command/HgChangesetsCommand.java | 9 ++-- .../hg4idea/command/HgRevisionsCommand.java | 17 ++++--- ...TrackFileNamesAccrossRevisionsCommand.java | 13 +++-- .../HgWorkingCopyRevisionsCommand.java | 7 +-- .../zmlx/hg4idea/util/HgChangesetUtil.java | 48 +++++++++++++++++++ 5 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgChangesetsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgChangesetsCommand.java index 261fdda52a77..c8f1ad54d7e8 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgChangesetsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgChangesetsCommand.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.HgRevisionNumber; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; +import org.zmlx.hg4idea.util.HgChangesetUtil; import java.util.ArrayList; import java.util.Arrays; @@ -33,8 +34,6 @@ public abstract class HgChangesetsCommand { private static final Logger LOG = Logger.getInstance(HgChangesetsCommand.class.getName()); - private static final String SEPARATOR_STRING = "\u0017"; //ascii: end of transmission block - protected final Project project; protected final String command; @@ -50,7 +49,7 @@ public abstract class HgChangesetsCommand { protected List getRevisions(VirtualFile repo) { List args = new ArrayList(Arrays.asList( "--template", - "{rev}|{node|short}|{author}|{desc|firstline}" + SEPARATOR_STRING, + HgChangesetUtil.makeTemplate("{rev}", "{node|short}", "{author}", "{desc|firstline}"), "--quiet" )); @@ -67,11 +66,11 @@ public abstract class HgChangesetsCommand { return Collections.emptyList(); } - String[] changesets = output.split(SEPARATOR_STRING); + String[] changesets = output.split(HgChangesetUtil.CHANGESET_SEPARATOR); List revisions = new ArrayList(changesets.length); for(String changeset: changesets) { - String[] parts = StringUtils.split(changeset, "|", 4); + String[] parts = StringUtils.split(changeset, HgChangesetUtil.ITEM_SEPARATOR, 4); if (parts.length == 4) { revisions.add(HgRevisionNumber.getInstance(parts[0], parts[1], parts[2], parts[3])); } else { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java index 3e5ee5319ce6..ce13c6e053fa 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRevisionsCommand.java @@ -23,6 +23,7 @@ import org.zmlx.hg4idea.HgFile; import org.zmlx.hg4idea.HgFileRevision; import org.zmlx.hg4idea.HgRevisionNumber; import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.util.HgChangesetUtil; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.execution.HgCommandExecutor; @@ -33,12 +34,10 @@ import java.util.*; abstract class HgRevisionsCommand { private static final Logger LOG = Logger.getInstance(HgRevisionsCommand.class.getName()); - private static final String SEPARATOR_STRING = "\u0017"; //ascii: end of transmission block - private static final String SHORT_TEMPLATE = "{rev}|{node|short}|{parents}|{date|isodatesec}|{author}|{branches}|{desc}" + SEPARATOR_STRING; - private static final int SHORT_ITEM_COUNT = 7; - private static final String LONG_TEMPLATE = "{rev}|{node|short}|{parents}|{date|isodatesec}|{author}|{branches}|{desc}|{file_adds}|{file_mods}|{file_dels}|{file_copies}" + SEPARATOR_STRING; - private static final int LONG_ITEM_COUNT = 11; + private static final String[] SHORT_TEMPLATE_ITEMS = { "{rev}","{node|short}", "{parents}", "{date|isodatesec}", "{author}", "{branches}", "{desc}" }; + private static final String[] LONG_TEMPLATE_ITEMS = + { "{rev}", "{node|short}", "{parents}", "{date|isodatesec}", "{author}", "{branches}", "{desc}", "{file_adds}", "{file_mods}", "{file_dels}", "{file_copies}" }; private static final int REVISION_INDEX = 0; private static final int CHANGESET_INDEX = 1; @@ -73,8 +72,8 @@ abstract class HgRevisionsCommand { HgCommandExecutor hgCommandExecutor = new HgCommandExecutor(project); - String template = includeFiles ? LONG_TEMPLATE : SHORT_TEMPLATE; - int itemCount = includeFiles ? LONG_ITEM_COUNT : SHORT_ITEM_COUNT; + String template = HgChangesetUtil.makeTemplate(includeFiles ? LONG_TEMPLATE_ITEMS : SHORT_TEMPLATE_ITEMS); + int itemCount = includeFiles ? LONG_TEMPLATE_ITEMS.length : SHORT_TEMPLATE_ITEMS.length; FilePath originalFileName = HgUtil.getOriginalFileName(hgFile.toFilePath(), ChangeListManager.getInstance(project)); HgFile originalHgFile = new HgFile(hgFile.getRepo(), originalFileName); @@ -84,10 +83,10 @@ abstract class HgRevisionsCommand { List revisions = new LinkedList(); String output = result.getRawOutput(); - String[] changeSets = output.split(SEPARATOR_STRING); + String[] changeSets = output.split(HgChangesetUtil.CHANGESET_SEPARATOR); for (String line : changeSets) { try { - String[] attributes = StringUtils.splitPreserveAllTokens(line, '|'); + String[] attributes = line.split(HgChangesetUtil.ITEM_SEPARATOR); if (attributes.length != itemCount) { LOG.debug("Wrong format. Skipping line " + line); continue; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTrackFileNamesAccrossRevisionsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTrackFileNamesAccrossRevisionsCommand.java index ee141ca08e9a..49e171540ebf 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTrackFileNamesAccrossRevisionsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTrackFileNamesAccrossRevisionsCommand.java @@ -19,16 +19,15 @@ import org.apache.commons.lang.StringUtils; import org.zmlx.hg4idea.HgFile; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; +import org.zmlx.hg4idea.util.HgChangesetUtil; import java.util.*; class HgTrackFileNamesAccrossRevisionsCommand { private static final Logger LOG = Logger.getInstance(HgTrackFileNamesAccrossRevisionsCommand.class.getName()); - private static final String SEPARATOR_STRING = "\u0027"; //ascii: end of transmission block - private static final String TEMPLATE = "{rev}|{file_dels}|{file_copies}" + SEPARATOR_STRING; - private static final int ITEM_COUNT = 3; + private static final String[] TEMPLATE_ITEMS = { "{rev}", "{file_dels}", "{file_copies}" }; private static final int REVISION_INDEX = 0; private static final int FILES_DELETED_INDEX = 1; @@ -48,7 +47,7 @@ class HgTrackFileNamesAccrossRevisionsCommand { arguments.add("--follow"); arguments.add("--template"); - arguments.add(TEMPLATE); + arguments.add(HgChangesetUtil.makeTemplate(TEMPLATE_ITEMS)); if (limit != -1) { arguments.add("--limit"); @@ -69,15 +68,15 @@ class HgTrackFileNamesAccrossRevisionsCommand { HgCommandResult result = execute(hgCommandExecutor, hgFile.getRepo(), limit, hgFile, currentRevision, givenRevision); String output = result.getRawOutput(); - String[] changeSets = output.split(SEPARATOR_STRING); + String[] changeSets = output.split(HgChangesetUtil.CHANGESET_SEPARATOR); String currentFileName = hgFile.getRelativePath(); // needed on windows machines currentFileName = currentFileName.replaceAll("\\\\", "/"); for (String line : changeSets) { try { - String[] attributes = StringUtils.splitPreserveAllTokens(line, '|'); - if (attributes.length != ITEM_COUNT) { + String[] attributes = line.split(HgChangesetUtil.ITEM_SEPARATOR); + if (attributes.length != TEMPLATE_ITEMS.length) { LOG.debug("Wrong format. Skipping line " + line); continue; } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java index db4e5de1ab98..689ceb481b7d 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgWorkingCopyRevisionsCommand.java @@ -25,6 +25,7 @@ import org.zmlx.hg4idea.HgRevisionNumber; import org.zmlx.hg4idea.HgUtil; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.execution.HgCommandExecutor; +import org.zmlx.hg4idea.util.HgChangesetUtil; import java.util.ArrayList; import java.util.Arrays; @@ -165,7 +166,7 @@ public class HgWorkingCopyRevisionsCommand { boolean silent) { final List args = new LinkedList(); args.add("--template"); - args.add("{rev}|{node|short}\\n"); + args.add(HgChangesetUtil.makeTemplate("{rev}", "{node|short}")); if (revision != null) { args.add("-r"); args.add(revision.getChangeset()); @@ -180,10 +181,10 @@ public class HgWorkingCopyRevisionsCommand { if (result == null) { return new ArrayList(0); } - final List lines = result.getOutputLines(); + final List lines = Arrays.asList(result.getRawOutput().split(HgChangesetUtil.CHANGESET_SEPARATOR)); final List revisions = new ArrayList(lines.size()); for(String line: lines) { - final String[] parts = StringUtils.split(line, '|'); + final String[] parts = StringUtils.split(line, HgChangesetUtil.ITEM_SEPARATOR); revisions.add(HgRevisionNumber.getInstance(parts[0], parts[1])); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java new file mode 100644 index 000000000000..9118dc217fb9 --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2011 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 org.zmlx.hg4idea.util; + +import com.intellij.openapi.util.SystemInfo; + +/** + * Utilities for operations involving working with a number of changesets: log, incoming, outgoing, parents, etc. + * @author Kirill Likhodedov + */ +public class HgChangesetUtil { + + public static final String CHANGESET_SEPARATOR = "\u0003"; + public static final String ITEM_SEPARATOR = "\u0017"; + + /** + * Common method for hg commands which receive templates via --template option. + * @param templateItems template items like
{rev}
,
{node}
. + * @return items joined by ITEM_SEPARATOR, ended by CHANGESET_SEPARATOR, and, if needed (for Windows), surrounded with double-quotes. + */ + public static String makeTemplate(String... templateItems) { + StringBuilder template = new StringBuilder(); + + for (String item : templateItems) { + template.append(item).append(ITEM_SEPARATOR); + } + + template.append(CHANGESET_SEPARATOR); + if (SystemInfo.isWindows) { + return "\"" + template + "\""; + } + return template.toString(); + } + +}