https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
k

Kwabena Berko

08/23/2022, 5:09 PM
Hi folks, How do I run a custom gradle task that only runs after the build tasks completes in a KMM project?
Copy code
tasks.register("copySomething", Copy::class) {
   println("How Do I Run This Task After Build Completes?")
}
j

Jeff Lockhart

08/23/2022, 5:21 PM
You can configure code to run after the task, but not register a task to always run after:
Copy code
tasks.named("otherTask") {
    doLast {
        // code to run after
    }
}
Or you could register the task and have it depend on the other task:
Copy code
tasks.register<Copy>("copyTask") {
    dependsOn(tasks.named("otherTask"))
    // configure task
}
Then instead of running the other task, just run the new task, which will run the other task first.
k

Kwabena Berko

08/23/2022, 5:25 PM
In this particular case, I want to run the
copyTask
after the project
build
completes. So I need to hook or depend on the
build
task. How do I do that?
j

Jeff Lockhart

08/23/2022, 5:27 PM
Are you able to do the copy task before the build? What is it you are copying?
k

Kwabena Berko

08/23/2022, 5:29 PM
No, im not able to do that as Im not sure how to depend on the
build
task. I have a task:
Copy code
tasks.named("build"){
   finalizedBy("copyTask")
}
But the
build
task does not exist. I want to find out how to hook onto the
build
task.
j

Jeff Lockhart

08/23/2022, 5:36 PM
When a task completes in gradle, its work is considered done. If you want to do another task's work, you'd need to run that other task (the copy task), which can depend on the build task running first. If you want the copy to be part of the build task, instead of making it a separate task, just run the code in a
doLast { // copy code }
block on the build task, like my first example above.
k

Kwabena Berko

08/23/2022, 5:39 PM
Yeah. How do I hook onto the build task. What does it look like? I mean the gradle build task
j

Jeff Lockhart

08/23/2022, 5:49 PM
It depends on the target and what part of the build pipeline, what the task is called. Is this after compilation (compile<Target>)? Or after bundling a .jar (<target>Jar)? Or linking a native binary (link<Target>)? If it's a specific build task:
Copy code
tasks.named("buildTaskName") {
    doLast {
        // code to run after
    }
}
Or if you want to do something after all tasks of a particular type (e.g. KotlinNativeLink or FatFrameworkTask):
Copy code
tasks.withType<TaskType> {
    doLast {
        // code to run after all TaskType tasks
    }
}
m

mkrussel

08/23/2022, 5:51 PM
I’m guessing your copy task depends on the output from another task(s) from build. If so you should make your task depend on those tasks, and then make build depend on your copy task. Then every time you run the build task, your copy task will run if the inputs it needs have been changed by those tasks running.
k

Kwabena Berko

08/24/2022, 7:50 PM
@Jeff Lockhart @mkrussel Thanks. These are all great answers but does not entirely the initial question. Let me elaborate a bit more I currently have the below gradle task for installing git hooks for contributors of a project:
Copy code
tasks.register<Copy>("installGitHooks") {
    val fromDir = "${rootProject.rootDir}/.githooks"
    val toDir = "${rootProject.rootDir}/.git/hooks"
    val os = OperatingSystem.current()
    val isMacOrLinux = os.isMacOsX || os.isLinux

    from(fromDir)
    into(toDir)

    if (isMacOrLinux){
        Runtime.getRuntime().exec("chmod a+x $toDir")
    }
}
How do I run this automatically when the project builds?
m

mkrussel

08/24/2022, 8:11 PM
Why do you want to install git hooks on every build? And the
chmod
should probably be in a doFirst or doLast block not in the configuration block. But the answer depends on what you mean by building. If you mean running the
build
task then you would do.
tasks.findByName("build")?.dependsOn("installGitHooks")
That will then run the task anytime you do
gradle build
k

Kwabena Berko

08/24/2022, 8:15 PM
Yeah, I actually dont want to call that task multiple times. I wasnt sure which task to use so I went with the
build
task. What task do you suggest?
m

mkrussel

08/24/2022, 8:38 PM
I would go with nothing. Just make it a task that people run when they first clone the repo and anytime the scripts are updated. If you are trying to make sure that people don’t forget, then you probably need to do go with some assemble task that is required to run the app. When running from the IDE they won’t be using the
build
task or the high level
assemble
task.
k

Kwabena Berko

08/24/2022, 9:13 PM
Thanks for the suggestions @mkrussel! Really appreciate
Was finally able to do this in the
afterEvaluate
block:
Copy code
afterEvaluate {
    tasks["clean"].dependsOn("installGitHooks")
}
Now, when ever the project is cleaned, the installGitHooks tasks is run
270 Views