gradle脚本,直接dsl和 “apply from:”的自定义函数调用有什么区别

标签 gradle apply

首先,私有(private) maven repo 中部署了一些常用脚本:

http://domain/repo/com/d/build/script/java-project/1.0/java-project-1.0.gradle

http://domain/repo/com/d/build/script/maven/1.0/maven-1.0.gradle

在目标项目中,build.gradle

subprojects {
  apply from: 'http://domain/repo/com/d/build/script/java-project/1.0/java-project-1.0.gradle'
  apply from: 'http://domain/repo/com/d/build/script/maven/1.0/maven-1.0.gradle'
}

没关系!

但,
ext.applyScript = { script, version ->
  apply from: "http://domain/repo/com/d/build/script/${script}/${version}/${script}-${version}.gradle"
}

subprojects {
  applyScript('java-project', '1.0')
  applyScript('maven', '1.0')
}

它会失败 ,带有消息:

“错误:无法添加任务':javadocJar',因为具有该名称的任务已经存在。”

任务“:javadocJar”在脚本“java-project-1.0.gradle”中定义
我们有几个子项目。

为什么 ?

顺便说一句:任何人都可以给我一个“申请来源:”的来源位置吗?

我自己很难定位。

最佳答案

问题是在 latte 案例中,您将脚本多次应用于同一个根项目。

这怎么可能?这很有趣,也有点棘手:

  • 您正在定义 applyScript作为扩展容器的闭包ext当前 Gradle 项目的
  • 一般是 apply from: ...作为方法调用处理 apply(Map)org.gradle.api.plugins.PluginAware接口(interface)是 org.gradle.api.Project 的 super 接口(interface)之一界面
  • 这意味着每次你写 apply ...您正在调用apply当前 Gradle 项目上的方法(指定 apply ... 的方法)
  • 正如您定义的 apply ...作为关闭的一部分,标准委派适用
  • 它在语义上与 this.apply ... 相同
  • this默认指向作为根项目的封闭类/对象(这里不能是其他任何东西)

  • 因此,即使看起来您正在将 2 个脚本应用于所有子项目,实际上您实际上是将 2 个脚本应用于根项目 N 次(N 是子项目的数量)。

    您需要做的是将委托(delegate)更改为正确的Project实例。 :
  • 您可以通过向闭包添加一个额外的参数并显式调用该参数的 apply 方法来非常轻松地做到这一点:
    ext.applyScript = { project, script, version ->
        project.apply from: "..."
    }
    
    subprojects {
        applyScript(it, 'java-project', '1.0')
        applyScript(it, 'maven', '1.0')
    }
    
  • 或者您可以明确设置委托(delegate):
    ext.applyScript = { script, version ->
        apply from: "..."
    }
    
    subprojects {
        applyScript.resolveStrategy = Closure.DELEGATE_FIRST
        applyScript.delegate = it
    
        applyScript('java-project', '1.0')
        applyScript('maven', '1.0')
    }
    
  • 关于gradle脚本,直接dsl和 “apply from:”的自定义函数调用有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40373209/

    相关文章:

    gradle - 如何在 gradle 中添加预处理任务

    android - 如何使用库源代码创建 .aar 文件?

    Gradle Findbugs 评估子项目,但不评估具有根任务的根项目

    python - 如何记录引发 KeyError 的值

    r - 计算向量的最大版本

    Gradle:从 .class 文件创建 .jar 并在构建 EAR 时将其包含在 EAR_dir/lib 中

    gradle - 无法使用Serenity Framework使用Gradle执行Jbehave

    R ave 还是申请?通过具有 strata 变量的函数添加列,但快速且多列

    r - 使用 "apply"将函数应用于矩阵,其中参数是特定于列的

    R_使用apply函数时提取正在使用的元素的行和列