首页 文章

Gradle 无法识别应用子脚本中的插件任务

提问于
浏览
1

我真的想将我的脚本模块化为多个部分(测试,默认,文档,android)部分。但是当我尝试将子脚本应用于父脚本时,我遇到了问题...

这是我的子脚本(IDE 此时没有抱怨)

import io.gitlab.arturbosch.detekt.Detekt

task("hello").doLast {
    println("Hello World from plugins! :D")
}

tasks {
    val detekt by existing(Detekt::class) {
        reports {
            html {
                val destination = "$buildDir/detekt"
            }
        }
    }
}

但是当我尝试将此脚本应用于主脚本时:

apply(from = "tdd.gradle.kts")

我得到了以下错误:

Script compilation errors:

  Line 01: import io.gitlab.arturbosch.detekt.Detekt
                  ^ Unresolved reference: io

  Line 10:  val detekt by existing(Detekt::class) {
                                   ^ Unresolved reference: Detekt

  Line 11:      reports {
             ^ Unresolved reference: reports

  Line 12:          html {
              ^ Unresolved reference: html

如何解决这个问题,以便我可以在子脚本中应用示例的 detekt 插件并将其应用到 parrent 脚本中?

2 回答

  • 0

    来自 Gradle 核心开发(情况与你的相似):

    脚本插件无权访问主要的 buildcript 类路径。

    您可以使用 buildscript {}语法将 mycompany.plugin 的依赖项添加到 tests.gradle

    所以基本上,使用旧的buildscript语法,你的导入应该工作

  • 0

    我试图破解这么多方面。它的长短是在 Kotlin DSL 中是不可能的。

    UNTESTED:我会尝试的方法(bc 这是我还没有尝试过的一件事)是在你应用的脚本插件中做插件(旧样式)和配置的所有应用程序作为显式交叉项目配置的方式不需要在应用的脚本中使用allProjectssubProjects块。

    您应该参考 gradle 当前的项目文档,但通常采用以下形式:

    project(":foo") {
        // Some configuration here
        apply(plugin = "plugin.id.here.sample-plugin")
        // Then use configuration techniques in the Kotlin DSL guide for configuring when you don't have access to type-safe accessors, small example below
        configure<SamplePluginExtension> {
            // Plugin extension configuration...
        }
    }
    

    这是因为在 Kotlin 中 DSL allProjectssubProjects块在应用脚本插件中定义时仍然不会像 hope/expect(据我所知)。

    虽然我的要求使我不值得测试上面的完整 cross-project/apply 插件技术,但我确实绕过allProjectssubProjects没有预期的行为(并且需要在这些块中正确使用withPlugin<PluginClass>,因为这似乎不能很好地与上面的插件问题)通过在我应用的脚本中声明 extra-lambas 然后从它们相关的allProjectssubProjects配置块中的目标脚本调用它们。

    例如:

    applied.build.gradle.kts

    val allProjectsConfiguration by extra { p: Project ->
        // Some project configuration here...
    }
    

    build.gradle.kts

    //Boilerplate build script dependencies, repositories, and buildscript block as necessary...
    val allProjectsConfiguration: (Project) -> Unit by extra
    allProjects {
        allProjectsConfiguration(this)
    // where `this` is not the host script's project, not the applied script's project (of course), but one of the given projects in *all* of the projects.
    

    这些 lambda 的一些一般安全提示:

    • 使用p作为Project实例将确保没有使用它的开发人员需要考虑当前在范围内的项目实例(在应用的脚本中或在其调用的位置)。这也意味着仍然可以使用呼叫站点的封闭范围提供的project

    • 大量考虑返回单位提供 side-effect 免费使用。一些插件具有扩展,只需注册在它们的配置块中找到的所有实例,就可以容纳容器的各种元素。除非绝对要求是最安全的选择,否则不会隐式支持链接。

    • 请记住,在很多情况下,人们不能在标准库中依赖 kotlin 的T.apply { },因为它会解析为 Gradle 的apply所以如果你想在多个配置 lambdas 中轻松地执行此操作(或返回 Unit),最好创建它一个小帮助函数基本上可以在 Kotlin 中执行什么操作,或者,像我一样,构建一个帮助程序,运行它给出的块并始终返回 Unit(或一些通用类型)。

    @ToYonos - gradle 建议不适用于 Kotlin DSL。我得到的结果很差(我特意使用classpath依赖)因为 gradle 会报告插件从未应用过,并且在同一个错误消息中它表明应用了扩展。我的浅层猜测是,这与字节代码 and/or 有关,它为应用的脚本提供了单独的类加载器。 (对不起,我会把它放在你的答案评论中,但没有足够的代表)

相关问题