diff options
-rw-r--r-- | buildSrc/src/main/groovy/org/jetbrains/CrossPlatformExec.groovy | 92 | ||||
-rw-r--r-- | runners/maven-plugin/build.gradle | 5 |
2 files changed, 95 insertions, 2 deletions
diff --git a/buildSrc/src/main/groovy/org/jetbrains/CrossPlatformExec.groovy b/buildSrc/src/main/groovy/org/jetbrains/CrossPlatformExec.groovy new file mode 100644 index 00000000..9c6780f7 --- /dev/null +++ b/buildSrc/src/main/groovy/org/jetbrains/CrossPlatformExec.groovy @@ -0,0 +1,92 @@ +package org.jetbrains + +import org.gradle.api.tasks.AbstractExecTask +import org.gradle.api.tasks.TaskAction +import org.gradle.internal.os.OperatingSystem + +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + +class CrossPlatformExec extends AbstractExecTask { + private static final def windowsExtensions = ['bat', 'cmd', 'exe']; + private static final def unixExtensions = [null, 'sh']; + + private boolean windows; + + public CrossPlatformExec() { + super(CrossPlatformExec.class); + windows = OperatingSystem.current().windows; + } + + @Override + @TaskAction + protected void exec() { + List<String> commandLine = this.getCommandLine(); + + if (!commandLine.isEmpty()) { + commandLine[0] = findCommand(workingDir, commandLine[0], windows); + } + + if (windows) { + if (!commandLine.isEmpty() && commandLine[0]) { + commandLine + } + commandLine.add(0, '/c'); + commandLine.add(0, 'cmd'); + } + + this.setCommandLine(commandLine); + + super.exec(); + } + + private static String findCommand(File workingDir, String command, boolean windows) { + command = normalizeCommandPaths(command); + def extensions = windows ? windowsExtensions : unixExtensions; + + return extensions.findResult(command) { extension -> + Path commandFile + if (extension) { + commandFile = Paths.get(command + '.' + extension); + } else { + commandFile = Paths.get(command); + } + + return resolveCommandFromFile(workingDir, commandFile, windows); + }; + } + + private static String resolveCommandFromFile(File workingDir, Path commandFile, boolean windows) { + if (!Files.isExecutable(commandFile)) { + return null; + } + + Path cwd = Paths.get(workingDir.absolutePath).toAbsolutePath().normalize(); + + String resolvedCommand = cwd.relativize(commandFile.toAbsolutePath().normalize()); + + if (!windows && !resolvedCommand.startsWith('.')) { + resolvedCommand = '.' + File.separator + resolvedCommand; + } + + return resolvedCommand; + } + + private static String normalizeCommandPaths(String command) { + // need to escape backslash so it works with regex + String backslashSeparator = '\\\\'; + + String forwardSlashSeparator = '/'; + + // escape separator if it's a backslash + char backslash = '\\'; + String separator = File.separatorChar == backslash ? backslashSeparator : File.separator + + return command + // first replace all of the backslashes with forward slashes + .replaceAll(backslashSeparator, forwardSlashSeparator) + // then replace all forward slashes with whatever the separator actually is + .replaceAll(forwardSlashSeparator, separator); + } +}
\ No newline at end of file diff --git a/runners/maven-plugin/build.gradle b/runners/maven-plugin/build.gradle index e69d1eb1..d73126f4 100644 --- a/runners/maven-plugin/build.gradle +++ b/runners/maven-plugin/build.gradle @@ -1,3 +1,4 @@ +import org.jetbrains.CrossPlatformExec apply plugin: 'kotlin' apply plugin: 'com.github.johnrengelman.shadow' @@ -31,12 +32,12 @@ task generatePom << { .replace("<version>maven-plugin-plugin</version>", "<version>$maven_plugin_tools_version</version>") } -task pluginDescriptor(type: Exec) { +task pluginDescriptor(type: CrossPlatformExec) { workingDir buildDir commandLine mvn, '-e', '-B', 'org.apache.maven.plugins:maven-plugin-plugin:descriptor' } -task helpMojo(type: Exec) { +task helpMojo(type: CrossPlatformExec) { workingDir buildDir commandLine mvn, '-e', '-B', 'org.apache.maven.plugins:maven-plugin-plugin:helpmojo' } |