How to run execute string as a shell command in Kotlin DSL?

I’m migrating to Kotlin DSL.
The old commands look like:

final gitBranch = "git rev-parse --abbrev-ref HEAD".execute().text.trim()
final gitTag = "git tag -l --points-at HEAD".execute().text.trim()
final gitCommitId = "git rev-parse --short=8 HEAD".execute().text.trim()

In Kotlin DSL i have not found the same way.
Tried this approach:https://stackoverflow.com/questions/35421699/how-to-invoke-external-command-from-within-kotlin-code

but is there is any built-in way?

Perhaps the kotlin equivalent of

project.exec {
   commandLine = "git rev-parse --abbrev-ref HEAD".split(" ")
} 

But how than i capture the output?

String.execute() is a groovy enhancement which is why it’s not available in Kotlin. It has nothing to do with Gradle. See Groovy String Enhancements

But how than i capture the output?

See Project.exec(ExecSpec)

Eg:

ByteArrayOutputStream byteOut = new ByteArrayOutputStream() 
project.exec {
   commandLine = "git rev-parse --abbrev-ref HEAD".split(" ")
   standardOutput = byteOut
} 
String output = new String(byteOut.toByteArray())

I hoped to have smth shorter ((. Than i’d better introduce a function, like in this answer:

fun String.runCommand(workingDir: File = file("./")): String {
    val parts = this.split("\\s".toRegex())
    val proc = ProcessBuilder(*parts.toTypedArray())
            .directory(workingDir)
            .redirectOutput(ProcessBuilder.Redirect.PIPE)
            .redirectError(ProcessBuilder.Redirect.PIPE)
            .start()

    proc.waitFor(1, TimeUnit.MINUTES)
    return proc.inputStream.bufferedReader().readText().trim()
}

I’d use project.exec rather than ProcessBuilder directly. I’m sure there’s some nice error handling etc in the Gradle version

unfortunately i’ve not understood how to use that code snippe with project.exec. Shall i repeat all these 5 lines for each command i want to execute?

with ProcessBuilder i declare fun runCommand once and reuse it in the build script:

fun String.runCommand(workingDir: File = file("./")): String {
    val parts = this.split("\\s".toRegex())
    val proc = ProcessBuilder(*parts.toTypedArray())
            .directory(workingDir)
            .redirectOutput(ProcessBuilder.Redirect.PIPE)
            .redirectError(ProcessBuilder.Redirect.PIPE)
            .start()

    proc.waitFor(1, TimeUnit.MINUTES)
    return proc.inputStream.bufferedReader().readText().trim()
}

val gitBranch = "git rev-parse --abbrev-ref HEAD".runCommand()
val gitTag = "git tag -l --points-at HEAD".runCommand()
val gitCommitId = "git rev-parse --short=8 HEAD".runCommand()

Here’s what it might look like in groovy

def runCommand = { Project project, String command ->
   ByteArrayOutputStream byteOut = new 
   ByteArrayOutputStream() 
   project.exec {
      commandLine = command.split(" ")
      standardOutput = byteOut
   } 
   return new String(byteOut.toByteArray()).trim()
}
def gitBranch = runCommand(project, "git rev-parse --abbrev-ref HEAD") 
def gitTag = runCommand(project, "git tag -l --points-at HEAD") 
def gitCommitId = runCommand(project, "git rev-parse --short=8 HEAD") 
1 Like

ok, for Kotlin DSL it looks like this:

fun String.runCommand(currentWorkingDir: File = file("./")): String {
    val byteOut = ByteArrayOutputStream()
    project.exec {
        workingDir = currentWorkingDir
        commandLine = this@runCommand.split("\\s".toRegex())
        standardOutput = byteOut
    }
    return String(byteOut.toByteArray()).trim()
}

val gitBranch = "git branch --show-current".runCommand()
val gitTag = "git tag -l --points-at HEAD".runCommand()
val gitCommitId = "git rev-parse HEAD".runCommand()
1 Like