Share classpath between buildscript and project configuration

My build script needs the same classpath for buildscript and the projects runtime configuration. I am probably using the wrong terminology.

I don’t want this duplication:

buildscript {

repositories { flatDir dirs: ‘lib’ }

classpath ‘a’

classpath ‘b’ }

repositories { flatDir dirs: ‘lib’ }

dependencies {

runtime ‘a’

runtime ‘b’

}

How can I share? For example, this doesn’t work:

buildscript {

repositories { flatDir dirs: ‘lib’ }

classpath ‘a’

classpath ‘b’ }

dependencies {

runtime buildscript.configurations.classpath }

And I would want to share the repositories.

It seems like I am endlessly struggling to find how to get access to a key and a value from different places in gradle.

The ‘buildscript’ block is very special. It’s more or less a “meta” build script that has to be evaluated before the rest of the build script can even be compiled. There shouldn’t be many common repositories/dependencies between the two, and I recommend to declare them twice. If you really want to share, something like this might work:

buildscript {
    ext.sharedRepos = {
        flatDir dirs: 'lib'
    }
    ext.sharedDeps = ['a', 'b']
      repositories sharedRepos
    dependencies {
        classpath sharedDeps
    }
}
  repositories sharedRepos
dependencies {
    runtime sharedDeps
}

The basic idea here is that because the ‘buildscript’ block gets evaluated first, the rest of the build script can access the ‘buildscript’ block, but not the other way around.

2 Likes

Thank you for the explanation about the evaluation time.

I have groovy code in a task and import statements. If I don’t have the buildscript block, the classes in the import statements aren’t found. If I don’t have the dependencies block, the classes in the task aren’t found.

Unfortunately, using the code that you suggested, and nothing else (with valid string instead of ‘a’ and ‘b’), I get an error message saying no such property sharedRepos for class DefaultScriptHandler.

I’ve updated the code (see above), it should now work.

Thank you. That worked, with a plugin that creates the runtime configuration.

Is the buildscript block evaluated during what the documentation calls the build initialization phase? Is there a project at that point and evaluating the build script adds the extra properties to the project?

Not quite. A build script is essentially executed in two phases. In the first, only ‘buildscript {}’ blocks are evaluated. At the end of this, what was in these blocks goes into forming the classpath for the execution of the rest of the script.