Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide support for gradle style version catalogs #4483

Open
3 tasks
DamianReeves opened this issue Feb 5, 2025 · 5 comments
Open
3 tasks

Provide support for gradle style version catalogs #4483

DamianReeves opened this issue Feb 5, 2025 · 5 comments

Comments

@DamianReeves
Copy link

In gradle, users are able to manage versions using version catalogs.

In the typical scenario, a user defines their version catalog as a TOML file under the gradle folder in their project.

The TOML file follows the following format:

[versions]
androidx-activityCompose = "1.9.2"
androidx-ui-tooling = "1.7.0"
androidx-lifecycle = "2.8.4"
coroutines = "1.8.1"
kamel = "0.9.5"
koin = "3.5.6"
ktor = "2.3.12"
voyager = "1.0.0"

[libraries]
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "androidx-ui-tooling" }
androidx-lifecycle-runtime-compose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
kamel = { module = "media.kamel:kamel-image", version.ref = "kamel" }
kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "coroutines" }
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
voyager-koin = { module = "cafe.adriel.voyager:voyager-koin", version.ref = "voyager" }
voyager-navigator = { module = "cafe.adriel.voyager:voyager-navigator", version.ref = "voyager" }

Here is a simpler example showing all sections:

[versions]
common = "1.4"

[libraries]
my-lib = "com.mycompany:mylib:1.4"
my-lib-no-version.module = "com.mycompany:mylib"
my-other-lib = { module = "com.mycompany:other", version = "1.4" }
my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" }
mylib-full-format = { group = "com.mycompany", name = "alternate", version = { require = "1.4" } }

[bundles]
mylib = ["my-lib", "my-other-lib", "my-other-lib2"]

[plugins]
short-notation = "some.plugin.id:1.4"
long-notation = { id = "some.plugin.id", version = "1.4" }
reference-notation = { id = "some.plugin.id", version.ref = "common" }

Typesafe Access

What is a convenient outcome of this, is that gradle generates type safe accessors for the libraries, so the ktor-client-core lib above could be referenced like:

def ivyDeps = super.ivyDeps() + Agg(libs.ktor.client.cor)

Or perhaps adding a full bundle with:

def ivyDeps = super.ivyDeps + bundle.mylib

Convenient And Familiar

As Mill is making a push to be a respected polyglot build tool, I think quality of life tools are both familiar to folks coming from other tools like gradle and cargo, and also show a level of polish that users appreciate.

Open Questions

  • Are you open to having this in the main mill codebase (even as a contrib module)?
  • The best TOML library for Scala I see out there is: toml-scala, are we open to pulling in such a dependency?
  • This would require a way to easily hook into the code-generation process of the build itself. This seems like it would be doable by adding code to the meta-build, but if ergonomics is a goal we'd want something more approachable, how could this be accomplished?
@DamianReeves DamianReeves changed the title Provide support for a gradle style version catalogs Provide support for gradle style version catalogs Feb 5, 2025
@lefou
Copy link
Member

lefou commented Feb 5, 2025

I think, why not? Personally, I find managing versions in Scala directly easier, but if that helps with adoption by users and eases tooling, we might as well support it.

I haven't used any TOML library in Scala, so I leave that question open for now.

The code generation seems to be a regular code generator which contributes to generatedSources, but it needs to go to MillBuildRootModule (or better into some dedicated Module/trait) which is the Scala module that builds the build script itself.

I assume, these catalogs are for the whole project, not per-module. Is that right?

@DamianReeves
Copy link
Author

Yeah I see them for the whole project.

@lefou
Copy link
Member

lefou commented Feb 5, 2025

I think this should come as contrib plugin for a start. That way, it can be used in various ways including in meta-builds, which is your intended case. The additional dependencies should be loaded via an worker or isolated classloader, so they don't bloat or collide with the core build. Ideally, you can find an existing library that already does the harder parts and just need to plug-in the part, that writes the Mill-specific code.

@DamianReeves
Copy link
Author

For clarification, when you say contrib plugin, you mean external outside the mill codebase?

@lefou
Copy link
Member

lefou commented Feb 6, 2025

For clarification, when you say contrib plugin, you mean external outside the mill codebase?

I meant the contrib section of the Mill repo. Those will be released as part of the Mill releases, but they are not by-default on the classpath. You need to add them explicitly. See https://mill-build.org/mill/extending/contrib-plugins.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants