How do I include buildscript block from external gradle script?

I’m trying to include an external gradle script that holds the whole buildscript block like this:

apply from: "lib/gradle/buildscript.gradle"
apply plugin: "myplugin"

where buildscript.gradle is:

buildscript {
 repositories {
  def libDir = new File(project.projectDir.canonicalPath, '../Build/lib'
  flatDir dirs: libDir
 }
 dependencies {
  classpath 'my.group:mylib:1.0'
 }
}

However, I’m getting an error in the build saying "Plugin with id ‘myplugin’ not found.

If I move the entire block into the main build.gradle it works fine, but I really want to hide as much of the plumbing as possible from devs, and making it maintainable over multiple projects from one place. I can also move the “apply plugin: ‘myplugin’” line into buildscript.gradle and it works too.

I’ve tried doing as suggested on http://forums.gradle.org/gradle/topics/inherit_inject_buildscript_dependencies_into_custom_script_within_subproject and having format:

buildscript {
 apply from: "path/to/buildscript.gradle", to: buildscript
}

and removing the surrounding “buildscript { }” from that file, however, any properties I reference in buildscript.gradle (like “project.projectDir”) come back with “Could not find property ‘project’ on repository container.”

In this particular case, I can make everything relative without referencing project.projectDir at all, so I can get away with it. But is this just a limitation of the method or a lack of understanding by me?

So I’m trying to find the best way to combine both styles to minimize the copy paste over many projects.

cheers,

In external scripts (we call them script plugins), plugin IDs cannot be used. Instead, the fully qualified class name has to be used. This is a known bug.

Secondly, externalizing a build script block into a script plugin isn’t supported. (It’s a tough problem, and can’t think of a good way to implement this.) You may have to live with some duplication, at least for the time being. Remember that dependencies specified in a project’s ‘buildscript’ block are visible to all subprojects. Hence, as long as you don’t need dependencies to be available in a script plugin, you just need to declare them in the root project’s build script.

ok, thanks for the clarification.

But see http://www.gradle.org/docs/current/userguide/init_scripts.html

Also, this works: slightly more verbose than a one-liner, but quite tidy.

buildscript { apply from: “${gradle_base_path}/init_buildscript.gradle”, to: buildscript } apply plugin: ‘my-custom-plugin’

Define gradlebasepath in your gradle.properties file. It can be either a URL or a file path.

I note that when Peter last replied to this thread 2 years ago, he appears to say that what Immo describes doesn’t work (plugin id for an external script). Has this bug been fixed since then, or are we talking about different things here?

I have a feeling the Immo’s second solution will have the same issue as the OP’s; the project properties will not be available. I’d really like to separate the buildscript block into a reusable file.

Better yet I’d like an easy way to reuse gradle scripts over different projects as we have many builds that are basically just copy after copy of the same or very similar gradle files… I prefer scripts to plugins as the DSL is familiar and more clear to me.

I’ve packaged up scripts into a commonBuild.jar and then the buildscript grabs that file from an enterprise Ivy repo and then I can apply files from the commonBuild.jar, but it still feels harder / messier than it should be.

3 Likes