¿Cómo compartir la configuration repetitiva de Kotlin en múltiples proyectos de Gradle?

La configuration típica de Kotlin en un proyecto de Gradle es muy repetitiva, y estoy buscando una forma de abstraerla en un script de construcción externo para que pueda ser reutilizada.

Tengo una solución de trabajo (abajo), pero se siente como un truco ya que el plugin de kotlingradle no funciona de esta manera.

Es complicado aplicar cualquier complemento no estándar de un script externo ya que no se puede aplicar el complemento por ID , es decir,

apply plugin: 'kotlin' dará como resultado un Plugin with id 'kotlin' not found.

La solución simple (bueno, generalmente) es aplicarla por el nombre de class completamente calificado del complemento, es decir,

apply plugin: org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper

que en este caso arroja una pequeña y agradable exception que indica que el complemento probablemente no estaba destinado a ser llamado de esta manera:

 Failed to determine source cofiguration of kotlin plugin. Can not download core. Please verify that this or any parent project contains 'kotlin-gradle-plugin' in buildscript's classpath configuration. 

Así que logré hackear un plugin (solo una versión modificada del plugin real ) que lo obliga a encontrar el plugin desde el buildscript actual.

kotlin.gradle

 buildscript { ext.kotlin_version = "1.0.3" repositories { jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" } apply plugin: CustomKotlinPlugin import org.jetbrains.kotlin.gradle.plugin.CleanUpBuildListener import org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper import org.jetbrains.kotlin.gradle.plugin.KotlinPlugin import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider /** * Wrapper around the Kotlin plugin wrapper (this code is largely a refactoring of KotlinBasePluginWrapper). * This is requinetworking because the default behaviour expects the kotlin plugin to be applied from the project, * not from an external buildscript. */ class CustomKotlinPlugin extends KotlinBasePluginWrapper { @Override void apply(Project project) { // use String literal as KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY constant isn't available System.setProperty("kotlin.environment.keepalive", "true") // just use the kotlin version defined in this script project.extensions.extraProperties?.set("kotlin.gradle.plugin.version", project.property('kotlin_version')) // get the plugin using the current buildscript def plugin = getPlugin(this.class.classLoader, project.buildscript) plugin.apply(project) def cleanUpBuildListener = new CleanUpBuildListener(this.class.classLoader, project) cleanUpBuildListener.buildStarted() project.gradle.addBuildListener(cleanUpBuildListener) } @Override Plugin<Project> getPlugin(ClassLoader pluginClassLoader, ScriptHandler scriptHandler){ return new KotlinPlugin(scriptHandler, new KotlinTasksProvider(pluginClassLoader)); } } 

Esto se puede aplicar en cualquier proyecto (es decir, apply from: "kotlin.gradle" ) y está apply from: "kotlin.gradle" para el desarrollo de Kotlin.

Funciona, y todavía no he tenido ningún problema, pero me pregunto si hay una mejor manera. No estoy muy interesado en fusionar los cambios al complemento cada vez que hay una nueva versión de Kotlin.