Is there a way to define property to be used in both settings.gradle.kts and projects/subprojects build.gradle.kts with gradle 6.0?
See ticket #11090 "Definitions from buildSrc/ not found in settings.gradle.kts using gradle 6.0-rc-1".
As you already noticed this changed recently:
This has changed in 6.0, and was deprecated in 5.6. Please see: https://docs.gradle.org/current/userguide/upgrading_version_5.html#buildsrc_usage_in_gradle_settings
-- https://github.com/gradle/gradle/issues/11090#issuecomment-544473179
One of the maintainers describes the reasons behind the decision:
Unfortunately, there are pros and cons to both arrangements (
settings-then-buildSrc
andbuildSrc-then-settings
), and we opted for the former after considering.(...)
The pros that compelled us to make the change:
- Settings plugins can influence buildSrc and main build (i.e. apply a build plugin to both)
- Build cache configuration is applied to buildSrc
- buildSrc behaves more like a regular included build
-- https://github.com/gradle/gradle/issues/11090#issuecomment-545697268
And finally some bad news:
We won't be changing the behaviour back to the pre Gradle 6 arrangement. Please let us know if you would like more detail on how to use one of the alternative mechanisms for using complex logic in a settings script.
-- https://github.com/gradle/gradle/issues/11090#issuecomment-545697268
Workarounds
In the aforementioned post the author proposes some workarounds:
The con of this is exactly what you have hit. It's now less convenient to use complex logic in your settings script. Now, you have to either:
- Inline the logic into the settings file
- Move the logic to a shared script that can be used where it needs to
- Move the logic to a pre-built binary that you load in the settings file (i.e. a settings plugin)
-- https://github.com/gradle/gradle/issues/11090#issuecomment-545697268
#1 is pretty straightforward, but I can only assume what #2 and #3 mean. I come from the Groovy world and only recently started making friends with Kotlin DSL. Having said that let's give it a try.
In #3 the author might be talking about developing an external plugin and applying it in both scripts. I'm not really sure if this is something that would make sense to implement (it gives you strong typing though).
"#2 Move the logic to a shared script that can be used where it needs to"
I think it's about having a common script plugin and including it in both settings.gradle
and build.gradle
files. The plugin would put the static information in the ExtraPropertiesExtension
of the ExtensionAware
in scope (Settings
in case of a settings.gradle
script plugin and Project
in case of build.gradle
). This is described in this answer to "Include scripts with Gradle Kotlin DSL":
How can I put all common constants (such as dependency versions) to the separate file to include them just by using something like springBootVersion or Constants.springBootVersion with compile-time checks?
There is no good way to do it currently. You can use extra properties, but it won't guarantee compile time checks. Something like that:
// $rootDir/dependencies.gradle.kts // this will try to take configuration from existing ones val compile by configurations val api by configurations dependencies { compile("commons-io:commons-io:1.2.3") api("some.dep") } // This will put your version into extra extension extra["springBootVersion"] = "1.2.3"
And you can use it like this:
// $rootDir/build.gradle.kts subprojects { apply { plugin<JavaLibraryPlugin>() from("$rootDir/dependencies.gradle.kts") }
And in your module:
// $rootDir/module/build.gradle.kts // This will take existing dependency from extra val springBootVersion: String by extra dependencies { compile("org.spring:boot:$springBootVersion") }
-- Include scripts with Gradle Kotlin DSL