David Herman
01/09/2025, 7:40 PMDavid Herman
01/09/2025, 7:42 PMsettings.gradle.kts
is this declaration for my artifact snapshots:
fun RepositoryHandler.exampleSnapshots() {
maven("<https://s01.oss.sonatype.org/content/repositories/snapshots/>") {
content {
includeGroupByRegex("com\\.example\\.stuff.*")
}
}
}
And important: I have snapshots both for some Gradle plugins AND normal library artifacts related to my project, so I'd want to reference this from both the pluginManagement
and dependencyResolutionManagement
blocks.David Herman
01/09/2025, 7:43 PMpluginManagement {
repositories {
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositories {
mavenCentral()
google()
}
}
gradle.settingsEvaluated {
fun RepositoryHandler.exampleSnapshots() { /* ... */ }
pluginManagement.repositories { exampleSnapshots() }
dependencyResolutionManagement.repositories { exampleSnapshots() }
}
David Herman
01/09/2025, 7:48 PMsettings.gradle.kts
file, well, that would be it. I'd be done! But I understand that the pluginManagement
block is magical.
Outside of that, I suspect that the Gradle idiomatic approach would be to create a Settings plugin, but looking into that, it looks a lot messier than I'd like.
And here's a final wrinkle: I'm not actually writing code in my own project. I'm writing a README for my users, and I'm trying to suggest to them what code they can add to their project enable snapshots. I'm also providing some templates that users can build their projects on top of, and I'd like to have this code in there already, so that users could easily help us test snapshot versions if we ask them to.David Herman
01/09/2025, 7:49 PMPhilip W
01/09/2025, 7:52 PMDavid Herman
01/09/2025, 7:52 PMPhilip W
01/09/2025, 7:57 PMDavid Herman
01/09/2025, 7:57 PMDavid Herman
01/09/2025, 7:58 PMPhilip W
01/09/2025, 7:58 PMPhilip W
01/09/2025, 7:59 PMDavid Herman
01/09/2025, 8:00 PMDavid Herman
01/09/2025, 8:00 PMDavid Herman
01/09/2025, 8:02 PMpluginManagement {
repositories {
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositories {
mavenCentral()
google()
}
}
// Snapshots added this way to share code across pluginManagement and dependencyResolutionManagement blocks.
// You cannot simply declare a top level function and call them from both places due to Gradle limitations.
gradle.settingsEvaluated {
fun RepositoryHandler.kobwebSnapshots() {
maven("<https://s01.oss.sonatype.org/content/repositories/snapshots/>") {
content {
includeGroupByRegex("com\\.varabyte\\.kobweb.*")
}
}
}
pluginManagement.repositories { kobwebSnapshots() }
dependencyResolutionManagement.repositories { kobwebSnapshots() }
}
^ There's the final version of the proposed code.David Herman
01/09/2025, 8:02 PMDavid Herman
01/09/2025, 8:04 PMpluginManagement {
repositories {
gradlePluginPortal()
maven("<https://s01.oss.sonatype.org/content/repositories/snapshots/>")
}
}
dependencyResolutionManagement {
repositories {
mavenCentral()
google()
maven("<https://s01.oss.sonatype.org/content/repositories/snapshots/>")
}
}
Philip W
01/09/2025, 8:08 PMPhilip W
01/09/2025, 8:10 PMDavid Herman
01/09/2025, 8:15 PMsnapshotOnly
, and initial Google searches are failing me. Am I missing something obvious?David Herman
01/09/2025, 8:17 PMmavenContent
David Herman
01/09/2025, 8:18 PMmaven("<https://s01.oss.sonatype.org/content/repositories/snapshots/>") {
content {
includeGroupByRegex("com\\.varabyte\\.kobweb.*")
}
mavenContent {
snapshotsOnly()
}
}
Vampire
01/10/2025, 12:27 AMmavenContent
is a specialization of content
so just put both lines in mavenContent
and ditch content
. mavenContent
can just do more than content
(namely configuring "snapshots only" and "releases only")
• The problem with the settingsEvaluated
construct is, it is ugly
• The next problem with the settingsEvaluated
construct is, it is confusing to the non-expert
• Yet another problem with the settingsEvaluated
construct is, that it does not work if you need to resolve a settings plugin from that repository as this is executed after the settings plugins are resolved and so would only work for project plugins, but that might be ok for your use-case of course
Here a likewise ugly alternative that behaves better, as it also works for settings plugins and has less repetition:
// 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 {
maven("<https://s01.oss.sonatype.org/content/repositories/snapshots/>") {
mavenContent {
includeGroupByRegex("com\\.varabyte\\.kobweb.*")
snapshotsOnly()
}
}
}
}
}
Vampire
01/10/2025, 12:28 AMpluginManagement
block inside (just like plugins
block or buildscript
block or initscript
block) but you can do configuration you would do outside of it inside.David Herman
01/10/2025, 12:50 AMDavid Herman
01/10/2025, 5:09 PMsettingsEvaluated
approach (although don't get me wrong, I do agree with all your points about why settingsEvaluated
can be problematic)
1. (Minor) I had to jam the logic into the middle of the existing pluginManagement
block (Gradle complains if you declare more than one). Before, having a totally separated code block meant I could tell users to just paste some code blindly in their settings file and it would just work, and if they wanted to comment out / delete it later, it would be pretty easy for them to do so.
2. (Minor) The comment you left about repositories
vs pluginManagement.repositories
feels itself nuanced in a confusing way.
3. (Major?) Your code declares the snapshot repository BEFORE the dependencyResolutionManagement
block gets a chance to run, which would give the snapshot repository precedence over the mavenCentral
and google
ones. Here, this is technically unlikely to actually cause problems (because my snapshot artifacts will never be in maven central or google locations), but my intention is definitely to treat the snapshot URL as a final fallback, not be first in the list.
I think in general I have a better understanding now of why I should avoid settingsEvaluated
but for this specific use-case (about declaring a snapshot repository just for local development purposes), I'm thinking I may just leave the suggestion as is.Vampire
01/10/2025, 5:44 PMDavid Herman
01/10/2025, 5:44 PMVampire
01/10/2025, 5:44 PMDavid Herman
01/10/2025, 5:45 PMVampire
01/10/2025, 5:46 PMVampire
01/10/2025, 5:46 PMDavid Herman
01/10/2025, 5:47 PMVampire
01/10/2025, 5:50 PMVampire
01/10/2025, 5:52 PM