Add config reader for user-defined mergetools

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>
This commit is contained in:
Andre Bossert 2019-03-08 21:32:57 +01:00 committed by Andrey Loskutov
parent b63c2f39a1
commit 24171b05f0
6 changed files with 483 additions and 4 deletions

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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();
}
}

View File

@ -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<>();
}
}

View File

@ -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;
}
}

View 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