Included builds from a Settings plugin aren't being imported

I’ve been moving several projects from multi-projects to composite builds.

I’ve written a Settings plugin that conditionally includes builds based on several factors. (Side note, you can tell me this is a bad idea if it is). This plugin is in its own project that I have published to a private repo. Essentially the plugin is this logic:

  • Find potential builds to include
  • If they exist on the file system, includeBuild them

In my settings.gradle for a separate multi-project, I have applied my plugin.

Building from the command line works fine and includes builds when appropriate.

Importing the project into IntelliJ (Android Studio) works as expected as well. I see the additional included builds when they should be available and they are not included when they are not available.

When I import the project into Eclipse (09-2023, buildship 3.1.7) I never see the include builds. Refreshing the Gradle Project doesn’t help.

Am I doing something wrong or am I running into a limitation of buildship?

I think I’ve been running into a path issue. Here’s more detail of the plugin:

class SettingsPlugin implements Plugin<Settings>
{
    void apply( Settings settings )
    {
        ...
        File configFile = new File( 'config' )
        if( configFile.exists() ) 
        {
            // read file and include builds        
        }
        ...
    }
}
my-project
- settings.gradle - applies SettingsPlugin
- config
- everything_else

Gradle on the command line finds config. Eclipse does not (using File->Import->Existing Gradle Project).

To determine that, I added some logging, essentially:
log.info( "configFile: $configFile fullPath: $configFile.absolutePath" ) and ended up with this:
configFile: config fullPath: <USER_HOME>/.gradle/daemon/8.4/configFile for both Eclipse and the command line. However the configFile.exists() check is true when running from the CLI and false importing into Eclipse.

It looks like I can solve/workaround this by passing either settings.rootDir or settings.settingsDir as the parent when I access the config file. I’ve love to know why the CLI finds the file and Eclipse doesn’t in the way I had the code originally.

By using new File(...) with a relative path, you are resolving it relative to the current working directory.
This is practically always the wrong thing to do in any Java program, except for cases where a user specifies a relative path on the commandline, so you can expect it should be relative to his current working directory.

For practically all other cases, it is a bug to do so, that might work as long as the working directory is the expected path.

For Gradle builds, sometimes the current working directory is the actual root project directory, but this is in no case guaranteed or consistent. It can be other directories, or the daemon log directory as in the case you logged and so on.

So any build that uses this is at best flaky and could break anytime. It can work from Eclipse and / or IntelliJ and / or commandline, or it can fail anytime as you have seen.

That from the commandline the log shows the daemon log dir but the logic works is unlikely. I suspect you just assumed it always works from commandline and never works from Eclipse and then just looked at the log output or similar.

The solution as you correctly assumed is to use an explicit directory from the Gradle model.

Thanks for the feedback and confirmation of my mistake @Vampire. When I wrote the code, it just didn’t occur to me that current working directory could be different.

It is a moot point, since I was doing it wrong, but the plugin did work consistently when running from the command line. I had a test project that applied the plugin. Removing configFile would stop including builds. Adding it back would start including them again. Modifying it would also create the expected change.

So I am still puzzled about the log output showing the same file path for the eclipse import and the command line, but it doesn’t really matter.

1 Like