【问题标题】:How to import a helper class in buildSrc/build.gradle.kts, settings.gradle.kts, and build.gradle.kts?如何在 buildSrc/build.gradle.kts、settings.gradle.kts 和 build.gradle.kts 中导入 helper 类?
【发布时间】:2020-05-31 17:21:11
【问题描述】:

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

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

请考虑我们正在使用Gradle 6.+

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

插件/属性/build.gradle.kts:

package com.example

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

我们如何才能在所有这些文件(buildSrc/build.gradle.ktssettings.gradle.ktsbuild.gradle.kts)中成功导入这个 Properties 类并从那里使用它?比如:

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

我们可以在插件中创建这个类并从那里应用它吗?没有预编译和发布插件?可能是这样的:

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

这将是如何实现的?

我尝试了不同的方法,但我无法找到一种完全适用于这 3 个文件的方法。

【问题讨论】:

    标签: gradle plugins gradle-plugin gradle-kotlin-dsl


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 2018-12-19
      • 2020-08-11
      • 1970-01-01
      • 2023-03-08
      • 2022-08-21
      • 1970-01-01
      • 2023-03-07
      • 2018-10-23
      • 1970-01-01
      相关资源
      最近更新 更多