How to run a command line command with Kotlin DSL in Gradle 6.1.1?
Asked Answered
Q

5

19

I am trying to run the code block below, after reading multiple posts on the topic and the Gradle manual. I run the below and get the following error: execCommand == null!

Any ideas on what I am doing wrong with the below code block?

open class BuildDataClassFromAvro : org.gradle.api.tasks.Exec() {

    @TaskAction
    fun build() {
        println("Building data classes.....")
        commandLine("date")
    }
}

tasks.register<BuildDataClassFromAvro>("buildFromAvro") {
    description = "Do stuff"
}
Quarrelsome answered 4/2, 2020 at 15:57 Comment(2)
What is it you're trying to get the task to do? An Exec task is for running a cmd-line process, so you don't need to actually create a Kotlin class that subclasses it: instead you create a Gradle task of type Exec and define the commandLine in there (see docs.gradle.org/current/dsl/org.gradle.api.tasks.Exec.html). Are you trying to run a cmd-line process? Or are you trying to write a task that will run some custom Kotlin code?Pedaiah
I am trying to run a command line process as part of the build process.Quarrelsome
P
35

To define a Gradle task that runs a command-line using the Gradle Kotlin DSL do something like this in your build file:

task<Exec>("buildFromAvro") {
    commandLine("echo", "test")
}

In the example above the commandLine will simply run echo, outputting the value test. So replace that with whatever you want to actually do.

You can then run that with gradle buildFromAvro

More info here: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Exec.html

Pedaiah answered 4/2, 2020 at 17:42 Comment(4)
I keep getting too many characters in a character literal 'echo'Afroasiatic
@Afroasiatic If you're getting that error, you're probably using ' instead of " - single quotes instead of double. They have different meanings.Surprise
This command doesn't do anything in 2023 :(Arenaceous
@Arenaceous If you are running as part of the Android Studio build process it is not working, but it is when run from the terminal with gradlew buildFromAvro, reasons unknownMeniscus
S
2

If adding to an existing task:

exec {
    commandLine("echo", "hi")
}

Superhuman answered 25/10, 2022 at 20:28 Comment(0)
I
0

Another approach is to use the Java ProcessBuilder API:

tasks.create("MyTask") {
    val command = "echo Hello"
    doLast {
        val process = ProcessBuilder()
            .command(command.split(" "))
            .directory(rootProject.projectDir)
            .redirectOutput(Redirect.INHERIT)
            .redirectError(Redirect.INHERIT)
            .start()
            .waitFor(60, TimeUnit.SECONDS)
        val result = process.inputStream.bufferedReader().readText()
        println(result) // Prints Hello
    }
}
Inosculate answered 4/5, 2022 at 7:26 Comment(0)
A
0

I hope didactique code to execute the ls command against workingDir.

    @Throws(RuntimeException::class)
    fun Project.lsWorkingDir() = ByteArrayOutputStream().use { outputStream ->
        exec {
            standardOutput = outputStream
            workingDir = projectDir
            when {
                "os.name"
                    .run(System::getProperty)
                    .lowercase()
                    .contains("windows") -> commandLine("cmd.exe", "/c", "dir", workingDir, "/b")

                else -> commandLine("ls", workingDir)
            }
        }.let { result ->
            when {
                result.exitValue != 0 -> throw RuntimeException("Command ls failed.")
                else -> outputStream.toString()
                    .trim()
                    .let { "Command ls output:\n$it" }
                    .let(::println)
            }
        }
    }



tasks.register("lsWorkingDir") {
    group = "playground"
    description = "Run ls command against workingDir."
    doFirst { lsWorkingDir() }
}

Apart answered 7/2 at 4:25 Comment(0)
B
0

I was working something similar to this where I face the same issue

I was trying to do multiple tasks inside Exec type. For me all commands of this task was working but build was failing with Exec Command == null!

i.e

tasks.regsiter<Exec>("taskname"){
  exec{}
  copy{}
  delete{}
}

I just removed <Exec> and started building.

tasks.regsiter("taskname"){
  exec{}
  copy{}
  delete{}
}
Bourgeon answered 10/6 at 10:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.