so looking at the docs, stackoverflow and the gene...
# community-support
b
so looking at the docs, stackoverflow and the general APIs, I'm struggling to figure out what the correct way is to: 1. execute a task after another task (e.g. execute copyJson before jsProcessResources) 2. run a validateJsonSchema task during check My general understanding so far: 1. Looking at the APIs, there does not seem to be a mustRunBefore API, so I need to get the existing task and define it like this?
Copy code
tasks {
    getByName("jsProcessResources") {
        mustRunAfter("copyJson")
    }
}
2. Not sure what the appropriate API is to just execute it during the check phase? So far I've got:
Copy code
tasks {
    getByName("check") {
        finalizedBy("validateJsonSchema")
    }
}
but it looks like finalizedBy is more like a finally block in a try catch and executed regardless of previous failures
1
v
execute a task after another task
The "correct" way is to not need that. The "even more correct" way is to not even think about it. 🙂 You should always wire task outputs to task inputs and by that get necessary task dependencies and ordering automatically. Whenever you need to do a manual
dependsOn
where the left-hand side is not a lifecycle task, you most probably do something wrong (even if Gradle hinted you at it) and in the majority of cases also if you use an ordering constraint like
mustRunAfter
.
e.g. execute copyJson before jsProcessResources
You first say run one task after the other, then your example says the opposite. This is an important distinction which might influence an answer. Besides the fact, that you probably need to elaborate on the use-case, as your question strongly sounds like an XY-problem. So from where does
copyJson
copy what to where, and why does it need to be run before
jsProcessResources
? If the answer for example is, that the
copyJson
copies something into
src/js/resources
which
jsProcessResources
then copies, then the answer indeed is that you shouldn't. For example any other task needing resources will still miss the task dependency and might or might not get the copied json depending on whether the copy task run first or not. And sometimes Gradle 7 will also recognize that and warn or Gradle 8 fail. Not fully sure about KMP, but usually you do something like
sourceSets { main { resources { srcDir(copyJson) } } }
with
copyJson
having some dedicated output directory in
layout.buildDirectory
. Then any task needing resources also gets those resources and automatically has a dependency on the "code generation" task.
run a validateJsonSchema task during check
Here an explicit
dependsOn
indeed is the right choice.
check
is a lifecycle task, so if you want that task to run when someone invokes
check
, just add a direct task dependency using
dependsOn
.
Looking at the APIs, there does not seem to be a mustRunBefore API
Well, it's called
dependsOn
and you should not use it as written above 🙂
So far I've got:
You can do it like that, it's just semantically non-sense.
finalizedBy
means "run this task always after that task, even if that task failed during execution.
check
does never fail as it is a lifecycle task unless someone evilly added actions directly to it, so it will never fail to execute. If you want that the task is executed after all tasks that
check
depends upon, then this construct could help, but usually you just want a
dependsOn
as written above.
b
If the answer for example is, that the
copyJson
copies something into
src/js/resources
which
jsProcessResources
then copies,
that's exactly the use case: I'm concatenating a json file from another folder and want that to appear in the build directory
thank you
v
Btw. it is too early for my brain. If you really would want to only define order in case both tasks are executed,
mustRunAfter
is indeed the way to go. But as you already said that's the use-case, you probably got exactly that message I meant from Gradle like "task uses outputs of that other task without dependency" and there the suggested actions are imho non-sense and only duct-tape instead of a proper solution. 🙂
b
srcDir(copyJson) I suppose isn't valid Kotlin, can't find the equivalent
I think I've figured it out
Copy code
sourceSets {
        val commonMain by getting {
            resources.srcDir(tasks.named { it == "combineJsonFiles"})
            dependencies {
                implementation(libs.kotlinx.serialization.core)
                implementation(libs.kotlinx.serialization.json)
                implementation(libs.kotlinx.datetime)
                implementation(libs.kotlinx.coroutines)
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(libs.kotlin.test)
            }
        }
    }
setting resources.srcDir does not seem to override resolving existing resources in commonMain which is what I would have expected, so it seems to be exactly what I need
v
srcDir(copyJson) I suppose isn't valid Kotlin, can't find the equivalent
if
copyJson
is a variable holding the
Task
or
TaskProvider
it is. Be careful with
named
as I just explained on the Kotlin Slack to someone with your first name, so probably you? 🙂
setting resources.srcDir does not seem to override resolving existing resources in commonMain
Correct,
srcDir
adds additional source dirs.
setSrcDirs
would override preexisting source dirs.
❤️ 1
b
yes, that was me, already changed it 🙂
👌 1