Gradle 根据配置阶段完成后确定的模式复制文件

Gradle 根据配置阶段完成后确定的模式复制文件,gradle,Gradle,我目前正在评估gradle是否可以作为Maven的替代品,用于基于本土约定的ant+ivy构建。ant+ivy构建旨在为广泛的j2se应用程序提供一个标准环境&它支持以下常规布局到应用程序配置 conf/ fooPROD.properties fooUAT.properties bar.properties UK/ bazPROD.properties bazUAT.properties 如果我选择为UAT进行构建,那么我得到 c

我目前正在评估gradle是否可以作为Maven的替代品,用于基于本土约定的ant+ivy构建。ant+ivy构建旨在为广泛的j2se应用程序提供一个标准环境&它支持以下常规布局到应用程序配置

conf/
    fooPROD.properties
    fooUAT.properties
    bar.properties
    UK/
        bazPROD.properties
        bazUAT.properties
如果我选择为UAT进行构建,那么我得到

conf/
    foo.properties
    bar.properties
    UK/
        baz.properties
i、 e.它复制以目标环境(本例中为UAT)为后缀的文件以及任何没有此类模式的文件。还有很多其他的事情伴随着这件事发生,使事情变得更加复杂,但这是我目前问题的核心

我一直在玩各种各样的gradle功能,而不是仅仅让它工作。我目前的方法是允许像这样动态地提供targetenv

tasks.addRule("Pattern: make<ID>") { String taskName ->
    task(taskName).dependsOn tasks['make']
}
(感觉必须有一种更快/更惯用的方法来实现这一点,但我离题了)

然后我可以像
gradlemakeuat

我的问题是,以这种方式设置
targetEnv
意味着在配置时未设置
targetEnv
。因此,如果我有一个复制任务,如

task prepareEnvSpecificDist(type: Copy) {
    from 'src/main/conf'
    into "$buildDir/conf"
    include "**/*$project.targetEnv.*"
    rename "(.*)$project.targetEnv.(.*)", '$1.$2'
}
它没有执行我想要的操作,因为尚未设置
$project.targetEnv
。天真的,我把这个改成了

task prepareEnvSpecificDist(type: Copy) << {
    from 'src/main/conf'
    into "$buildDir/conf"
    include "**/*$project.targetEnv.*"
    rename "(.*)$project.targetEnv.(.*)", '$1.$2'
}
因为我没有配置复制任务来告诉它输入和输出是什么

问题是如何根据配置完成后变得具体的属性来处理任务配置问题

注意:我意识到我可以传入一个系统属性,并执行类似于
gradle-Dtarget.env=UAT make
的操作,但这相对来说比较冗长,我想知道到底发生了什么

干杯


Matt

为特定目标环境构建是一个跨领域的问题,并不真正符合任务的性质。使用系统属性(
-D
)或项目属性(
-P
)是处理此问题的自然方法

如果您确实想保存几个字符,可以查询和操作
gradle.startParameter.taskNames
,以实现一个看起来像任务名称的环境开关。然而,这是一种非标准的解决方案

如何处理基于配置完成后变得具体的属性的任务配置问题

这是更一般的问题的一个特例,即配置值在读取后被写入。典型的解决方案有:

  • 尽量避免
  • 一些任务/模型属性接受一个闭包,然后对其进行惰性评估。这需要在相应的任务/插件文档中查找
  • 在全局钩子中执行配置,如
    gradle.projectsEvaluated
    gradle.taskGraph.whenReady
    (具体取决于需要)
  • 在任务操作中执行配置(在执行时)。正如您已经体验到的,这并不是在所有情况下都有效,通常是不鼓励的(但有时是可以容忍的)
  • 插件用于将模型值惰性地绑定到任务属性。这是一种高级技术,不应在构建脚本中使用,但对于编写扩展构建语言的插件是必需的
  • 作为旁注,请记住Gradle允许您介绍自己的抽象。例如,您可以添加一个方法,该方法允许您编写:

    environment("uat") {
        // special configuration for UAT environment
    }
    

    答案似乎是用一个闭包来设置它,比如
    include{“***$project.targetEnv.*”}
    在旁注上,你会怎么做?
    Skipping task ':prepareEnvSpecificDist' as it has no source files.
    
    environment("uat") {
        // special configuration for UAT environment
    }