diff options
author | Andre Bossert <andre.bossert@siemens.com> | 2020-01-19 20:57:23 +0100 |
---|---|---|
committer | Andrey Loskutov <loskutov@gmx.de> | 2022-06-02 10:36:31 +0200 |
commit | ff77d412a9f1a956b8d76b139489038ee3b0870c (patch) | |
tree | 2e636007062bba558a674208d4a508f79fed2271 /org.eclipse.jgit.test | |
parent | 973e955ead1a9bf41efb3168baf5b68527e78023 (diff) | |
download | jgit-ff77d412a9f1a956b8d76b139489038ee3b0870c.tar.gz jgit-ff77d412a9f1a956b8d76b139489038ee3b0870c.zip |
Adapt diff- and merge tool code for PGM and EGit usage
see: https://git-scm.com/docs/git-mergetool
* DiffTools and MergeTools
* store FS, gitDir and workTree for usage without
git repository (for EGit preferences)
* add getUserDefinedToolNames() and getPredefinedToolNames()
* replace getToolNames() with getAllToolNames() that combines the two
lists and put default tool name (diff.tool or merge.tool) as first
element (for EGit preferences)
* FileElement: refactoring of getFile() and friends to have midName
(LOCAL, REMOTE etc.) always added to the temp file name (also for EGit)
* FileElement: added directory attribute that is used in getFile() to
return path with workDir as parent
* DiffTool and MergeTool
* added errw.flush(), because sometimes stderr is not printed in case
of die()
* print e.getMessage() always to stderr
* Moved toolname and prompt logic into managers
* Exported internal packages required for egit.ui
Bug: 356832
Change-Id: I71e7f4dc362169a7612ca4f6546a021bc4b2b5f4
Signed-off-by: Andre Bossert <andre.bossert@siemens.com>
Signed-off-by: Tim Neumann <Tim.Neumann@advantest.com>
Diffstat (limited to 'org.eclipse.jgit.test')
3 files changed, 289 insertions, 80 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalDiffToolTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalDiffToolTest.java index 1b501c25b0..222608e314 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalDiffToolTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalDiffToolTest.java @@ -18,13 +18,20 @@ import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PROMPT; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_TOOL; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_TRUST_EXIT_CODE; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.eclipse.jgit.lib.internal.BooleanTriState; @@ -48,14 +55,7 @@ public class ExternalDiffToolTest extends ExternalToolTestCase { config.setString(CONFIG_DIFFTOOL_SECTION, toolName, CONFIG_KEY_CMD, command); - DiffTools manager = new DiffTools(db); - - BooleanTriState prompt = BooleanTriState.UNSET; - BooleanTriState gui = BooleanTriState.UNSET; - BooleanTriState trustExitCode = BooleanTriState.TRUE; - - manager.compare(local, remote, merged, toolName, prompt, gui, - trustExitCode); + invokeCompare(toolName); fail("Expected exception to be thrown due to external tool exiting with error code: " + errorReturnCode); @@ -72,33 +72,84 @@ public class ExternalDiffToolTest extends ExternalToolTestCase { config.setString(CONFIG_DIFFTOOL_SECTION, toolName, CONFIG_KEY_CMD, command); + invokeCompare(toolName); + fail("Expected exception to be thrown due to external tool exiting with error code: " + + errorReturnCode); + } + + @Test + public void testUserDefinedTool() throws Exception { + String command = getEchoCommand(); + + FileBasedConfig config = db.getConfig(); + String customToolName = "customTool"; + config.setString(CONFIG_DIFFTOOL_SECTION, customToolName, + CONFIG_KEY_CMD, command); + DiffTools manager = new DiffTools(db); - BooleanTriState prompt = BooleanTriState.UNSET; - BooleanTriState gui = BooleanTriState.UNSET; - BooleanTriState trustExitCode = BooleanTriState.FALSE; + Map<String, ExternalDiffTool> tools = manager.getUserDefinedTools(); + ExternalDiffTool externalTool = tools.get(customToolName); + boolean trustExitCode = true; + manager.compare(local, remote, externalTool, trustExitCode); - manager.compare(local, remote, merged, toolName, prompt, gui, - trustExitCode); + assertEchoCommandHasCorrectOutput(); + } - fail("Expected exception to be thrown due to external tool exiting with error code: " - + errorReturnCode); + @Test + public void testUserDefinedToolWithPrompt() throws Exception { + String command = getEchoCommand(); + + FileBasedConfig config = db.getConfig(); + String customToolName = "customTool"; + config.setString(CONFIG_DIFFTOOL_SECTION, customToolName, + CONFIG_KEY_CMD, command); + + DiffTools manager = new DiffTools(db); + + PromptHandler promptHandler = PromptHandler.acceptPrompt(); + MissingToolHandler noToolHandler = new MissingToolHandler(); + + manager.compare(local, remote, Optional.of(customToolName), + BooleanTriState.TRUE, false, BooleanTriState.TRUE, + promptHandler, noToolHandler); + + assertEchoCommandHasCorrectOutput(); + + List<String> actualToolPrompts = promptHandler.toolPrompts; + List<String> expectedToolPrompts = Arrays.asList("customTool"); + assertEquals("Expected a user prompt for custom tool call", + expectedToolPrompts, actualToolPrompts); + + assertEquals("Expected to no informing about missing tools", + Collections.EMPTY_LIST, noToolHandler.missingTools); } @Test - public void testToolNames() { + public void testUserDefinedToolWithCancelledPrompt() throws Exception { DiffTools manager = new DiffTools(db); - Set<String> actualToolNames = manager.getToolNames(); - Set<String> expectedToolNames = Collections.emptySet(); - assertEquals("Incorrect set of external diff tool names", - expectedToolNames, actualToolNames); + + PromptHandler promptHandler = PromptHandler.cancelPrompt(); + MissingToolHandler noToolHandler = new MissingToolHandler(); + + Optional<ExecutionResult> result = manager.compare(local, remote, + Optional.empty(), BooleanTriState.TRUE, false, + BooleanTriState.TRUE, promptHandler, noToolHandler); + assertFalse("Expected no result if user cancels the operation", + result.isPresent()); } @Test public void testAllTools() { + FileBasedConfig config = db.getConfig(); + String customToolName = "customTool"; + config.setString(CONFIG_DIFFTOOL_SECTION, customToolName, + CONFIG_KEY_CMD, "echo"); + DiffTools manager = new DiffTools(db); - Set<String> actualToolNames = manager.getPredefinedTools(true).keySet(); + Set<String> actualToolNames = manager.getAllToolNames(); Set<String> expectedToolNames = new LinkedHashSet<>(); + expectedToolNames.add(customToolName); CommandLineDiffTool[] defaultTools = CommandLineDiffTool.values(); for (CommandLineDiffTool defaultTool : defaultTools) { String toolName = defaultTool.name(); @@ -166,18 +217,12 @@ public class ExternalDiffToolTest extends ExternalToolTestCase { config.setString(CONFIG_DIFFTOOL_SECTION, toolName, CONFIG_KEY_CMD, command); - - BooleanTriState prompt = BooleanTriState.UNSET; - BooleanTriState gui = BooleanTriState.UNSET; - BooleanTriState trustExitCode = BooleanTriState.UNSET; - - DiffTools manager = new DiffTools(db); - + Optional<ExecutionResult> result = invokeCompare(toolName); + assertTrue("Expected external diff tool result to be available", + result.isPresent()); int expectedCompareResult = 0; - ExecutionResult compareResult = manager.compare(local, remote, merged, - toolName, prompt, gui, trustExitCode); assertEquals("Incorrect compare result for external diff tool", - expectedCompareResult, compareResult.getRc()); + expectedCompareResult, result.get().getRc()); } @Test @@ -192,17 +237,16 @@ public class ExternalDiffToolTest extends ExternalToolTestCase { toolName); DiffTools manager = new DiffTools(db); - BooleanTriState gui = BooleanTriState.UNSET; + boolean gui = false; String defaultToolName = manager.getDefaultToolName(gui); assertEquals( "Expected configured difftool to be the default external diff tool", toolName, defaultToolName); - gui = BooleanTriState.TRUE; + gui = true; String defaultGuiToolName = manager.getDefaultToolName(gui); - assertEquals( - "Expected configured difftool to be the default external diff tool", - "my_gui_tool", defaultGuiToolName); + assertNull("Expected default difftool to not be set", + defaultGuiToolName); config.setString(CONFIG_DIFF_SECTION, subsection, CONFIG_KEY_GUITOOL, guiToolName); @@ -210,7 +254,7 @@ public class ExternalDiffToolTest extends ExternalToolTestCase { defaultGuiToolName = manager.getDefaultToolName(gui); assertEquals( "Expected configured difftool to be the default external diff guitool", - "my_gui_tool", defaultGuiToolName); + guiToolName, defaultGuiToolName); } @Test @@ -247,20 +291,39 @@ public class ExternalDiffToolTest extends ExternalToolTestCase { @Test(expected = ToolException.class) public void testUndefinedTool() throws Exception { + String toolName = "undefined"; + invokeCompare(toolName); + fail("Expected exception to be thrown due to not defined external diff tool"); + } + + private Optional<ExecutionResult> invokeCompare(String toolName) + throws ToolException { DiffTools manager = new DiffTools(db); - String toolName = "undefined"; BooleanTriState prompt = BooleanTriState.UNSET; - BooleanTriState gui = BooleanTriState.UNSET; - BooleanTriState trustExitCode = BooleanTriState.UNSET; + boolean gui = false; + BooleanTriState trustExitCode = BooleanTriState.TRUE; + PromptHandler promptHandler = PromptHandler.acceptPrompt(); + MissingToolHandler noToolHandler = new MissingToolHandler(); - manager.compare(local, remote, merged, toolName, prompt, gui, - trustExitCode); - fail("Expected exception to be thrown due to not defined external diff tool"); + Optional<ExecutionResult> result = manager.compare(local, remote, + Optional.of(toolName), prompt, gui, trustExitCode, + promptHandler, noToolHandler); + return result; } private String getEchoCommand() { return "(echo \"$LOCAL\" \"$REMOTE\") > " + commandResult.getAbsolutePath(); } + + private void assertEchoCommandHasCorrectOutput() throws IOException { + List<String> actualLines = Files.readAllLines(commandResult.toPath()); + String actualContent = String.join(System.lineSeparator(), actualLines); + actualLines = Arrays.asList(actualContent.split(" ")); + List<String> expectedLines = Arrays.asList(localFile.getAbsolutePath(), + remoteFile.getAbsolutePath()); + assertEquals("Dummy test tool called with unexpected arguments", + expectedLines, actualLines); + } } 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 index 305f2b470e..130b42a92a 100644 --- 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 @@ -18,13 +18,21 @@ import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_TRUST_EXIT_CODE; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_MERGETOOL_SECTION; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_MERGE_SECTION; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.eclipse.jgit.lib.internal.BooleanTriState; @@ -50,12 +58,7 @@ public class ExternalMergeToolTest extends ExternalToolTestCase { config.setString(CONFIG_MERGETOOL_SECTION, toolName, CONFIG_KEY_TRUST_EXIT_CODE, String.valueOf(Boolean.TRUE)); - MergeTools manager = new MergeTools(db); - - BooleanTriState prompt = BooleanTriState.UNSET; - BooleanTriState gui = BooleanTriState.UNSET; - - manager.merge(local, remote, merged, base, null, toolName, prompt, gui); + invokeMerge(toolName); fail("Expected exception to be thrown due to external tool exiting with error code: " + errorReturnCode); @@ -72,31 +75,112 @@ public class ExternalMergeToolTest extends ExternalToolTestCase { config.setString(CONFIG_MERGETOOL_SECTION, toolName, CONFIG_KEY_CMD, command); + invokeMerge(toolName); + + fail("Expected exception to be thrown due to external tool exiting with error code: " + + errorReturnCode); + } + + @Test + public void testKdiff3() throws Exception { + assumePosixPlatform(); + + CommandLineMergeTool autoMergingTool = CommandLineMergeTool.kdiff3; + assumeMergeToolIsAvailable(autoMergingTool); + + CommandLineMergeTool tool = autoMergingTool; + PreDefinedMergeTool externalTool = new PreDefinedMergeTool(tool.name(), + tool.getPath(), tool.getParameters(true), + tool.getParameters(false), + tool.isExitCodeTrustable() ? BooleanTriState.TRUE + : BooleanTriState.FALSE); + MergeTools manager = new MergeTools(db); + ExecutionResult result = manager.merge(local, remote, merged, null, + null, externalTool); + assertEquals("Expected merge tool to succeed", 0, result.getRc()); + + List<String> actualLines = Files.readAllLines(mergedFile.toPath()); + String actualMergeResult = String.join(System.lineSeparator(), + actualLines); + String expectedMergeResult = DEFAULT_CONTENT; + assertEquals( + "Failed to merge equal local and remote versions with pre-defined tool: " + + tool.getPath(), + expectedMergeResult, actualMergeResult); + } - BooleanTriState prompt = BooleanTriState.UNSET; - BooleanTriState gui = BooleanTriState.UNSET; + @Test + public void testUserDefinedTool() throws Exception { + String customToolName = "customTool"; + String command = getEchoCommand(); - manager.merge(local, remote, merged, base, null, toolName, prompt, gui); + FileBasedConfig config = db.getConfig(); + config.setString(CONFIG_MERGETOOL_SECTION, customToolName, + CONFIG_KEY_CMD, command); - fail("Expected exception to be thrown due to external tool exiting with error code: " - + errorReturnCode); + MergeTools manager = new MergeTools(db); + Map<String, ExternalMergeTool> tools = manager.getUserDefinedTools(); + ExternalMergeTool externalTool = tools.get(customToolName); + manager.merge(local, remote, merged, base, null, externalTool); + + assertEchoCommandHasCorrectOutput(); } @Test - public void testToolNames() { + public void testUserDefinedToolWithPrompt() throws Exception { + String customToolName = "customTool"; + String command = getEchoCommand(); + + FileBasedConfig config = db.getConfig(); + config.setString(CONFIG_MERGETOOL_SECTION, customToolName, + CONFIG_KEY_CMD, command); + MergeTools manager = new MergeTools(db); - Set<String> actualToolNames = manager.getToolNames(); - Set<String> expectedToolNames = Collections.emptySet(); - assertEquals("Incorrect set of external merge tool names", - expectedToolNames, actualToolNames); + + PromptHandler promptHandler = PromptHandler.acceptPrompt(); + MissingToolHandler noToolHandler = new MissingToolHandler(); + + manager.merge(local, remote, merged, base, null, + Optional.of(customToolName), BooleanTriState.TRUE, false, + promptHandler, noToolHandler); + + assertEchoCommandHasCorrectOutput(); + + List<String> actualToolPrompts = promptHandler.toolPrompts; + List<String> expectedToolPrompts = Arrays.asList("customTool"); + assertEquals("Expected a user prompt for custom tool call", + expectedToolPrompts, actualToolPrompts); + + assertEquals("Expected to no informing about missing tools", + Collections.EMPTY_LIST, noToolHandler.missingTools); + } + + @Test + public void testUserDefinedToolWithCancelledPrompt() throws Exception { + MergeTools manager = new MergeTools(db); + + PromptHandler promptHandler = PromptHandler.cancelPrompt(); + MissingToolHandler noToolHandler = new MissingToolHandler(); + + Optional<ExecutionResult> result = manager.merge(local, remote, merged, + base, null, Optional.empty(), BooleanTriState.TRUE, false, + promptHandler, noToolHandler); + assertFalse("Expected no result if user cancels the operation", + result.isPresent()); } @Test public void testAllTools() { + FileBasedConfig config = db.getConfig(); + String customToolName = "customTool"; + config.setString(CONFIG_MERGETOOL_SECTION, customToolName, + CONFIG_KEY_CMD, "echo"); + MergeTools manager = new MergeTools(db); - Set<String> actualToolNames = manager.getPredefinedTools(true).keySet(); + Set<String> actualToolNames = manager.getAllToolNames(); Set<String> expectedToolNames = new LinkedHashSet<>(); + expectedToolNames.add(customToolName); CommandLineMergeTool[] defaultTools = CommandLineMergeTool.values(); for (CommandLineMergeTool defaultTool : defaultTools) { String toolName = defaultTool.name(); @@ -165,16 +249,12 @@ public class ExternalMergeToolTest extends ExternalToolTestCase { config.setString(CONFIG_MERGETOOL_SECTION, toolName, CONFIG_KEY_CMD, command); - BooleanTriState prompt = BooleanTriState.UNSET; - BooleanTriState gui = BooleanTriState.UNSET; - - MergeTools manager = new MergeTools(db); - + Optional<ExecutionResult> result = invokeMerge(toolName); + assertTrue("Expected external merge tool result to be available", + result.isPresent()); int expectedCompareResult = 0; - ExecutionResult compareResult = manager.merge(local, remote, merged, - base, null, toolName, prompt, gui); assertEquals("Incorrect compare result for external merge tool", - expectedCompareResult, compareResult.getRc()); + expectedCompareResult, result.get().getRc()); } @Test @@ -189,17 +269,16 @@ public class ExternalMergeToolTest extends ExternalToolTestCase { toolName); MergeTools manager = new MergeTools(db); - BooleanTriState gui = BooleanTriState.UNSET; + boolean gui = false; String defaultToolName = manager.getDefaultToolName(gui); assertEquals( "Expected configured mergetool to be the default external merge tool", toolName, defaultToolName); - gui = BooleanTriState.TRUE; + gui = true; String defaultGuiToolName = manager.getDefaultToolName(gui); - assertEquals( - "Expected configured mergetool to be the default external merge tool", - "my_gui_tool", defaultGuiToolName); + assertNull("Expected default mergetool to not be set", + defaultGuiToolName); config.setString(CONFIG_MERGE_SECTION, subsection, CONFIG_KEY_GUITOOL, guiToolName); @@ -207,7 +286,7 @@ public class ExternalMergeToolTest extends ExternalToolTestCase { defaultGuiToolName = manager.getDefaultToolName(gui); assertEquals( "Expected configured mergetool to be the default external merge guitool", - "my_gui_tool", defaultGuiToolName); + guiToolName, defaultGuiToolName); } @Test @@ -245,18 +324,48 @@ public class ExternalMergeToolTest extends ExternalToolTestCase { @Test(expected = ToolException.class) public void testUndefinedTool() throws Exception { - MergeTools manager = new MergeTools(db); - String toolName = "undefined"; + invokeMerge(toolName); + fail("Expected exception to be thrown due to not defined external merge tool"); + } + + private Optional<ExecutionResult> invokeMerge(String toolName) + throws ToolException { BooleanTriState prompt = BooleanTriState.UNSET; - BooleanTriState gui = BooleanTriState.UNSET; + boolean gui = false; - manager.merge(local, remote, merged, base, null, toolName, prompt, gui); - fail("Expected exception to be thrown due to not defined external merge tool"); + MergeTools manager = new MergeTools(db); + + PromptHandler promptHandler = PromptHandler.acceptPrompt(); + MissingToolHandler noToolHandler = new MissingToolHandler(); + + Optional<ExecutionResult> result = manager.merge(local, remote, merged, + base, null, Optional.of(toolName), prompt, gui, promptHandler, + noToolHandler); + return result; + } + + private void assumeMergeToolIsAvailable( + CommandLineMergeTool autoMergingTool) { + boolean isAvailable = ExternalToolUtils.isToolAvailable(db.getFS(), + db.getDirectory(), db.getWorkTree(), autoMergingTool.getPath()); + assumeTrue("Assuming external tool is available: " + + autoMergingTool.name(), isAvailable); } private String getEchoCommand() { - return "(echo \"$LOCAL\" \"$REMOTE\") > " + return "(echo $LOCAL $REMOTE $MERGED $BASE) > " + commandResult.getAbsolutePath(); } + + private void assertEchoCommandHasCorrectOutput() throws IOException { + List<String> actualLines = Files.readAllLines(commandResult.toPath()); + String actualContent = String.join(System.lineSeparator(), actualLines); + actualLines = Arrays.asList(actualContent.split(" ")); + List<String> expectedLines = Arrays.asList(localFile.getAbsolutePath(), + remoteFile.getAbsolutePath(), mergedFile.getAbsolutePath(), + baseFile.getAbsolutePath()); + assertEquals("Dummy test tool called with unexpected arguments", + expectedLines, actualLines); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalToolTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalToolTestCase.java index 0fd85cb456..7a6ff46578 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalToolTestCase.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/diffmergetool/ExternalToolTestCase.java @@ -11,6 +11,8 @@ package org.eclipse.jgit.internal.diffmergetool; import java.io.File; import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.util.FS; @@ -88,4 +90,39 @@ public abstract class ExternalToolTestCase extends RepositoryTestCase { "This test can run only in Linux tests", FS.DETECTED instanceof FS_POSIX); } + + protected static class PromptHandler implements PromptContinueHandler { + + private final boolean promptResult; + + final List<String> toolPrompts = new ArrayList<>(); + + private PromptHandler(boolean promptResult) { + this.promptResult = promptResult; + } + + static PromptHandler acceptPrompt() { + return new PromptHandler(true); + } + + static PromptHandler cancelPrompt() { + return new PromptHandler(false); + } + + @Override + public boolean prompt(String toolName) { + toolPrompts.add(toolName); + return promptResult; + } + } + + protected static class MissingToolHandler implements InformNoToolHandler { + + final List<String> missingTools = new ArrayList<>(); + + @Override + public void inform(List<String> toolNames) { + missingTools.addAll(toolNames); + } + } } |