如何在多个Gradle项目中共享样板Kotlin配置? [英] How to share boilerplate Kotlin configuration across multiple Gradle projects?

查看:149
本文介绍了如何在多个Gradle项目中共享样板Kotlin配置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Gradle项目中的典型的Kotlin配置非常简单,我正在寻找一种将其抽象到外部构建脚本中以便可以重用的方法.

The typical Kotlin configuration in a Gradle project is very boilerplate, and I'm looking for a way of abstracting it out into an external build script so that it can be reused.

我有一个可行的解决方案(如下),但是由于kotlin-gradle-plugin不能以这种方式工作,所以感觉有点像个黑客.

I have a working solution (below), but it feels like a bit of a hack as the kotlin-gradle-plugin doesn't work out of the box this way.

在您 apply plugin: 'kotlin'将导致Plugin with id 'kotlin' not found.

简单(通常)的解决方法是通过插件的完全合格的类名来应用,即

The simple (well, usually) workaround is to apply by the fully qualified classname of the plugin, i.e.

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

在这种情况下会抛出一个很好的小异常,表明该插件可能不是用这种方式调用的:

which in this case throws a nice little exception indicating that the plugin probably wasn't meant to be called this way:

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.

所以我设法一起破解了一个插件(只是

So I managed to hack together a plugin (just a modified version of the real plugin) which forces it to find the plugin from the current buildscript.

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 required 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));
    }
}

然后可以将其应用于任何项目(即apply from: "kotlin.gradle"),并且您可以启动并运行Kotlin开发.

This can then be applied in any project (i.e. apply from: "kotlin.gradle") and you're up and running for Kotlin development.

它有效,并且我还没有任何问题,但是我想知道是否有更好的方法?每次有新版本的Kotlin时,我都不太热衷于合并对插件的更改.

It works, and I haven't had any issues yet, but I'm wondering if there is a better way? I'm not really keen on merging in changes to the plugin every time there's a new version of Kotlin.

推荐答案

查看星云-kotlin-plugin .看来与您要达到的目标非常接近.

Check out the nebula-kotlin-plugin. It seems very close to what you're trying to achieve there.

这篇关于如何在多个Gradle项目中共享样板Kotlin配置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆