From 85191a53acd370561ef78097ae6496aa874085d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Champeau?= Date: Sat, 19 Mar 2022 15:54:40 +0100 Subject: [PATCH] Support spaces in paths in argfile (#403) This commit fixes the AOT tasks which use `@arfile` for calling Micronaut AOT: they suffer the same bug as in native build tools, which is that spaces in paths need to be escaped. See #401 --- .../aot/AbstractMicronautAotCliTask.java | 10 ++++++- .../gradle/aot/BasicMicronautAOTSpec.groovy | 17 ++++++++++- .../gradle/AbstractGradleBuildSpec.groovy | 29 +++++++++++++------ 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/aot-plugin/src/main/java/io/micronaut/gradle/aot/AbstractMicronautAotCliTask.java b/aot-plugin/src/main/java/io/micronaut/gradle/aot/AbstractMicronautAotCliTask.java index feea18f4..1bdbedd1 100644 --- a/aot-plugin/src/main/java/io/micronaut/gradle/aot/AbstractMicronautAotCliTask.java +++ b/aot-plugin/src/main/java/io/micronaut/gradle/aot/AbstractMicronautAotCliTask.java @@ -90,7 +90,7 @@ public final void execute() throws IOException { configureExtraArguments(args); boolean useArgFile = true; try (PrintWriter wrt = new PrintWriter(new FileWriter(argFile))) { - args.forEach(wrt::println); + args.forEach(arg -> wrt.println(escapeArg(arg))); } catch (IOException e) { useArgFile = false; } @@ -128,4 +128,12 @@ private void maybeAddOptimizerClasspath(List args, ConfigurableFileColle } } + private static String escapeArg(String arg) { + arg = arg.replace("\\", "\\\\"); + if (arg.contains(" ")) { + arg = "\"" + arg + "\""; + } + return arg; + } + } diff --git a/functional-tests/src/test/groovy/io/micronaut/gradle/aot/BasicMicronautAOTSpec.groovy b/functional-tests/src/test/groovy/io/micronaut/gradle/aot/BasicMicronautAOTSpec.groovy index 01ea1046..56cbb0c9 100644 --- a/functional-tests/src/test/groovy/io/micronaut/gradle/aot/BasicMicronautAOTSpec.groovy +++ b/functional-tests/src/test/groovy/io/micronaut/gradle/aot/BasicMicronautAOTSpec.groovy @@ -1,6 +1,7 @@ package io.micronaut.gradle.aot - +import org.gradle.testkit.runner.TaskOutcome +import spock.lang.Issue import spock.lang.Requires @Requires({ jvm.isJava11Compatible() }) @@ -138,4 +139,18 @@ class BasicMicronautAOTSpec extends AbstractAOTPluginSpec { } + @Issue("https://github.com/micronaut-projects/micronaut-gradle-plugin/issues/401") + def "supports spaces in file names"() { + withSpacesInTestDir() + withSample("aot/basic-app") + withPlugins(Plugins.MINIMAL_APPLICATION) + println("Base directory: $baseDir") + + when: + def result = build "prepareJitOptimizations" + + then: + result.task(":prepareJitOptimizations").outcome == TaskOutcome.SUCCESS + } + } diff --git a/minimal-plugin/src/testFixtures/groovy/io/micronaut/gradle/AbstractGradleBuildSpec.groovy b/minimal-plugin/src/testFixtures/groovy/io/micronaut/gradle/AbstractGradleBuildSpec.groovy index a2114584..31d21615 100644 --- a/minimal-plugin/src/testFixtures/groovy/io/micronaut/gradle/AbstractGradleBuildSpec.groovy +++ b/minimal-plugin/src/testFixtures/groovy/io/micronaut/gradle/AbstractGradleBuildSpec.groovy @@ -19,24 +19,35 @@ abstract class AbstractGradleBuildSpec extends Specification { @Rule TemporaryFolder testProjectDir = new TemporaryFolder() + protected Path baseDir - File settingsFile - File buildFile - File kotlinBuildFile + File getSettingsFile() { + baseDir.resolve("settings.gradle").toFile() + } + + File getBuildFile() { + baseDir.resolve("build.gradle").toFile() + } + + File getKotlinBuildFile() { + baseDir.resolve("build.gradle.kts").toFile() + } // This can be used during development to add statements like includeBuild final List postSettingsStatements = [ ] def setup() { - settingsFile = testProjectDir.newFile('settings.gradle') - buildFile = testProjectDir.newFile('build.gradle') - kotlinBuildFile = testProjectDir.newFile('build.gradle.kts') + baseDir = testProjectDir.root.toPath() + } + + void withSpacesInTestDir() { + baseDir = testProjectDir.newFolder("with spaces").toPath() } protected void withSample(String name) { File sampleDir = new File("../samples/$name").canonicalFile - copySample(sampleDir.toPath(), testProjectDir.root.toPath()) + copySample(sampleDir.toPath(), baseDir) } private static void copySample(Path from, Path into) { @@ -51,7 +62,7 @@ abstract class AbstractGradleBuildSpec extends Specification { } File file(String relativePath) { - testProjectDir.root.toPath().resolve(relativePath).toFile() + baseDir.resolve(relativePath).toFile() } def getRepositoriesBlock(String dsl = 'groovy') { @@ -85,7 +96,7 @@ abstract class AbstractGradleBuildSpec extends Specification { ) } } - runner.withProjectDir(testProjectDir.root) + runner.withProjectDir(baseDir.toFile()) .withArguments(["--no-watch-fs", "-S", "-Porg.gradle.java.installations.auto-download=false",