From 841518bf055c5e2cf3c1c3a48a4ae1426e1105b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Pa=C3=9F?= <22845248+mpass99@users.noreply.github.com> Date: Sun, 24 Apr 2022 17:55:41 +0200 Subject: [PATCH] Java11Exec: Add support for make assignments. (#131) * Java11Exec: Add support for make assignments. * Java11Exec: Make quotes in assignments optional. --- .../main/java/poseidon/SimpleMakefile.java | 32 +++++++++++++++++-- .../java/poseidon/SimpleMakefileTest.java | 24 ++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/deploy/aws/java11Exec/src/main/java/poseidon/SimpleMakefile.java b/deploy/aws/java11Exec/src/main/java/poseidon/SimpleMakefile.java index cb7a7cf..920305a 100644 --- a/deploy/aws/java11Exec/src/main/java/poseidon/SimpleMakefile.java +++ b/deploy/aws/java11Exec/src/main/java/poseidon/SimpleMakefile.java @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; // NoMakefileFoundException is thrown if no makefile could be found. class NoMakefileFoundException extends Exception {} @@ -21,7 +22,7 @@ class InvalidMakefileException extends Exception {} class SimpleMakefile { // This pattern validates if a command is a make command. - private static final Pattern isMakeCommand = Pattern.compile("^make(?:\\s+(?\\w*))?$"); + private static final Pattern isMakeCommand = Pattern.compile("^make(?:\\s+(?\\w*))?(?(?:.*?=.*?)+)?$"); // This pattern identifies the rules in a makefile. private static final Pattern makeRules = Pattern.compile("(?.*):\\r?\\n(?(?:\\t.+\\r?\\n?)*)"); @@ -87,6 +88,31 @@ class SimpleMakefile { return concatCommands(rules.get(rule)); } + // getAssignmentPart returns the key or value of the passed assignment depending on the flag firstPart. + private String getAssignmentPart(String assignment, boolean firstPart) { + String[] parts = assignment.split("="); + + if (firstPart) { + return parts[0]; + } else { + return parts[1].replaceAll("^\\\"|\\\"$", ""); + } + } + + // injectAssignments applies all set assignments in the command string. + private String injectAssignments(String command, String assignments) { + String result = command; + Map map = Arrays.stream(assignments.split(" ")) + .filter(s -> !s.isEmpty()) + .collect(Collectors.toMap(s -> getAssignmentPart(s, true), s -> getAssignmentPart(s, false))); + + for (Map.Entry entry : map.entrySet()) { + result = result.replaceAll("\\$\\{" + entry.getKey() + "\\}", entry.getValue()); + } + + return result; + } + // parseCommand returns a bash line of commands that would be executed by the passed command. public String parseCommand(String shellCommand) throws InvalidMakefileException, NoMakeCommandException { Matcher makeCommandMatcher = isMakeCommand.matcher(shellCommand); @@ -103,6 +129,8 @@ class SimpleMakefile { throw new InvalidMakefileException(); } - return getCommand(ruleArgument); + String command = getCommand(ruleArgument); + String assignments = makeCommandMatcher.group("assignments"); + return injectAssignments(command, (assignments != null) ? assignments : ""); } } diff --git a/deploy/aws/java11Exec/src/test/java/poseidon/SimpleMakefileTest.java b/deploy/aws/java11Exec/src/test/java/poseidon/SimpleMakefileTest.java index 933e5a1..581d0af 100644 --- a/deploy/aws/java11Exec/src/test/java/poseidon/SimpleMakefileTest.java +++ b/deploy/aws/java11Exec/src/test/java/poseidon/SimpleMakefileTest.java @@ -37,6 +37,12 @@ public class SimpleMakefileTest { "\t@java org/example/RecursiveMath\r\n" ).getBytes(StandardCharsets.UTF_8)); + static final String SuccessfulMakefileWithAssignments = Base64.getEncoder().encodeToString( + ("test:\n" + + "\tjavac -encoding utf8 -cp .:/usr/java/lib/hamcrest-core-1.3.jar:/usr/java/lib/junit-4.11.jar ${FILENAME}\n" + + "\tjava -Dfile.encoding=UTF8 -cp .:/usr/java/lib/hamcrest-core-1.3.jar:/usr/java/lib/junit-4.11.jar org.junit.runner.JUnitCore ${CLASS_NAME}\n" + ).getBytes(StandardCharsets.UTF_8)); + static final String SuccessfulMakefileWithComment = Base64.getEncoder().encodeToString( ("run:\r\n" + "\t@javac org/example/RecursiveMath.java\r\n" + @@ -109,6 +115,24 @@ public class SimpleMakefileTest { } catch (NoMakeCommandException ignored) {} } + @Test + public void sucessfullMakeWithAssignments() { + Map files = new HashMap<>(); + files.put("Makefile", SuccessfulMakefileWithAssignments); + files.put("org/example/RecursiveMath.java", RecursiveMathContent); + + try { + String command = "make test CLASS_NAME=\"RecursiveMath\" FILENAME=\"RecursiveMath-Test.java\""; + SimpleMakefile make = new SimpleMakefile(files); + String cmd = make.parseCommand(command); + + assertEquals("javac -encoding utf8 -cp .:/usr/java/lib/hamcrest-core-1.3.jar:/usr/java/lib/junit-4.11.jar RecursiveMath-Test.java && " + + "java -Dfile.encoding=UTF8 -cp .:/usr/java/lib/hamcrest-core-1.3.jar:/usr/java/lib/junit-4.11.jar org.junit.runner.JUnitCore RecursiveMath", cmd); + } catch (NoMakefileFoundException | InvalidMakefileException | NoMakeCommandException ignored) { + fail(); + } + } + @Test public void withNotSupportedMakefile() { Map files = new HashMap<>();