CC-Tweaked/buildSrc/src/main/kotlin/cc/tweaked/gradle/ProcessHelpers.kt

78 lines
2.7 KiB
Kotlin

// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.codehaus.groovy.runtime.ProcessGroovyMethods
import org.gradle.api.GradleException
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.nio.charset.StandardCharsets
internal object ProcessHelpers {
fun startProcess(vararg command: String): Process {
// Something randomly passes in "GIT_DIR=" as an environment variable which clobbers everything else. Don't
// inherit the environment array!
return ProcessBuilder()
.command(*command)
.redirectError(ProcessBuilder.Redirect.INHERIT)
.also { it.environment().clear() }
.start()
}
fun captureOut(vararg command: String): String {
val process = startProcess(*command)
process.outputStream.close()
val result = ProcessGroovyMethods.getText(process)
process.waitForOrThrow("Failed to run command")
return result
}
fun captureLines(vararg command: String): List<String> {
val process = startProcess(*command)
process.outputStream.close()
val out = BufferedReader(InputStreamReader(process.inputStream, StandardCharsets.UTF_8)).use { reader ->
reader.lines().filter { it.isNotEmpty() }.toList()
}
ProcessGroovyMethods.closeStreams(process)
process.waitForOrThrow("Failed to run command")
return out
}
fun onPath(name: String): Boolean {
val path = System.getenv("PATH") ?: return false
return path.splitToSequence(File.pathSeparator).any { File(it, name).exists() }
}
/**
* Search for an executable on the `PATH` if required.
*
* [Process]/[ProcessBuilder] does not handle all executable file extensions on Windows (such as `.com). When on
* Windows, this function searches `PATH` and `PATHEXT` for an executable matching [name].
*/
fun getExecutable(name: String): String {
if (!System.getProperty("os.name").lowercase().contains("windows")) return name
val path = (System.getenv("PATH") ?: return name).split(File.pathSeparator)
val pathExt = (System.getenv("PATHEXT") ?: return name).split(File.pathSeparator)
for (pathEntry in path) {
for (ext in pathExt) {
val resolved = File(pathEntry, name + ext)
if (resolved.exists()) return resolved.getAbsolutePath()
}
}
return name
}
}
internal fun Process.waitForOrThrow(message: String) {
val ret = waitFor()
if (ret != 0) throw GradleException("$message (exited with $ret)")
}