]> source.dussan.org Git - jgit.git/commitdiff
Add config reader for user-defined mergetools 42/137942/40
authorAndre Bossert <andre.bossert@siemens.com>
Fri, 8 Mar 2019 20:32:57 +0000 (21:32 +0100)
committerAndrey Loskutov <loskutov@gmx.de>
Wed, 25 May 2022 11:50:50 +0000 (13:50 +0200)
see: https://git-scm.com/docs/git-mergetool
see: https://git-scm.com/docs/git-config

* add config reader for user-defined mergetools
  * merge.tool
  * merge.guitool
  * mergetool.prompt
  * mergetool.keepBackup
  * mergetool.keepTemporaries
  * mergetool.writeToTemp
  * mergetool.<tool>.path
  * mergetool.<tool>.cmd
  * mergetool.<tool>.trustExitCode

Bug: 356832
Change-Id: Ic4f07376630713d8e06cbad284d9c72c9ecc0405
Signed-off-by: Andre Bossert <andre.bossert@siemens.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalMergeToolTest.java [new file with mode: 0644]
org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/ExternalMergeTool.java [new file with mode: 0644]
org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/MergeToolConfig.java [new file with mode: 0644]
org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/MergeTools.java [new file with mode: 0644]
org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/UserDefinedMergeTool.java [new file with mode: 0644]
org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java

diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalMergeToolTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalMergeToolTest.java
new file mode 100644 (file)
index 0000000..96fd102
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2020-2022, Simeon Andreev <simeon.danailov.andreev@gmail.com> and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.diffmergetool;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.jgit.lib.internal.BooleanTriState;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.junit.Test;
+
+/**
+ * Testing external merge tools.
+ */
+public class ExternalMergeToolTest extends ExternalToolTestCase {
+
+       @Test
+       public void testToolNames() {
+               MergeTools manager = new MergeTools(db);
+               Set<String> actualToolNames = manager.getToolNames();
+               Set<String> expectedToolNames = Collections.emptySet();
+               assertEquals("Incorrect set of external diff tool names",
+                               expectedToolNames, actualToolNames);
+       }
+
+       @Test
+       public void testAllTools() {
+               MergeTools manager = new MergeTools(db);
+               Set<String> actualToolNames = manager.getAvailableTools().keySet();
+               Set<String> expectedToolNames = Collections.emptySet();
+               assertEquals("Incorrect set of available external diff tools",
+                               expectedToolNames, actualToolNames);
+       }
+
+       @Test
+       public void testUserDefinedTools() {
+               MergeTools manager = new MergeTools(db);
+               Set<String> actualToolNames = manager.getUserDefinedTools().keySet();
+               Set<String> expectedToolNames = Collections.emptySet();
+               assertEquals("Incorrect set of user defined external diff tools",
+                               expectedToolNames, actualToolNames);
+       }
+
+       @Test
+       public void testNotAvailableTools() {
+               MergeTools manager = new MergeTools(db);
+               Set<String> actualToolNames = manager.getNotAvailableTools().keySet();
+               Set<String> expectedToolNames = Collections.emptySet();
+               assertEquals("Incorrect set of not available external diff tools",
+                               expectedToolNames, actualToolNames);
+       }
+
+       @Test
+       public void testCompare() throws ToolException {
+               MergeTools manager = new MergeTools(db);
+
+               String newPath = "";
+               String oldPath = "";
+               String newId = "";
+               String oldId = "";
+               String toolName = "";
+               BooleanTriState prompt = BooleanTriState.UNSET;
+               BooleanTriState gui = BooleanTriState.UNSET;
+               BooleanTriState trustExitCode = BooleanTriState.UNSET;
+
+               int expectedCompareResult = 0;
+               int compareResult = manager.merge(newPath, oldPath, newId, oldId,
+                               toolName, prompt, gui, trustExitCode);
+               assertEquals("Incorrect compare result for external diff tool",
+                               expectedCompareResult, compareResult);
+       }
+
+       @Test
+       public void testDefaultTool() throws Exception {
+               FileBasedConfig config = db.getConfig();
+               // the default diff tool is configured without a subsection
+               String subsection = null;
+               config.setString("diff", subsection, "tool", "customTool");
+
+               MergeTools manager = new MergeTools(db);
+               BooleanTriState gui = BooleanTriState.UNSET;
+               String defaultToolName = manager.getDefaultToolName(gui);
+               assertEquals(
+                               "Expected configured difftool to be the default external diff tool",
+                               "my_default_toolname", defaultToolName);
+
+               gui = BooleanTriState.TRUE;
+               String defaultGuiToolName = manager.getDefaultToolName(gui);
+               assertEquals(
+                               "Expected configured difftool to be the default external diff tool",
+                               "my_gui_tool", defaultGuiToolName);
+
+               config.setString("diff", subsection, "guitool", "customGuiTool");
+               manager = new MergeTools(db);
+               defaultGuiToolName = manager.getDefaultToolName(gui);
+               assertEquals(
+                               "Expected configured difftool to be the default external diff guitool",
+                               "my_gui_tool", defaultGuiToolName);
+       }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/ExternalMergeTool.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/ExternalMergeTool.java
new file mode 100644 (file)
index 0000000..bcc749a
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2018-2022, Andre Bossert <andre.bossert@siemens.com>
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.diffmergetool;
+
+/**
+ * The merge tool interface.
+ */
+public interface ExternalMergeTool extends ExternalDiffTool {
+
+       /**
+        * @return the tool "trust exit code" option
+        */
+       boolean isTrustExitCode();
+
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/MergeToolConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/MergeToolConfig.java
new file mode 100644 (file)
index 0000000..e912822
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2018-2022, Andre Bossert <andre.bossert@siemens.com>
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.diffmergetool;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.Config.SectionParser;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.internal.BooleanTriState;
+
+/**
+ * Keeps track of difftool related configuration options.
+ */
+public class MergeToolConfig {
+
+       /** Key for {@link Config#get(SectionParser)}. */
+       public static final Config.SectionParser<MergeToolConfig> KEY = MergeToolConfig::new;
+
+       private final String toolName;
+
+       private final String guiToolName;
+
+       private final boolean prompt;
+
+       private final boolean keepBackup;
+
+       private final boolean keepTemporaries;
+
+       private final boolean writeToTemp;
+
+       private final Map<String, ExternalMergeTool> tools;
+
+       private MergeToolConfig(Config rc) {
+               toolName = rc.getString(ConfigConstants.CONFIG_MERGE_SECTION, null,
+                               ConfigConstants.CONFIG_KEY_TOOL);
+               guiToolName = rc.getString(ConfigConstants.CONFIG_MERGE_SECTION, null,
+                               ConfigConstants.CONFIG_KEY_GUITOOL);
+               prompt = rc.getBoolean(ConfigConstants.CONFIG_MERGETOOL_SECTION,
+                               ConfigConstants.CONFIG_KEY_PROMPT, true);
+               keepBackup = rc.getBoolean(ConfigConstants.CONFIG_MERGETOOL_SECTION,
+                               ConfigConstants.CONFIG_KEY_KEEP_BACKUP, true);
+               keepTemporaries = rc.getBoolean(
+                               ConfigConstants.CONFIG_MERGETOOL_SECTION,
+                               ConfigConstants.CONFIG_KEY_KEEP_TEMPORARIES, false);
+               writeToTemp = rc.getBoolean(ConfigConstants.CONFIG_MERGETOOL_SECTION,
+                               ConfigConstants.CONFIG_KEY_WRITE_TO_TEMP, false);
+               tools = new HashMap<>();
+               Set<String> subsections = rc
+                               .getSubsections(ConfigConstants.CONFIG_MERGETOOL_SECTION);
+               for (String name : subsections) {
+                       String cmd = rc.getString(ConfigConstants.CONFIG_MERGETOOL_SECTION,
+                                       name, ConfigConstants.CONFIG_KEY_CMD);
+                       String path = rc.getString(ConfigConstants.CONFIG_MERGETOOL_SECTION,
+                                       name, ConfigConstants.CONFIG_KEY_PATH);
+                       BooleanTriState trustExitCode = BooleanTriState.FALSE;
+                       String trustStr = rc.getString(
+                                       ConfigConstants.CONFIG_MERGETOOL_SECTION, name,
+                                       ConfigConstants.CONFIG_KEY_TRUST_EXIT_CODE);
+                       if (trustStr != null) {
+                               trustExitCode = Boolean.valueOf(trustStr).booleanValue()
+                                               ? BooleanTriState.TRUE
+                                               : BooleanTriState.FALSE;
+                       } else {
+                               trustExitCode = BooleanTriState.UNSET;
+                       }
+                       if ((cmd != null) || (path != null)) {
+                               tools.put(name,
+                                               new UserDefinedMergeTool(name, path, cmd,
+                                                               trustExitCode));
+                       }
+               }
+       }
+
+       /**
+        * @return the default merge tool name (merge.tool)
+        */
+       public String getDefaultToolName() {
+               return toolName;
+       }
+
+       /**
+        * @return the default GUI merge tool name (merge.guitool)
+        */
+       public String getDefaultGuiToolName() {
+               return guiToolName;
+       }
+
+       /**
+        * @return the merge tool "prompt" option (mergetool.prompt)
+        */
+       public boolean isPrompt() {
+               return prompt;
+       }
+
+       /**
+        * @return the tool "keep backup" option
+        */
+       public boolean isKeepBackup() {
+               return keepBackup;
+       }
+
+       /**
+        * @return the tool "keepTemporaries" option
+        */
+       public boolean isKeepTemporaries() {
+               return keepTemporaries;
+       }
+
+       /**
+        * @return the tool "write to temp" option
+        */
+       public boolean isWriteToTemp() {
+               return writeToTemp;
+       }
+
+       /**
+        * @return the tools map
+        */
+       public Map<String, ExternalMergeTool> getTools() {
+               return tools;
+       }
+
+       /**
+        * @return the tool names
+        */
+       public Set<String> getToolNames() {
+               return tools.keySet();
+       }
+
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/MergeTools.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/MergeTools.java
new file mode 100644 (file)
index 0000000..bb5d73e
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2018-2022, Andre Bossert <andre.bossert@siemens.com>
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.diffmergetool;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.internal.BooleanTriState;
+
+/**
+ * Manages merge tools.
+ */
+public class MergeTools {
+       private final MergeToolConfig config;
+
+       private final Map<String, ExternalMergeTool> predefinedTools;
+
+       private final Map<String, ExternalMergeTool> userDefinedTools;
+
+       /**
+        * @param repo
+        *            the repository database
+        */
+       public MergeTools(Repository repo) {
+               config = repo.getConfig().get(MergeToolConfig.KEY);
+               predefinedTools = setupPredefinedTools();
+               userDefinedTools = setupUserDefinedTools();
+       }
+
+       /**
+        * @param localFile
+        *            the local file element
+        * @param remoteFile
+        *            the remote file element
+        * @param baseFile
+        *            the base file element
+        * @param mergedFilePath
+        *            the path of 'merged' file
+        * @param toolName
+        *            the selected tool name (can be null)
+        * @param prompt
+        *            the prompt option
+        * @param trustExitCode
+        *            the "trust exit code" option
+        * @param gui
+        *            the GUI option
+        * @return the execution result from tool
+        * @throws ToolException
+        */
+       public int merge(String localFile,
+                       String remoteFile, String baseFile, String mergedFilePath,
+                       String toolName, BooleanTriState prompt, BooleanTriState gui,
+                       BooleanTriState trustExitCode)
+                       throws ToolException {
+               return 0;
+       }
+
+       /**
+        * @return the tool names
+        */
+       public Set<String> getToolNames() {
+               return config.getToolNames();
+       }
+
+       /**
+        * @return the user defined tools
+        */
+       public Map<String, ExternalMergeTool> getUserDefinedTools() {
+               return userDefinedTools;
+       }
+
+       /**
+        * @return the available predefined tools
+        */
+       public Map<String, ExternalMergeTool> getAvailableTools() {
+               return predefinedTools;
+       }
+
+       /**
+        * @return the NOT available predefined tools
+        */
+       public Map<String, ExternalMergeTool> getNotAvailableTools() {
+               return new TreeMap<>();
+       }
+
+       /**
+        * @param gui
+        *            use the diff.guitool setting ?
+        * @return the default tool name
+        */
+       public String getDefaultToolName(BooleanTriState gui) {
+               return gui != BooleanTriState.UNSET ? "my_gui_tool" //$NON-NLS-1$
+                               : "my_default_toolname"; //$NON-NLS-1$
+       }
+
+       /**
+        * @return is interactive (config prompt enabled) ?
+        */
+       public boolean isInteractive() {
+               return config.isPrompt();
+       }
+
+       private Map<String, ExternalMergeTool> setupPredefinedTools() {
+               return new TreeMap<>();
+       }
+
+       private Map<String, ExternalMergeTool> setupUserDefinedTools() {
+               return new TreeMap<>();
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/UserDefinedMergeTool.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/UserDefinedMergeTool.java
new file mode 100644 (file)
index 0000000..df4d8cb
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018-2022, Andre Bossert <andre.bossert@siemens.com>
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.diffmergetool;
+
+import org.eclipse.jgit.lib.internal.BooleanTriState;
+
+/**
+ * The user-defined merge tool.
+ */
+public class UserDefinedMergeTool extends UserDefinedDiffTool
+               implements ExternalMergeTool {
+
+       /**
+        * the merge tool "trust exit code" option
+        */
+       private final BooleanTriState trustExitCode;
+
+       /**
+        * Creates the merge tool
+        *
+        * @param name
+        *            the name
+        * @param path
+        *            the path
+        * @param cmd
+        *            the command
+        * @param trustExitCode
+        *            the "trust exit code" option
+        */
+       public UserDefinedMergeTool(String name, String path, String cmd,
+                       BooleanTriState trustExitCode) {
+               super(name, path, cmd);
+               this.trustExitCode = trustExitCode;
+       }
+
+       /**
+        * @return the "trust exit code" flag
+        */
+       @Override
+       public boolean isTrustExitCode() {
+               return trustExitCode == BooleanTriState.TRUE;
+       }
+
+       /**
+        * @return the "trust exit code" option
+        */
+       public BooleanTriState getTrustExitCode() {
+               return trustExitCode;
+       }
+
+}
index 8ad32d41c7149809d1aaa8e5c974caa5244887d0..e982a33b2995abc23c26f92d4a50a691f65bf3b0 100644 (file)
@@ -31,14 +31,14 @@ public final class ConfigConstants {
        public static final String CONFIG_DIFF_SECTION = "diff";
 
        /**
-        * The "tool" key within "diff" section
+        * The "tool" key within "diff" or "merge" section
         *
         * @since 6.1
         */
        public static final String CONFIG_KEY_TOOL = "tool";
 
        /**
-        * The "guitool" key within "diff" section
+        * The "guitool" key within "diff" or "merge" section
         *
         * @since 6.1
         */
@@ -52,14 +52,14 @@ public final class ConfigConstants {
        public static final String CONFIG_DIFFTOOL_SECTION = "difftool";
 
        /**
-        * The "prompt" key within "difftool" section
+        * The "prompt" key within "difftool" or "mergetool" section
         *
         * @since 6.1
         */
        public static final String CONFIG_KEY_PROMPT = "prompt";
 
        /**
-        * The "trustExitCode" key within "difftool" section
+        * The "trustExitCode" key within "difftool" or "mergetool.<name>." section
         *
         * @since 6.1
         */
@@ -123,6 +123,34 @@ public final class ConfigConstants {
         */
        public static final String CONFIG_MERGE_SECTION = "merge";
 
+       /**
+        * The "mergetool" section
+        *
+        * @since 5.13
+        */
+       public static final String CONFIG_MERGETOOL_SECTION = "mergetool";
+
+       /**
+        * The "keepBackup" key within "mergetool" section
+        *
+        * @since 5.13
+        */
+       public static final String CONFIG_KEY_KEEP_BACKUP = "keepBackup";
+
+       /**
+        * The "keepTemporaries" key within "mergetool" section
+        *
+        * @since 5.13
+        */
+       public static final String CONFIG_KEY_KEEP_TEMPORARIES = "keepTemporaries";
+
+       /**
+        * The "writeToTemp" key within "mergetool" section
+        *
+        * @since 5.13
+        */
+       public static final String CONFIG_KEY_WRITE_TO_TEMP = "writeToTemp";
+
        /**
         * The "filter" section
         * @since 4.6