Buildscript dependency configs do not work from project config

In our multi-project build, we do most of the subproject setup in allprojects section and I have just added asciidoc support using the gradle-asciidoctor plugin. As it is hosted on Bintray, I needed to add a new repo to the buildscript.

My natural reaction was to add the new repo of the buildscript section of the new projects only, but then I found that it does not work. Thinking about that, I realized that the buildscript block should be evaluated before allprojects, so it kind-of makes sense my setup does not work.

Please add an exception if we try to do something that does not make sense.

This is what fails:

allprojects {
    repositories { ... }
    if (autodetect.hasAsciidoc) {
        buildscript {
            repositories {
                maven {
                    name = 'nexus-asciidoctor-'
                    url = "$repoGroupRoot/asciidoctor"
                }
            }
            dependencies {
                classpath 'org.asciidoctor:asciidoctor-gradle-plugin:0.7.0'
            }
        }
        apply plugin: 'asciidoc'
    }
}

This works:

if (autodetect.hasAsciidoc) {
    buildscript {
        repositories {
            maven {
                name = 'nexus-asciidoctor-'
                url = "$repoGroupRoot/asciidoctor"
            }
        }
        dependencies {
            classpath 'org.asciidoctor:asciidoctor-gradle-plugin:0.7.0'
        }
    }
    apply plugin: 'asciidoc'
}
  allprojects {
    repositories { ... }
}

‘buildscript’ is very special. In general, it should always be specified as the outermost level. If you don’t, you need to know exactly what you are doing. I recommend to get rid of the conditional configuration.

What is the reasoning behind getting rid of the conditional config? In practice, now we specify the build classpath unconditionally, but we do a lot of conditional setup in a custom plugin, deducing capabilities from the file system layout and some custom component descriptors.

As I said, the ‘buildscript’ block is very special. It gets extracted from the build script before the remainder of the build script gets compiled and evaluated, but that extraction only happens if ‘buildscript’ is a top-level element.