gradle
gradle copied to clipboard
Properties defined in 'gradle.properties' should be passed down to child builds
@oehme commented on Thu Oct 06 2016
Properties (both in gradle.properties and passed via -P
) should be passed to included builds.
@adammurdoch commented on Wed Mar 08 2017
Maybe. The injection of configuration from a containing build needs more discussion. I don't think we necessarily want to automatically inherit everything, but probably want something a bit more declarative to allow a build to push config down.
@adammurdoch commented on Wed Mar 08 2017
As always, we should start with the use cases instead of the implementations.
@eskatos commented on Tue Apr 25 2017
One example use case. I wanted to run the :install
task of the Gradle build from a composite build and pass it a installPath
property. Ideally my composite build would have a bunch of tasks depending on :gradle:install
with different installPath
properties. Maybe it's a bit of a stretch.
Hello, Maybe there is workaround for this. Need to pass project property to root composite build and override it included projects.
another use case. composite builds for android project must all use the same version of the android gradle plugin. I usually setup my projects with agp_version=x.y.z
in gradle.properties, but having to go update 2...N projects to test a new versions is less than ideal.
Properties passed via -P
are already passed to included builds (tested with Gradle versions 6.4 and 6.5), properties set in gradle.properties
are not passed.
I have another use case, for which it would be necessary to set a property programmatically. If projectA
includes projectB
and a certain task of projectA
is executed, I want to set a property in the build.gradle
of projectA
that can be evaluated in the build.gradle
of projectB
, because in this case a special behaviour of projectB
is necessary.
I guess this isn't possible/supported at the moment?
Simple workaround for reading properties from root project into included project if anyone needs it:
buildscript {
new BufferedReader(new FileReader(file('../gradle.properties'))).withCloseable { reader ->
String line
while ((line = reader.readLine()) != null) {
if (line.startsWith('myProperty')) {
project.ext.myProperty = line.substring(line.indexOf('=') + 1)
}
}
}
}
Common Use Case
I define the version of my product in gradle.properties
and all my components, located in separate builds, should use that same version.
Real world occurrence in Spring Boot build. If you change the build into a composite hierarchy, this breaks.
To reproduce the issue:
- download composite build sample
- Add a
gradle.properies
files withversion=1.1
- Add a
println(name + ":" + properties["version"])
to all build files
You'll see how it works for app
(which is a subproject) but not the other included build projects:
number-utils:unspecified
string-utils:unspecified
multirepo-app:1.1
app:1.1
Expected Behavior
- A property is passed down to child builds and from there to the nested children
- A child may override the property in its own
gradle.properties
, then that value is used and passed to the children of that child - a
-P
property overrides all definition of that property in allgradle.properties
files (this is already working today)
Another use case similar to @jjohannes and also related to spring boot is when I want to use conventions to author a multi-project build of a spring boot based project.
I have 2 main projects app
and domain
both are using spring's style of dependency management.
I have an application
convention plugin that applies org.springframework.boot
and because of that, have to provide the dependency in the build.gradle
file:
dependencies {
implementation "io.spring.gradle:dependency-management-plugin:$springDependencyManagementVersion"
implementation "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
}
I have to add springBootVersion
to the buildSrc
gradle.properties
file instead of where I would like to see it--in the my root project's gradle.properties
where other versions are held as properties.
I also have to set things other properties like urls to my nexus repos in each properties file as well because they are not inherited from the root project.
I would be happy with what @jjohannes is proposing as expected behavior.
Does gradle know the full project hierarchy so that included composite builds know what project is the parent?
Just wanted to post the workaround that ended up working best for me. If there is no need to define additional properties at the included composite build, you can just symlink the top-level project gradle.properties
into the composite project. This will ensure that the properties are automatically propagated for use within the composite project as "regularly" defined properties.
EDIT: Just to note that this falls short if you'd like to build the project on different operating systems.
Any fix in sight?
Sharing my workaround to this. It is not the better approach but works:
Tree:
- root-project
- build-logic
- domain-model
- platforms
- ...
- gradle.properties
- settings.gradle.kts
settings.gradle.kts
val builds = listOf(
"build-logic",
"domain-model",
"platforms",
)
rootProject.name = "root-project"
// Issue: https://github.com/gradle/gradle/issues/2534
val gradleProperties = "gradle.properties"
builds.forEach { projectName ->
includeBuild(projectName)
val includeGradleProperties = File(rootDir, "$projectName/$gradleProperties")
if (!includeGradleProperties.exists()) {
file(gradleProperties).copyTo(includeGradleProperties)
}
}
.gitignore
/**/gradle.properties
Common Use Case
I define the version of my product in
gradle.properties
and all my components, located in separate builds, should use that same version.Real world occurrence in Spring Boot build. If you change the build into a composite hierarchy, this breaks.
To reproduce the issue:
- download composite build sample
- Add a
gradle.properies
files withversion=1.1
- Add a
println(name + ":" + properties["version"])
to all build filesYou'll see how it works for
app
(which is a subproject) but not the other included build projects:number-utils:unspecified string-utils:unspecified multirepo-app:1.1 app:1.1
Expected Behavior
- A property is passed down to child builds and from there to the nested children
- A child may override the property in its own
gradle.properties
, then that value is used and passed to the children of that child- a
-P
property overrides all definition of that property in allgradle.properties
files (this is already working today)
Can composite builds now share a single gradle.properties?
@Cyberavater they just intentionally won't add this behavior by default
A simple workaround I'm using is symlinking gradle.properties
file into all included builds using relative paths.
A simple workaround I'm using is symlinking
gradle.properties
file into all included builds using relative paths.
Will you kindly let us see the script? 😜
Will you kindly let us see the script? 😜
There is no script. Creating a symlink is as simple as:
cd my-included-build
ln -s ../gradle.properties
A simple workaround I'm using is symlinking
gradle.properties
file into all included builds using relative paths.
It's a great solution if the whole team works on MacOS. Unfortunately, this is not possible for Windows users 😢 .
I've used symlinks for gradle.properties
successfully on Windows and can confirm it works when you got it configured before you clone the repo: https://github.com/git-for-windows/git/wiki/Symbolic-Links
To import all properties (based on @Dkhusainov suggestion), I changed it to:
buildscript {
Properties properties = new Properties()
file('../gradle.properties').withInputStream {
properties.load(it)
}
properties.forEach { key, val ->
project.ext[key] = val
}
}
my 2 cts 😉