Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ dependencies:
org.slf4j:slf4j-simple: "2.0.17"

actions:
clean: ".{/}mvnw clean"
build: ".{/}mvnw spotless:apply package -DskipTests"
run: "{./target/binary/bin/jpm}"
test: ".{/}mvnw test"
clean: "./mvnw clean"
build: "./mvnw spotless:apply package -DskipTests"
run: "./target/binary/bin/jpm"
test: "./mvnw test"
buildj: "javac -cp {{deps}} -d classes --source-path src/main/java src/main/java/org/codejive/jpm/Main.java"
runj: "java -cp classes:{{deps}} org.codejive.jpm.Main"
53 changes: 38 additions & 15 deletions src/main/java/org/codejive/jpm/util/ScriptUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,7 @@ public static int executeScript(String command, List<Path> classpath, boolean ve
(isWindows() && tmpCommand.length() > 8000)
|| (!isWindows() && tmpCommand.length() > 32000);

if (!usingSubstitutions(command)) {
// First try to parse the command
CommandsParser parser = new CommandsParser(command);
CommandsParser.Commands commands = parser.parse();
if (commands != null) {
command = suggestSubstitutions(commands);
}
}
command = suggestSubstitutions(command);

try (ArgsFiles argsFiles = new ArgsFiles()) {
// Process the command for variable substitution and path conversion
Expand Down Expand Up @@ -73,21 +66,33 @@ public static String quoteArgument(String arg) {
return arg;
}

static String suggestSubstitutions(String command) {
if (!usingSubstitutions(command)) {
// First try to parse the command
CommandsParser parser = new CommandsParser(command);
CommandsParser.Commands commands = parser.parse();
if (commands != null) {
command = suggestCommandsSubstitutions(commands);
}
}
return command;
}

// Is the command using any substitutions? (we ignore {{deps}} here)
private static boolean usingSubstitutions(String command) {
command = command.replace("{]}", "\u0007");
Pattern pattern = Pattern.compile("\\{([/:;~]|\\./.*|~/.*)}|@\\[.*]");
return pattern.matcher(command).find();
}

static String suggestSubstitutions(CommandsParser.Commands commands) {
private static String suggestCommandsSubstitutions(CommandsParser.Commands commands) {
StringBuilder cmd = new StringBuilder();
for (CommandsParser.Node node : commands.elements) {
if (node instanceof CommandsParser.Command) {
cmd.append(suggestSubstitutions((CommandsParser.Command) node));
cmd.append(suggestCommandSubstitutions((CommandsParser.Command) node));
} else if (node instanceof CommandsParser.Group) {
CommandsParser.Group group = (CommandsParser.Group) node;
String groupStr = suggestSubstitutions(group.commands);
String groupStr = suggestCommandsSubstitutions(group.commands);
cmd.append("(").append(groupStr).append(")");
} else if (node instanceof CommandsParser.Separator) {
CommandsParser.Separator sep = (CommandsParser.Separator) node;
Expand All @@ -101,7 +106,7 @@ static String suggestSubstitutions(CommandsParser.Commands commands) {
return cmd.toString();
}

static String suggestSubstitutions(CommandsParser.Command command) {
static String suggestCommandSubstitutions(CommandsParser.Command command) {
StringBuilder cmd = new StringBuilder();
if (command.words.isEmpty()) {
return "";
Expand Down Expand Up @@ -179,12 +184,30 @@ private static String suggestClassPathSubstitution(String classpath) {
if (parts.length <= 1) {
return null;
}
// First see if this plausibly looks like a classpath
// This requires at least one part to be a relative path with
// at least two parts (i.e. have at least one / in it)
// This does mean that it won't suggest substitutions for
// classpaths that are all single-name parts (e.g. "lib:ext").
if (!classpath.contains("{{deps}}")) {
boolean hasAtLeastOneComplexPart = false;
for (String path : parts) {
Path p = FileUtils.safePath(path);
if (p == null || p.isAbsolute()) {
return null;
}
if (p.getNameCount() >= 2) {
hasAtLeastOneComplexPart = true;
}
}
if (!hasAtLeastOneComplexPart) {
return null;
}
}
// Now do the actual conversion
StringBuilder sb = new StringBuilder();
for (String path : parts) {
Path p = FileUtils.safePath(path);
if (p == null || p.isAbsolute()) {
return null;
}
if (sb.length() == 0) {
// Looks like a relative path, let's suggest {./...} or {~/...}
if (p.startsWith("~")) {
Expand Down
8 changes: 8 additions & 0 deletions src/test/java/org/codejive/jpm/util/ScriptUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,12 @@ void testProcessMultiCommandArgsFilesUse() throws Exception {
assertThat(argsFiles.files.get(1)).hasContent(expectedContents2);
}
}

@Test
void testProcessCommandWithInvalidClasspath() {
String command = "./mvnw spotless:apply package -DskipTests";
String result = ScriptUtils.suggestSubstitutions(command);
// Substitutions should not have treated spottless:apply as a classpath
assertThat(result).isEqualTo("{./mvnw} spotless:apply package -DskipTests");
}
}
Loading