I have a plugin that installs a 'toolchain' (a kot...
# community-support
a
I have a plugin that installs a 'toolchain' (a kotlin-native-prebuilt distribution) in the user's home dir. I've created a task for running installation verification (e.g. verifying checksums, running
clang --version
to make sure it's executable), which the base
check
task depends on. However, if my plugin is installed in multiple subprojects, then the verification tasks in each subprojects could effectively perform the same check, which is redundant and slower. Each subproject could have a different kotlin-native-prebuilt distribution (e.g. one that's for macOS and another for Linux). What are some good ways of 'deduplicating' these check tasks?
c
Perhaps a build service that caches the result based on the platform requirements?
a
hmmm yes, I think a BuildService for sharing inter-project state is necessary. I was hoping to avoid one because of https://github.com/gradle/gradle/issues/17559, and because I'd have to do a refactor...
c
yea, that’s a nasty one. The workaround of
Provider<Object>
seems solid.
y
When you say you "have a plugin" do you mean that you own the source of the plugin OR that you have a 3rdParty plugin in your build. Because if it is the first, then there are better ways of managing the toolchain installation.
a
it's the first
y
Why don't you put the necessary checks in the plugin that installs the toolchain. Then you just work on the principle in other projects that the installation is good? You can use an exclusive file access lock to ensure that only one project actually does the installation and check. This is effectively what Gradle does under the hood when installing a new Gradle distribution. The same is the case for a number of plugins that install toolchains like terraform, node etc.
p
Do you download the toolchain (I guess so)? I wonder if you can use a transformer action instead, it is scoped to the build and is cacheable across builds.
a
Why don't you put the necessary checks in the plugin that installs the toolchain. Then you just work on the principle in other projects that the installation is good?
I want a way to manually run the checks (like verifying the file checksums, or checking if
clang --version
returns the expected result). Running such checks automatically (e.g. on every build) is far too slow, and isn't necessary in almost all cases.
Do you download the toolchain (I guess so)? I wonder if you can use a transformer action instead, it is scoped to the build and is cacheable across builds.
The source archives are downloaded via Gradle (using a custom Ivy repo). I really really really want to avoid using transformers because they're overly sensitive to buildscript classpath changes. Any change would re-trigger the transform, which is slow and uses a lot of disk space. https://github.com/gradle/gradle/issues/30968
y
I want a way to manually run the checks (like verifying the file checksums, or checking if
clang --version
returns the expected result). Running such checks automatically (e.g. on every build) is far too slow, and isn't necessary in almost all cases.
This implies that you should not hook verification into the lifecycle
check
which is something that is meant to be run as part of automation. If you only want to verify this on the odd moment, then have a standalone (sanity check) task that can be run on-demand. You are still better off doing the initial checks in the toolchain plugin.
a
yeah, exactly, a standalone 'verify toolchains' task is what I want (whether it should automatically run as part
check
is up for debate). The question is how to prevent different subprojects re-running the same check. So let's say I have 3 subprojects: • foo-linux-lib (uses the linux toolchain) • bar-linux-lib (again, uses the linux toolchain) • bar-macos-lib (uses the macos toolchain) If my toolchain plugin registers a 'verify toolchain' task in each project, then the tasks in foo-linux-lib and bar-linux-lib tasks are going to be duplicated. Even if the actual validation computation was de-duplicated (e.g. the validation was done once in a shared BuildService), the result is either going to be reported multiple times (which is weird imo), or one of the subproject tasks will have to skip (again, weird imo). What I'm gravitating towards a toolchains settings plugin that registers a 'verify all toolchains' task in the root project. The setting plugin registers a BuildService that collects all requested toolchains (using
gradle.afterProject {}
), and the check task verifies all distinct toolchains.
y
What I'm gravitating towards a toolchains settings plugin that registers a 'verify all toolchains' task in the root project.
That is a better solution.