I had a look at the following issue: <https://git...
# gradle
a
I had a look at the following issue: https://github.com/gradle/kotlin-dsl/issues/1287 Where it seems that only main build scripts have type safe accessors (https://docs.gradle.org/current/userguide/kotlin_dsl.html#type-safe-accessors) In that case, is there a desired approach to multi module projects, where I want to reuse some scripts for each module? Typically I’d have another gradle file they can include, but that won’t work with kotlin dsl
g
Yes, use precompiled script plugins
👍 1
you will get type safe accessors
you can use also common plugin, but precompiled script plugins require less boilerplate and provide the same DSL as build.gradle.kts
m
I'm currently writing extensions myself
for example
Copy code
// Hack to allow android block below. See <https://github.com/gradle/kotlin-dsl/issues/1287>
@Suppress("UnstableApiUsage")
fun Project.android(
    configure: com.android.build.gradle.BaseExtension.() -> Unit
): Unit =
    (this as ExtensionAware).extensions.configure("android", configure)
@gildor What would be solution to build scripts that have conflicting namespaces?
For example, I have modules
com.android.library
and
com.android.application
in my app
both of these expose different type for
android
extension. However both extensions extend from the
com.android.build.gradle.BaseExtension
, so I can manually add extension like with code snippet above
g
Only by checking type inside of your
Project.android
function
Also I’m not sure that your approach is correct, why do you write function to configure existing extension
it shouldn’t work like this
Hack to allow android block below
It’s not needed
Static accessors generated automatically if you use plugins block
did you read official guide?
m
I think I explained my use case poorly
let me rephrase
It is multi-module project
that has both application and library modules
Then in main
build.gradle.kts
I have a line like this:
Copy code
subprojects {
	android {
        // Perform some  configuration that is common to both android library and applicaton projects
     }
}
so basically I want to apply android block in single file to both library and application modules
If i I add
Copy code
plugins {
    id("com.android.application")
}
to this common file, then it will break libraries if I add
Copy code
plugins {
    id("com.android.library")
}
then it will break application modules
because both of those modules import their own type for
android
extension, so I would get ClassCastExceptions
g
What you want to achieve? Create a custom plugin with common configuration?
m
I want to be able to update configuration of both library and application modules at once
g
I got it, how you want to apply this configuration?
m
what do you mean
g
Do you use some function in buildSrc, custom plugin, just a config in root build.grafle?
m
just a config in root build.grafle
g
Than it's the only way
Originally in this thread I talk about precompiled script plugins, which is different approach
m
would I be able to do this from precompiled plugins?
or any other way 😄
g
In case of precompiled plugin I would create 2 plugins: application-convention and library-convention and applied them instead of com.android.*
And extract shared config of them to an extension function for BaseExtension
And call it from
android
extension static accessor of each plugin
m
I see
so basically this would be `application-convention.gradle.kts`:
Copy code
plugins {
    id("com.android.application")
}

subprojects {
	android {
        performCommonConfiguration()
     }
}
g
Again, nothing wrong in your approach, it's just not so declarative
No, without subprojects
m
oh, so I would need to manually apply it to every project?
g
You can apply it in submodules block of your root project
But than how would you skip application module?
But I believe that each module should declare main plugin manually, apply the same is never work, you always have application, library, often dynamic-feature etc
We also have many pure java modules
Again, it's just my opinion which I believe based on currently Kotlin DSL and Gradle recommendations
Of course, if every module in your project has the same type it's fine to use submodules and apply common config, it also works for some other configs, like repositories or resolution strategies
m
thanks for your info
g
Also, want to be clear, that if I would create
*-convention
plugins, I would apply them instead of
com.android.*
, not together
m
ah I see
yeah that would make sense
g
One more thing, approach with configuring extension is fine for most medium-sized project if you have only app and library modules, not sure tho that you need any helpers with all this casting, you can just add it to root build,gradle
Copy code
// Configure exten
subprojects { // or even allprojects, depends on your project structure
// Apply this config only when any of android plugins is applied
plugins.withType<com.android.build.gradle.BasePlugin<*>> {
     // configure extension by common type for all android plugins
    configure<com.android.build.gradle.BaseExtension> { 
        // this has type BaseExtension, so you can configure common properties
        compileSdkVersion(28)
    }
}
}
but there is no approach better because you don’t have static accessors in root build.gradle, so you have to use dynamic API
👍 1