From 7b17632caa177e92ecd3234fe505e0f8b4cc5f45 Mon Sep 17 00:00:00 2001
From: ascopes <73482956+ascopes@users.noreply.github.com>
Date: Sun, 21 Apr 2024 12:23:53 +0100
Subject: [PATCH] Make Shlex emit line continutations
---
.../protobufmavenplugin/utils/Shlex.java | 55 ++++++++++++++-----
.../protobufmavenplugin/utils/ShlexTest.java | 22 +++++++-
2 files changed, 60 insertions(+), 17 deletions(-)
diff --git a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/utils/Shlex.java b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/utils/Shlex.java
index a0125c70..a5d520c7 100644
--- a/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/utils/Shlex.java
+++ b/protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/utils/Shlex.java
@@ -16,7 +16,7 @@
package io.github.ascopes.protobufmavenplugin.utils;
-import java.util.function.BiConsumer;
+import java.util.function.Function;
/**
* Shell/batch file quoting.
@@ -24,25 +24,35 @@
*
Losely based on Python's {@code shlex} module.
*
*
This is far from perfect but should work in the majority of use cases
- * to ensure scripts do not interpret special characters in paths in strange and unexpected ways.
+ * to ensure scripts do not interpret special characters in paths in strange
+ * and unexpected ways.
+ *
+ *
Long lines will be split up with line continuations.
*
* @author Ashley Scopes
*/
public final class Shlex {
+ private static final int LINE_LENGTH_TARGET = 99;
+ private static final String INDENT = " ".repeat(4);
+
private Shlex() {
// Static-only class
}
public static String quoteShellArgs(Iterable args) {
- return quote(args, Shlex::quoteShellArg);
+ return quote(args, Shlex::quoteShellArg, " \\\n");
}
public static String quoteBatchArgs(Iterable args) {
- return quote(args, Shlex::quoteBatchArg);
+ return quote(args, Shlex::quoteBatchArg, " ^\r\n");
}
- private static String quote(Iterable args, BiConsumer quoter) {
+ private static String quote(
+ Iterable args,
+ Function quoter,
+ String continuation
+ ) {
var iter = args.iterator();
if (!iter.hasNext()) {
@@ -50,23 +60,34 @@ private static String quote(Iterable args, BiConsumer= LINE_LENGTH_TARGET) {
+ sb.append(continuation);
+ lineLength = INDENT.length();
+ sb.append(INDENT);
+ } else {
+ sb.append(" ");
+ lineLength += 1;
+ }
+
+ sb.append(next);
+ lineLength += next.length();
}
return sb.toString();
}
- private static void quoteShellArg(StringBuilder sb, String arg) {
+ private static String quoteShellArg(String arg) {
if (isSafe(arg)) {
- sb.append(arg);
- return;
+ return arg;
}
+ var sb = new StringBuilder();
sb.append('\'');
for (var i = 0; i < arg.length(); ++i) {
var c = arg.charAt(i);
@@ -89,14 +110,16 @@ private static void quoteShellArg(StringBuilder sb, String arg) {
}
}
sb.append('\'');
+
+ return sb.toString();
}
- private static void quoteBatchArg(StringBuilder sb, String arg) {
+ private static String quoteBatchArg(String arg) {
if (isSafe(arg)) {
- sb.append(arg);
- return;
+ return arg;
}
+ var sb = new StringBuilder();
for (var i = 0; i < arg.length(); ++i) {
var c = arg.charAt(i);
switch (c) {
@@ -121,6 +144,8 @@ private static void quoteBatchArg(StringBuilder sb, String arg) {
break;
}
}
+
+ return sb.toString();
}
private static boolean isSafe(String arg) {
diff --git a/protobuf-maven-plugin/src/test/java/io/github/ascopes/protobufmavenplugin/utils/ShlexTest.java b/protobuf-maven-plugin/src/test/java/io/github/ascopes/protobufmavenplugin/utils/ShlexTest.java
index 33e47db6..567cde68 100644
--- a/protobuf-maven-plugin/src/test/java/io/github/ascopes/protobufmavenplugin/utils/ShlexTest.java
+++ b/protobuf-maven-plugin/src/test/java/io/github/ascopes/protobufmavenplugin/utils/ShlexTest.java
@@ -85,7 +85,16 @@ static Stream quoteShellArgsTestCases() {
arguments(list("'potato'"), "''\"'\"'potato'\"'\"''"),
arguments(list("foo\nbar", "baz"), "'foo'$'\\n''bar' baz"),
arguments(list("foo\rbar", "baz"), "'foo'$'\\r''bar' baz"),
- arguments(list("foo\tbar", "baz"), "'foo'$'\\t''bar' baz")
+ arguments(list("foo\tbar", "baz"), "'foo'$'\\t''bar' baz"),
+ arguments(
+ list("a".repeat(100), "b".repeat(100), "c".repeat(100)),
+ String.join(
+ " \\\n ",
+ "a".repeat(100),
+ "b".repeat(100),
+ "c".repeat(100)
+ )
+ )
);
}
@@ -115,7 +124,16 @@ static Stream quoteBatchArgsTestCases() {
arguments(list("<"), "^<"),
arguments(list(">"), "^>"),
arguments(list("|"), "^|"),
- arguments(list("100% complete", "0% incomplete"), "100%%^ complete 0%%^ incomplete")
+ arguments(list("100% complete", "0% incomplete"), "100%%^ complete 0%%^ incomplete"),
+ arguments(
+ list("a".repeat(100), "b".repeat(100), "c".repeat(100)),
+ String.join(
+ " ^\r\n ",
+ "a".repeat(100),
+ "b".repeat(100),
+ "c".repeat(100)
+ )
+ )
);
}