The build fails with Unresolved reference: testImplementation. It’s weird for me since I specified apply(plugin = "kotlin") in the subproject section. That plugin should bring testImplementation and other configurations into scope!
Besides that it is bad practice to cross-configure projects like that, you only get the accessor you expect if you apply a plugin using the plugins DSL, not if you use the legacy apply method you are using there. It should work if you make testImplementation a string iirc though.
What’s the reason behind to not configure multiple projects from within root build.gradle.kts like I did? Why it’s a bad practice?
How can I then apply a bunch of plugins to all subproject without duplicating
plugins {
application
kotlin("jvm") version "1.6.10"
...
}
across all build.gradle.kts files?
Or I shouldn’t care about such kind of duplicating?
That has multiple reasons and I might miss some, but some are:
it’s cleaner if a project defines it’s own build and not configuration comes from other projects injected
that also increases maintainability
you cannot use the recommended plugins DSL, but only the legacy apply function
with Kotlin DSL you don’t get type safe accessor generated for plugins applied the legacy way
cross project configuration like that couples projects, which prevents some advanced optimizations like configuration cache or configure on demand
…
There are probably some others in just don’t have on mind right now.
The idiomatic way is to have a convention plugin either in buildSrc or - what I prefer - in an included build, which you then apply to the projects directly. This way you don’t have duplication and the actual project build scripts often just apply one to a few convention plugins and define a list of dependencies. And if you write the convention plugin as precompiled script plugin, it looks almost like a normal build script.