gradle icon indicating copy to clipboard operation
gradle copied to clipboard

Properties defined in 'gradle.properties' should be passed down to child builds

Open bigdaz opened this issue 7 years ago • 17 comments

@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.

bigdaz avatar Jul 19 '17 19:07 bigdaz

Hello, Maybe there is workaround for this. Need to pass project property to root composite build and override it included projects.

alexey-kanashevich avatar Feb 28 '20 14:02 alexey-kanashevich

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.

trevjonez avatar Feb 28 '20 18:02 trevjonez

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?

LarsKaulen avatar Jun 29 '20 07:06 LarsKaulen

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)
      }
    }
  }
}

Dkhusainov avatar Sep 23 '20 16:09 Dkhusainov

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 with version=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 all gradle.properties files (this is already working today)

jjohannes avatar Oct 14 '20 13:10 jjohannes

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?

jjstreet avatar Mar 17 '21 16:03 jjstreet

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.

sugarmanz avatar Nov 25 '21 01:11 sugarmanz

Any fix in sight?

Phlegethon90 avatar May 05 '23 02:05 Phlegethon90

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

programadorthi avatar Feb 11 '24 15:02 programadorthi

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 with version=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 all gradle.properties files (this is already working today)

Can composite builds now share a single gradle.properties?

Cyberavater avatar Mar 30 '24 02:03 Cyberavater

@Cyberavater they just intentionally won't add this behavior by default

lonkly avatar Apr 23 '24 03:04 lonkly

A simple workaround I'm using is symlinking gradle.properties file into all included builds using relative paths.

technoir42 avatar Apr 23 '24 08:04 technoir42

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? 😜

lonkly avatar Apr 25 '24 04:04 lonkly

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

technoir42 avatar Apr 25 '24 22:04 technoir42

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 😢 .

rsicarelli avatar May 02 '24 18:05 rsicarelli

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

bddckr avatar May 02 '24 19:05 bddckr

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 😉

cmoine avatar Jun 17 '24 13:06 cmoine