This message was deleted.
# community-support
s
This message was deleted.
v
Besides that
allprojects { ... }
is evil, there is no order guarantee in what you configured. That you include one project later than another does not impose any ordering constraints or guarantees. If your backend depends on artifacts from the frontend, you will have a dependency declared and that will then care about building in the correct order.
👍 1
m
The issue is that when I tried to configure the backend processResources task with
from(project(":wiki-frontend-public").tasks.named("bundle"))
, it gave an error, as the task had not yet been created.
And the only documentation I could find for this issue was that include() was specifying the order for subprojects, which many websites seemed to confirm.
v
Well, it doesn't matter actually, because what you do is unsafe and very bad anyway. You must not reach into other projects like that. Even if the configuration would work, it is highly fragile and might break anytime in obvious or not so obvious ways. See here for ways to do it properly: https://docs.gradle.org/current/userguide/cross_project_publications.html
m
That page seems to cover using other projects in dependencies, but I don't see how it would help me in using task outputs from a different project as input for a separate task.
v
Exactly like that. And then you can use the configuration on the consumer side as input to the task.
from(theConfigurationOnTheConsumerSide)
m
Copy code
// backend build.gradle.kts
val bundleArtifact by configurations.creating

dependencies {
    implementation(project(":wiki-common"))

    bundleArtifact(project(":wiki-frontend-admin", "bundles"))
    bundleArtifact(project(":wiki-frontend-public", "bundles"))
}

tasks {
    val processResources by getting(Copy::class) {
        from(bundleArtifact)
    }
}

// frontend-* build.gradle.kts
val bundles by configurations.creating

tasks {
    val bundleResources by creating(Copy::class) {
        destinationDir = buildDir.resolve("bundle")

        // ...

        artifacts {
            add(bundles.name, destinationDir)
        }
    }
}
But it seems backend:processResources doesn't move any of the resources this way.
v
Besides that you disturb task-configuration avoidance by using
getting
and
creating
instead of
existing
and
registering
, the
artifacts
is misplaced within the
tasks
closure. And besides that, you use a plain
File
as artifact, that cannot bear any task dependency. Use the task itself as artifact or at least configure the
builtBy
as shown in the documentation, but the former is preferable.
m
I tried using the task as artifact but that gave an error saying it couldn't be converted to the required type, but I'll try builtBy. What's the purpose of existing and registering? Previously when asking for support I was told to always just use getting and creating.
v
Well, never ask that person again, that recommendation is total bullshit and the opposite of what is recommended. You can read about task-configuration avoidance at https://docs.gradle.org/current/userguide/task_configuration_avoidance.html And if you break it, nothing really bad happens, but you wast the time of anyone executing the build that would not need the tasks you broke the avoidance for.
Never use
getting
and
creating
unless you have a really good reason or are on a really ancient version of Gradle. Otherwise always use
existing
and
registering
unless you have a really good reason not to.
At least on task containers. For all other containers it doesn't really matter as they are not used in a lazy manner.
Also, usually you do not want a
Copy
task, but a
Sync
task, as that also wipes away stale files.
Copy
is mainly for special cases where you copy into a directory where existing files should be preserved.
Ah, ok, you can only use archive tasks as artifacts directly, yeah, then use
builtBy
Hm, interestingly, with a
TaskProvider<Copy>
it works, so if you would use
registering
instead of
creating
it works.
This feels strange and is probably a bug on either side though
Ah, it also supports a provider of a task that has exactly one output file, which is the case for the
Copy
or
Sync
task, as the one output file is the directory into which the files are copied, that's why it works with the
TaskProvider
you get from
registering
I reported the inconsistencies as https://github.com/gradle/gradle/issues/25569
m
Additionally, it seems artifacts don't properly propagate needed updates:
Copy code
> Task :wiki-frontend-public:bundleResources
> Task :wiki-backend:processResources UP-TO-DATE  // This depends on the bundleResources artifact, and should NOT be marked up-to-date!
v
Then you most probably did something wrong 🙂
m
I simply changed everything to use existing/registering and moved
Copy code
artifacts {
        add(bundles.name, bundleResources)  // now using the TaskProvider<Sync>
    }
outside of the task configuration
v
Well, if it doesn't work, something still is not right, as it should and does. You could knit an MCVE that shows your current try.