Alex Semin
05/31/2024, 3:28 PMTYPESAFE_PROJECT_ACCESSORS
Today, Gradle generates a named accessor for the root project, which causes various problems. It looks like this:
// setttings.gradle.kts
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
rootProject.name = "myproject" // <---- some name has been assigned to the root project
include("lib")
// lib/build.gradle.kts
dependencies {
implementation(projects.myproject) // <---- notice the "type-safe" access to the root project
}
Do you know of existing use-cases for this part of the feature?
It seems reasonable to deprecate and remove it, because there are at least two ways to achieve the same thing:
implementation(rootProject)
implementation(project(":"))
Share your use-cases here, or comment on the issue: https://github.com/gradle/gradle/issues/24295Vampire
05/31/2024, 3:58 PMrootProject might not be project isolation safe? But at least not consistent with the other project accessors.
And project(":") is for me not an argument, because then you also just not use type-safe accessors, but just use project("lib").
I don't know why one should name the root project and a subproject the same.Alex Semin
05/31/2024, 4:07 PMI would vote to keep the accessor, as it is imho more consistent.Are there any other arguments in favor of this apart from the consistency?
Alex Semin
05/31/2024, 4:08 PMUsingIt is safe, because no mutable cross-project state is access when setting up a dependencymight not be project isolation safe?rootProject
Vampire
05/31/2024, 4:10 PMAre there any other arguments in favor of this apart from the consistency?Not right now from me, not used them too much so far. But when I use it, I would expect to have an accessor for the root project 🙂
Vampire
05/31/2024, 4:11 PMAlex Semin
05/31/2024, 4:30 PMAnd naming the root project the same as a subproject, I personally consider a build bug anyway, no matter whether the accessors are used or not.Well, it seems a non-trivial number of people would disagree https://github.com/gradle/gradle/issues/16608
Vampire
05/31/2024, 4:33 PM-project to the root project name or similar, especially if it just is an empty project anyway. 🙂Vampire
05/31/2024, 4:34 PMAdam
06/02/2024, 7:49 AMimplementation( project(":") / rootProject / projects.myproject ).
I think that implementation(rootProject) is really strange. rootProject is usually used for configuration, or accessing configuration, and never for adding a dependency. I guess it makes sense technically, but it's conflating a couple of concepts. It's not easy to discover.
I have the same opinion for implementation(project) - which is sometimes needed, e.g. for JVM test suites. It's confusing.
I much prefer using the typesafe accessors. They're similar to the version catalog. I would like it if they were promoted as a default.
I agree it's important to fix the `projects.myproject`/`projects(":myproject)` same-name clash. However, I would prefer to see a different solution, so that the typesafe accessors can be used consistently, and so it's conceptionally simpler to add dependencies. The DSL should also be easier to discover and understand.
• Remove the generated accessor projects.myproject
• Add a generated accessor the root project projects.rootProject (a shortcut for project(":"), only to be used for declaring dependencies).
• For convenience/symmetry, add projects.currentProject (a shortcut for project(project.path) - again, only for declaring dependencies).
And I'd go one step further and deprecate adding dependencies via implementation(rootProject / project). Dependencies should only be added via string coords, version catalog entries, typesafe project accessors, and project(":path") (which should eventually be phased out).Alex Semin
06/03/2024, 6:18 AM• For convenience/symmetry, addWhat is the use case for this part?(a shortcut forprojects.currentProject- again, only for declaring dependencies).project(project.path)
Adam
06/03/2024, 7:07 AMtesting.suites.register<JvmTestSuite>("integrationTest") {
dependencies {
implementation(project())
implementation(projects.fooProject)
implementation(project(":barProject"))
implementation(rootProject)
}
}
This might also look weird, but at least it's consistent!
testing.suites.register<JvmTestSuite>("integrationTest") {
dependencies {
implementation(projects.currentProject)
implementation(projects.fooProject)
implementation(projects.barProject)
implementation(projects.rootProject)
}
}Alex Semin
06/03/2024, 7:23 AMAdam
06/05/2024, 1:20 PMVampire
06/05/2024, 1:22 PMAlex Semin
06/05/2024, 2:56 PM