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

时间:2012-03-03 20:21:27

标签: gradle

我目前正在评估gradle作为Maven的替代方案,用于基于本土会议的ant + ivy构建。 ant + ivy版本旨在为各种j2se应用程序提供标准环境。它支持以下传统布局到app config

conf/
    fooPROD.properties
    fooUAT.properties
    bar.properties
    UK/
        bazPROD.properties
        bazUAT.properties

如果我选择为UAT进行构建,那么我得到

conf/
    foo.properties
    bar.properties
    UK/
        baz.properties

即。它复制以目标环境为后缀的文件(本例中为UAT)以及没有此类模式的任何内容。除此之外还有其他各种各样的事情使它变得更加复杂,但这是我当前问题的核心。

我一直在玩各种gradle功能,同时转录它而不是让它正常工作。我目前的方法是允许像这样随时提供targetenv

tasks.addRule("Pattern: make<ID>") { String taskName ->
    task(taskName).dependsOn tasks['make']
}

make任务处理conf文件从src到构建区域的各种复制/过滤/转换。要做到这一点,它必须弄清楚在创建DAG之后我正在做的目标是什么

gradle.taskGraph.whenReady {taskGraph ->
    def makeTasks = taskGraph.getAllTasks().findAll{ 
        it.name.startsWith('make') && it.name != 'make' 
    }
    if (makeTasks.size() == 1) {
        project.targetEnv = makeTasks[0].name - 'make'
    } else {
        // TODO work out how to support building n configs at once
    }
}

(感觉必须有更快/更惯用的方式来做这件事,但我离题了)

我可以像gradle makeUAT

一样运行它

我的问题是以这种方式设置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'
}
一旦我理解了发生了什么。然后失败就像

Skipping task ':prepareEnvSpecificDist' as it has no source files.

因为我没有配置复制任务来告诉它输入和输出是什么。

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

注意:我意识到我可以传递系统属性并执行类似gradle -Dtarget.env=UAT make之类的操作,但这样做比较冗长,而且我想知道发生了什么。

干杯

马特

1 个答案:

答案 0 :(得分:2)

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

如果您绝对想要保存几个字符,则可以查询和操作gradle.startParameter.taskNames以实现看起来像任务名称的环境切换。但是,这是一种非标准的解决方案。

  

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

这是一个更普遍的问题的特殊情况,即配置值在读取后被写入。典型的解决方案是:

  1. 如果可以,请避免使用。
  2. 某些任务/模型属性接受一个闭包,然后懒惰地进行评估。这需要在相应的任务/插件文档中查找。
  3. gradle.projectsEvaluatedgradle.taskGraph.whenReady等全局挂钩中执行配置(具体取决于具体需求)。
  4. 在任务操作中执行配置(在执行时)。正如您已经经历的那样,这并不适用于所有情况,并且通常不鼓励(但有时可以容忍)。
  5. 插件使用convention mapping将模型值延迟绑定到任务属性。这是一种不应在构建脚本中使用的高级技术,但对于编写扩展构建语言的插件是必要的。
  6. 作为旁注,请记住,Gradle允许您介绍自己的抽象。例如,您可以添加一个允许您编写的方法:

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