如何在buildSrc/build.gradle.kts,settings.gradle.kts和build.gradle.kts中导入帮助程序类? [英] How to import a helper class in buildSrc/build.gradle.kts, settings.gradle.kts, and build.gradle.kts?

查看:361
本文介绍了如何在buildSrc/build.gradle.kts,settings.gradle.kts和build.gradle.kts中导入帮助程序类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个类来帮助我加载不同类型的属性(local.propertiesgradle.properties$GRADLE_HOME/gradle.properties,环境变量,系统属性和自定义属性文件(也许采用其他格式,例如xml等.

I'd like to create a class to help me loading different types of properties (local.properties, gradle.properties, $GRADLE_HOME/gradle.properties, environment variables, system properties, and custom properties files (maybe in other formats like yml, xml, etc.).

此外,我想在我的buildSrc/build.gradle.ktssettings.gradle.ktsbuild.gradle.kts中使用它.

Also, I'd like to use this in my buildSrc/build.gradle.kts, settings.gradle.kts, and build.gradle.kts.

请考虑我们使用的是Gradle 6.+.

该类的一个简单实现是(完整的实现会更强大):

A simple implementation of this class would be (the full implementation would be a lot of more powerful):

plugins/properties/build.gradle.kts:

plugins/properties/build.gradle.kts:

package com.example

object Properties {
    val environmentVariables = System.getenv()
}

如何在所有这些文件(buildSrc/build.gradle.ktssettings.gradle.ktsbuild.gradle.kts)中成功导入此Properties类并从那里使用它?像这样:

How can we successfully import this Properties class in all of those files (buildSrc/build.gradle.kts, settings.gradle.kts, build.gradle.kts) and use it from there? Something like:

println(com.example.Properties.environmentVariables ["my.property"])

println(com.example.Properties.environmentVariables["my.property"])

我们可以在插件中创建此类并从那里应用吗?没有预编译和发布插件?也许像这样:

Can we do that creating this class inside of a plugin and applying it from there? Without pre-compiling and releasing the plugin? Maybe something like:

apply("plugins/properties/build.gradle.kts")

apply("plugins/properties/build.gradle.kts")

这将是最小的实现吗?

我尝试了不同的方法,但无法找到一种可以完全使用这3个文件的方法.

I tried different approaches but I'm not being able to find a way that work with those 3 files altogether.

推荐答案

我对这种方法并不完全满意,但也许可以帮助其他人. 我无法在所有地方重用一个类,而是一个函数,像这样:

I'm not completely satisfied with this approach but maybe it can help others. I wasn't able to reuse a class but a function in all places, like this:

settings.gradle.kts

apply("plugin/properties/build.gradle.kts")
@Suppress("unchecked_cast", "nothing_to_inline")
inline fun <T> uncheckedCast(target: Any?): T = target as T
val getProperty = uncheckedCast<(key: String) -> String>(extra["getProperty"])
println(getProperty("group"))

buildSrc/build.gradle.kts

apply("../plugin/properties/build.gradle.kts")
@Suppress("unchecked_cast", "nothing_to_inline")
inline fun <T> uncheckedCast(target: Any?): T = target as T
val getProperty = uncheckedCast<(key: String) -> String>(extra["getProperty"])
println(getProperty("group"))

build.gradle.kts

// Can be used inside of the file
apply("plugin/properties/build.gradle.kts")
@Suppress("unchecked_cast", "nothing_to_inline")
inline fun <T> uncheckedCast(target: Any?): T = target as T
val getProperty = uncheckedCast<(key: String) -> String>(extra["getProperty"])
println(getProperty("group"))

buildScript {
    // Since the other getProperty is not visible here we need to do this again.
    apply("plugin/properties/build.gradle.kts")
    @Suppress("unchecked_cast", "nothing_to_inline")
    inline fun <T> uncheckedCast(target: Any?): T = target as T
    val getProperty = uncheckedCast<(key: String) -> String>(extra["getProperty"])
    println(getProperty("group"))
}

plugin/properties/build.gradle.kts

import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
import java.util.Properties as JavaProperties
import org.gradle.api.initialization.ProjectDescriptor

object Properties {

    lateinit var rootProjectAbsolutePath : String

    val local: JavaProperties by lazy {
        loadProperties(JavaProperties(), Paths.get(rootProjectAbsolutePath, "local.properties").toFile())
    }

    val environment by lazy {
        System.getenv()
    }

    val system: JavaProperties = JavaProperties()

    val gradle: JavaProperties by lazy {
        loadProperties(JavaProperties(), Paths.get(rootProjectAbsolutePath, "gradle.properties").toFile())
    }

    val globalGradle: JavaProperties by lazy {
        loadProperties(JavaProperties(), Paths.get(System.getProperty("user.home"), ".gradle", "gradle.properties").toFile())
    }

    fun containsKey(vararg keys: String): Boolean {
        if (keys.isNullOrEmpty()) return false

        keys.forEach {
            when {
                local.containsKey(it) -> return true
                environment.containsKey(it) -> return true
                system.containsKey(it) -> return true
                gradle.containsKey(it) -> return true
                globalGradle.containsKey(it) -> return true
            }
        }

        return false
    }

    fun get(vararg keys: String): String {
        return this.getAndCast<String>(*keys) ?: throw IllegalArgumentException("Property key(s) ${keys} not found.")
    }

    fun getOrNull(vararg keys: String): String? {
        return getAndCast<String>(*keys)
    }

    inline fun <reified R> getOrDefault(vararg keys: String, default: R?): R? {
        return getAndCast<R>(*keys) ?: default
    }

    inline fun <reified R> getAndCast(vararg keys: String): R? {
        if (keys.isNullOrEmpty()) return null

        keys.forEach {
            val value = when {
                local.containsKey(it) -> local[it]
                environment.containsKey(it) -> environment[it]
                system.containsKey(it) -> system[it]
                gradle.containsKey(it) -> gradle[it]
                globalGradle.containsKey(it) -> globalGradle[it]
                else -> null
            }

            // TODO Improve the casting using Jackson
            if (value != null) return value as R
        }

        return null
    }

    private fun loadProperties(target: JavaProperties, file: File): JavaProperties {
        if (file.canRead()) {
            file.inputStream().use { target.load(it) }
        }

        return target
    }
}

if (rootProject.name == "buildSrc") {
    Properties.rootProjectAbsolutePath = rootDir.parent
} else {
    Properties.rootProjectAbsolutePath = rootDir.absolutePath
}

extra["getProperty"] = {key: String -> Properties.get(key)}

这篇关于如何在buildSrc/build.gradle.kts,settings.gradle.kts和build.gradle.kts中导入帮助程序类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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