From f76420ceebc26cdb73380b17bbce1b78a8764811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lars=C3=A9n?= Date: Thu, 26 Mar 2020 10:13:30 +0100 Subject: [PATCH] [feat] Add Git compatibility mode, fix #84 This consists of hard linking .merge_file_xxx files to .merge_file_xxx.java, and then removing those hard links when the JVM exits. --- src/main/java/se/kth/spork/cli/Cli.java | 45 ++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/main/java/se/kth/spork/cli/Cli.java b/src/main/java/se/kth/spork/cli/Cli.java index de119012..73b2e92c 100644 --- a/src/main/java/se/kth/spork/cli/Cli.java +++ b/src/main/java/se/kth/spork/cli/Cli.java @@ -143,11 +143,31 @@ private static class MergeCommand implements Callable { description = "Path to the output file. Existing files are overwritten") File out; + @CommandLine.Option( + names = {"--git-mode"}, + description = "Enable Git compatibility mode. Required to use Spork as a Git merge driver." + ) + boolean gitMode; + @Override public Integer call() throws IOException { long start = System.nanoTime(); - String pretty = merge(base.toPath(), left.toPath(), right.toPath()); + Path basePath = base.toPath(); + Path leftPath = left.toPath(); + Path rightPath = right.toPath(); + + if (gitMode) { + basePath = gitCompatHardLink(basePath); + leftPath = gitCompatHardLink(leftPath); + rightPath = gitCompatHardLink(rightPath); + + basePath.toFile().deleteOnExit(); + leftPath.toFile().deleteOnExit(); + rightPath.toFile().deleteOnExit(); + } + + String pretty = merge(basePath, leftPath, rightPath); if (out != null) { LOGGER.info("Writing merge to " + out); @@ -193,6 +213,29 @@ public static String merge(Path base, Path left, Path right) { } } + /** + * Create a hard link from a temporary git .merge_xxx file, with the name .merge_xxx.java. This is necessary for + * Spork to be compatible with Git, as Spoon will only parse Java files if they actually have the .java file + * extension. + * + * @param path Path to the temporary merge file. + * @return A path to a new hard link to the file, but with a .java file extension. + */ + private static Path gitCompatHardLink(Path path) throws IOException { + if (!path.getFileName().toString().startsWith(".merge_file")) { + throw new IllegalArgumentException(path + " not a Git merge file"); + } + + Path compatLink = path.resolveSibling(path.getFileName().toString() + ".java"); + try { + Files.createLink(compatLink, path); + } catch (UnsupportedOperationException x) { + throw new IllegalStateException("Creating Git compatibility hard link not supported by file system"); + } + + return compatLink; + } + private static boolean containsTypes(CtElement elem) { List> types = elem.getElements(e -> true); return types.size() > 0;