Plugins DSL, multi-project build, and extension configuration

Considering a note in 7.0 release that apply plugin is going to be deprecated in the future, how would one configure the extension for all projects in a multi-project build?

For example, I have checkstyle plugin. I’ve been configuring it like this
allprojects {
apply plugin: ‘checkstyle’
checkstyle {

}
}

Now, with plugins {} block, it seems like the recommended way would be to have plugins { id 'checkstyle' } in every single build.gradle as it can’t be used in allprojects {}. Not optimal but not deadly either. However, I can’t keep its config in allprojects {} also cause the plugin and so extension are not applied yet when allprojects run. Copying the same config to a dozen build.gradle files is not something I’m looking forward to. What is the way of doing this with plugins DSL?

Actually the idiomatic approach is to use a convention plugin that you apply in all your projects manually instead of using allprojects or subprojects closures.

But as far as I know, the apply syntax will only be deprecated after the gaps were closed, like for example using a plugins block in such closures or in regular script plugins.

Besides convention plugins you could of course also use a regular script plugin that you then apply with apply from: ....

Or you can leave the configuration in the allprojects closure actually.
And if it does not work because the plugin is not applied yet, then you can make it reactive like

allprojects {
    pluginManager.withPlugin("checkstyle") {
        // config here
    }
}

Thanks, Björn! Conventional plugins seem to be the cleanest way and I’ll give it a try. One restriction there is that one has to put them in src/main/groovy that is does not look nice in a multi-project setup as it mixes projects/modules and sources at the top level. Any other way to have them compiled? Maybe in a conventional subproject/submodule?

Not sure what you mean.
A convention plugin is a precompiled script plugin.
So you have it either in a separate build you include via composite build or in buildSrc.
So they are pretty well separated from your production code.

It was not clear where this buildSrc comes from even. In the docs at Sharing build logic between subprojects Sample it goes from rather convention layout, similar to what I have:

├── internal-module
├── library-a
├── library-b
└── settings.gradle

straight into

├── buildSrc
│   ├── build.gradle
│   ├── settings.gradle
│   ├── src

with it’s settings and stuff. And this is way different from how I organize top-level projects. Never have buildSrc just hanging up there. I’d rather have something like

├── shared
│   ├── build.gradle
│   └── (src/groovy/main/) shared.java-conventions.gradle
├── internal-module
├── library-a
├── library-b
└── settings.gradle

I don’t see in the doc how can I place conventional plugin where I need it to be though.

Anyway, thanks! Looks like I’ll keep using apply plugin: until plugins DSL matures.

I don’t really get your question and plugins dsl is already pretty mature.
If you don’t want buildSrc then as I said you can just use any place you like and use a composite build to include that build.
So you add a settings.gradle to shared as every build should have a settings script and then you do includeBuild('../shared') in your main settings script.