Slackbot
11/18/2022, 11:43 AMMartin
11/18/2022, 11:46 AMfun RepositoryHandler.addRepos() {
mavenCentral()
google()
// more
}
pluginManagement {
repositories {
// Unresolved reference: addRepos
addRepos()
}
}
dependencyResolutionManagement {
repositories {
addRepos()
}
}
ephemient
11/18/2022, 11:55 AMVampire
11/18/2022, 11:56 AMpluginManagement
block is extracted and evaluated separately before the settings script itself is compiled, otherwise its content could not influence the plugins that you can apply to the settings script itself. Due to that you of course cannot reference anything outside that block. Same for plugins
blocks or buildscript
blocks.
But you can on the other hand inside the pluginManagement
block configure other objects. So what I sometimes did is:
// the plugin management block is evaluated first separately, do not change this to
// listOf(pluginManagement.repositories, dependencyResolutionManagement.repositories)
// instead that would change the semantics
pluginManagement {
listOf(repositories, dependencyResolutionManagement.repositories).forEach { repositories ->
repositories.apply {
mavenCentral()
google()
}
}
}
dependencyResolutionManagement {
repositoriesMode.set(FAIL_ON_PROJECT_REPOS)
}
Martin
11/18/2022, 11:58 AMpluginManagement{}
was the same as buildscript{}
but it makes a lot of sense 👍Vampire
11/18/2022, 11:59 AMMartin
11/18/2022, 11:59 AMMartin
11/18/2022, 12:01 PMapply(from = "other.gradle.kts")
in settings.gradle.kts
? Is Gradle smart enough to know that the script is applied in the context of settings and "extract" the pluginManagement
block?grossws
11/18/2022, 12:02 PMMartin
11/18/2022, 12:02 PMMartin
11/18/2022, 12:03 PMMartin
11/18/2022, 12:04 PM//other.gradle.kts
pluginManagement {
repositories {
mavenCentral()
}
}
//settings.gradle.kts
apply(from = "other.gradle.kts")
ephemient
11/18/2022, 12:04 PMMartin
11/18/2022, 12:05 PMVampire
11/18/2022, 12:06 PMgrossws
11/18/2022, 12:06 PMVampire
11/18/2022, 12:06 PMpluginManagement.repositories { ... }
Vampire
11/18/2022, 12:06 PMephemient
11/18/2022, 12:07 PMephemient
11/18/2022, 12:08 PMMartin
11/18/2022, 12:08 PMI'd guess it would not be extracted but just executed like if you doThe "// Unresolved reference: addRepos" above seems to indicate it's still evaluated separatelypluginManagement.repositories { ... }
I'd anyway recommend not to use "regular" script plugins ever. They usually just produce strange things and have issues like classpath nonsensen and so on.Yea, it's just convenient. I've tried to "extract" that logic to an included build but it's just included builds all the way down from there 😅 . There's some kind of "bootstrapping" needed. Including a script makes it easy to factor some logic/definitions once, in a sense, similar to version catalogs for versions
ephemient
11/18/2022, 12:09 PMephemient
11/18/2022, 12:10 PMephemient
11/18/2022, 12:10 PMVampire
11/18/2022, 12:10 PMThe "// Unresolved reference: addRepos" above seems to indicate it's still evaluated separately.No, if you would do
pluginManagement.repositories { ... }
it would not be extracted but then would also have the implicit gradlePluginPortal()
(except they fixed that in the meantime) just like if you onyl define the plugin repositories in a settings script.
With that syntax it is just executed in the normal settings script execution, hence the big header-comment in my hack-aroundMartin
11/18/2022, 12:17 PM// other.gradle.kts
fun addRepos() {
// do stufff, add repos
}
pluginManagement {
repositories {
// undefined reference
// addRepos()
println("this code is executed")
}
}
pluginManagement.repositories {
// compiles
addRepos()
println("this code is also executed")
}
Martin
11/18/2022, 12:18 PMpluginManagement{}
is evaluated separately, right? Even if it's in a separate other.gradle.kts
block. It's still executed like pluginManagement.repositories {}
but somehow compiled separatelyVampire
11/18/2022, 12:46 PMpluginManagement.repositories
.
So if you do pluginManagement { ... }
in a script plugin that you then apply in the settings script, it is still only executed when the script plugin is applied and thus has no effect on plugin resolution within the settings script.Vampire
11/18/2022, 1:08 PMpluginManagement
block directly within the settings script is evaluated.
Then the plugins
block direclty within the settings script is evaluated.
Only then the remaining settings script is evaluated which includes application of regular script plugins.
So to also affect the plugin resolution within the settings script, you have afaik no alternative to using the pluginManagement
block directly in the settings script.
Except if you would use an init script for example from a custom Gradle distribution. In that you could afair use beforeSettings
to have the same effect.ephemient
11/18/2022, 1:10 PMMartin
11/18/2022, 1:40 PMMartin
11/18/2022, 2:26 PMVampire
11/18/2022, 2:30 PMMartin
11/18/2022, 2:31 PMephemient
11/18/2022, 2:32 PMinitscript
is a special block in *.init.gradle.kts
, etc. basically there's some logic in that file I linked previouslyMartin
11/18/2022, 2:32 PMMartin
11/18/2022, 3:20 PMephemient
11/18/2022, 3:24 PMproperties[...]
IMO,
pluginManagement {
val kotlinVersion: String by settings
plugins {
resolutionStrategy {
eachPlugin {
if (requested.id.id.startsWith("org.jetbrains.kotlin.")) useVersion(kotlinVersion)
}
}
}
}
ephemient
11/18/2022, 3:25 PMby project
in a build script of course)Martin
11/18/2022, 3:26 PMMartin
11/18/2022, 3:26 PMMartin
11/18/2022, 3:31 PMephemient
11/18/2022, 4:04 PMpluginManagement {
val parseToml = DefaultTask::class.java.classLoader.loadClass("org.tomlj.Toml")
.getMethod("parse", java.io.InputStream::class.java)
val toml = file("gradle/libs.versions.toml").inputStream().use { parseToml.invoke(null, it) }
val versions = toml.withGroovyBuilder {
"getTable"("versions")?.withGroovyBuilder {
("keySet"() as Set<*>).associateWith { "get"(listOf(it)) as? String }
}
}.orEmpty()
val kotlinVersion = versions["kotlin"]
}