How can I tell a project to use a settings file from a different location?

I’m working on a rather large multi-project Gradle script that needs to build an arbitrary number of similarly structured java projects. A new requirement that was recently given to me is the need for the Gradle scripts themselves to be kept in their own location, while the projects that they build will be located at various other places in the file system. So basically I need to treat the Gradle scripts as a standalone SDK that the user points to somehow.

Our current (very clunky, begging to be replaced) Ant solution is able to do this rather painlessly by simply relying on a build.xml in each project directory that contains an “import” task that imports the main build.xml from the SDK’s directory. To clarify, it’s setup like this:

projectDir --build.xml {} SDKDir --build.xml {actual work}

Of course, Gradle has the “apply from:” functionality, which is great for single projects, but for my multi-project build I need to use a [highly scripted] settings.gradle to include all the right projects (typically projects that are dependencies for the projects the user is trying to build). This is where everything seems to come crashing down. I can’t use “apply” in a build.gradle to include the SDK’s settings file, because by the time that’s executed it’s already past the initialization phase. Strangely, apply does seem to function when i put it inside settings.gradle, however if I use it to apply from another settings file, it is simply treated as a standard build script that begins functioning during the configuration phase (and thus no projects that it specifies are included).

I know this is due to the fact that Gradle only supports a single settings file at a time, so putting one in the project directory while I really want to use the one in the SDK directory is probably a fool’s errand from the start, but I’m at a loss for what else I can do. The issue seems to me like a relatively simple one–tell a project to refer to a settings file from a directory other than its own (or its parent). Anyone have any ideas?

You can always specify the location of the settings file to be used on command line using ‘-c/–settings-file’ switch. If this becomes clunky and error prone then adding a command line alias for running Gradle for a given project might be a solution.

Also, I could not reproduce that “apply does seem to function when i put it inside settings.gradle, however if I use it to apply from another settings file, it is simply treated as a standard build script that begins functioning during the configuration phase (and thus no projects that it specifies are included)”. I have the following ‘settings.gradle’ file:

apply from: 'settings/settings.gradle'

And in ‘settings/settings.gradle’ I have:

include "sub"

‘gradle projects’ prints the following for such setup:

Root project 'applied-settings'
\--- Project ':sub'

Thanks for the tip on the settings file switch. I doubt I’ll be able to rely on it as a long term solution, but it will probably be helpful for testing things.

Regarding the apply function, I’m actually seeing the projects added when I run the “projects” task just like with your example. The issue I was having that made me think the projects weren’t getting added was the fact that certain project properties such as “projectDir” were giving me errors as if they didn’t exist during the execution of build.gradle. I’m pretty sure this was because I applied not only the additional settings.gradle in my initial settings.gradle, but the additional build.gradle as well, which I think caused it to be treated as yet another settings.gradle. So basically I was doing this:

projectDir/settings.gradle ‘’‘apply from: ‘…/sdkDir/settings.gradle’ apply from: ‘…/sdkDir/build.gradle’{code} ‘’’

But what I really needed was this:

projectDir/settings.gradle ‘apply from: ‘…/sdkDir/settings.gradle’’ projectDir/build.gradle ‘apply from: ‘…/sdkDir/build.gradle’’

It’s great that this works, but it makes me curious now about the general notion of Gradle’s settings file. I’ve seen it repeated several times that a Gradle build will support one and only one settings.gradle but using apply seems to get around this pretty directly. Would this be considered a hack, and might there be any reasons to avoid it?

Anyway, thanks for your reply!

Technically speaking you still have only one settings file because the applied file is a script plugin and not a settings file. You could even create a binary settings plugin (a class that implements Plugin) and apply that instead. This is not a workaround of any kind, it’s a supported behaviour and there’s nothing wrong with using it. There’s no need to be afraid that it will be removed, at least in the foreseeable future.

Awesome, this really helps me out, and will essentially allow me to set up chains of transitive project dependencies with just apply/include, rather that coming up with a much more complicated plugin in Java or Groovy. Thanks again!