如何将参数或参数传递到 gradle 任务中

Posted

技术标签:

【中文标题】如何将参数或参数传递到 gradle 任务中【英文标题】:How to pass parameters or arguments into a gradle task 【发布时间】:2013-12-23 00:49:23 【问题描述】:

我有一个 gradle 构建脚本,我试图在其中包含 Eric Wendelin 的 css 插件 - http://eriwen.github.io/gradle-css-plugin/

它很容易实现,而且因为我只想要缩小(而不是合并和 gzipping),所以构建脚本的相关部分如下所示:

minifyCss 
    source = "src/main/webapp/css/brandA/styles.css"
    dest = "$buildDir/brandA/styles.css"
    yuicompressor 
        lineBreakPos = -1
    


war 
    baseName = 'ex-ren'


war.doFirst 
    tasks.myTask.minifyCss.execute()

这很完美——当我运行 gradle war 任务时,它会调用 minifyCss 任务,获取源 css 文件,并在 buildDir 中创建一个缩小版本

但是,我有一些 css 文件需要缩小,但没有合并到一个文件中(因此我没有使用 combineCss 任务)

我想做的是使 minifyCss 任务引用某种类型的变量的源和目标属性(假设这是正确的术语?) - 要么变量传递到签名中的任务,要么全局变量,什么的……

我猜是这样的(这是行不通的):

minifyCss(sourceFile, destFile) 
    source = sourceFile
    dest = destFile
    yuicompressor 
        lineBreakPos = -1
    


war 
    baseName = 'ex-ren'


war.doFirst 
    tasks.myTask.minifyCss.execute("src/main/webapp/css/brandA/styles.css", "$buildDir/brandA/styles.css")
    tasks.myTask.minifyCss.execute("src/main/webapp/css/brandB/styles.css", "$buildDir/brandB/styles.css")
    tasks.myTask.minifyCss.execute("src/main/webapp/css/brandC/styles.css", "$buildDir/brandC/styles.css")

这也不起作用:

def sourceFile = null
def destFile = null

minifyCss 
    source = sourceFile
    dest = destFile
    yuicompressor 
        lineBreakPos = -1
    


war 
    baseName = 'ex-ren'


war.doFirst 
    sourceFile = "src/main/webapp/css/brandA/styles.css"
    destFile = "$buildDir/brandA/styles.css"
    tasks.myTask.minifyCss.execute()

对于我的一生,我无法弄清楚如何调用任务并传递变量:(

非常感谢任何帮助;

【问题讨论】:

【参考方案1】:

您应该考虑在调用 Gradle 时传递 -P 参数。

来自Gradle Documentation:

--项目道具 设置根项目的项目属性,例如 -Pmyprop=myvalue。请参阅第 14.2 节,“Gradle 属性和系统属性”。

考虑到这个 build.gradle

task printProp << 
    println customProp

调用Gradle -PcustomProp=myProp 将给出以下输出:

$ gradle -PcustomProp=myProp printProp
:printProp
myProp

BUILD SUCCESSFUL

Total time: 3.722 secs

这是我发现的传递参数的方式。

【讨论】:

我同意比皮。我运行了以下内容。 有没有办法使参数可选? 在任务中,可以使用project.hasProperty('a')和project.getProperty('a')。可能不是最短的语法,但至少你可以在属性不存在时做一些事情。 我不想要命令行参数,因为我想从 gradle 构建脚本中务实地多次调用任务。有没有办法做到这一点? 这是错字吗?应该是“-P customProp”而不是“-PcustomProp”吗?【参考方案2】:

如果您要向其传递参数的任务是 JavaExec 类型,并且您使用的是 Gradle 5,例如应用程序插件的 run 任务,则为 you can pass your parameters through the --args=... command line option。例如gradle run --args="foo --bar=true"

否则没有方便的内置方法来执行此操作,但有 3 种解决方法。

1。如果值很少,任务创建函数

如果可能的值很少并且事先已知,您可以通过编程方式为每个值创建一个任务:

void createTask(String platform) 
   String taskName = "myTask_" + platform;
   task (taskName) 
      ... do what you want
   


String[] platforms = ["macosx", "linux32", "linux64"];
for(String platform : platforms) 
    createTask(platform);

然后您可以通过以下方式调用您的任务:

./gradlew myTask_macosx

2。标准输入法

一种方便的技巧是通过标准输入传递参数,并从中读取您的任务:

./gradlew myTask <<<"arg1 arg2 arg\ in\ several\ parts"

代码如下:

String[] splitIntoTokens(String commandLine) 
    String regex = "(([\"']).*?\\2|(?:[^\\\\ ]+\\\\\\s+)+[^\\\\ ]+|\\S+)";
    Matcher matcher = Pattern.compile(regex).matcher(commandLine);
    ArrayList<String> result = new ArrayList<>();
    while (matcher.find()) 
        result.add(matcher.group());
    
    return result.toArray();   


task taskName, 
        doFirst 
            String typed = new Scanner(System.in).nextLine();
            String[] parsed = splitIntoTokens(typed);
            println ("Arguments received: " + parsed.join(" "))
            ... do what you want
         
 

您还需要在构建脚本的顶部添加以下行:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Scanner;

3。 -P 参数

最后一个选项是将-P 参数传递给Gradle:

./gradlew myTask -PmyArg=hello

然后您可以在构建脚本中以myArg 的身份访问它:

task myTask 
    doFirst 
       println myArg
       ... do what you want
    

his answer on splitting arguments into tokens@789 的信用卡

【讨论】:

这个答案也一样,它并不真正适用于我。我想从 gradle 构建脚本中务实地多次调用该任务。有没有办法做到这一点? @IanVaughan 我想你可能误解了 gradle 的工作原理。为了让我们可以帮助您,您能否分享不同价值观的来源?你事先知道它们会是什么吗? @VicSeedoubleyew 我面临的问题与 Ian 面临的问题相同。我从命令行调用父任务,该任务有两个子任务,需要在脚本本身中传递参数。有办法吗? @ParagKadam “子任务”是什么意思?什么是你的“父母”和“孩子”?【参考方案3】:

我会建议Gradle forum上介绍的方法:

def createMinifyCssTask(def brand, def sourceFile, def destFile) 
    return tasks.create("minify$brandCss", com.eriwen.gradle.css.tasks.MinifyCssTask) 
        source = sourceFile
        dest = destFile
    

我自己用这个方法来创建自定义任务,效果很好。

【讨论】:

【参考方案4】:
task mathOnProperties << 
    println Integer.parseInt(a)+Integer.parseInt(b)
    println new Integer(a) * new Integer(b)


$ gradle -Pa=3 -Pb=4 mathOnProperties
:mathOnProperties
7
12

BUILD SUCCESSFUL

【讨论】:

【参考方案5】:

我认为您可能希望将每组 css 的缩小视为单独的任务

task minifyBrandACss(type: com.eriwen.gradle.css.tasks.MinifyCssTask) 
     source = "src/main/webapp/css/brandA/styles.css"
     dest = "$buildDir/brandA/styles.css"


etc etc

顺便说一句,在战争任务的动作中执行你的缩小任务对我来说似乎很奇怪 - 让它们成为战争任务的依赖项不是更有意义吗?

【讨论】:

感谢您的回复,我想我明白了......但我无法让它工作:( - 当我按照您所说的那样定义我的任务时:“任务 minifyBrandACss(类型:MinifyCssTask ) ...”我在运行它时得到这个:“在根项目'ex-ren'上找不到属性'MinifyCssTask'”。我猜这是一个类路径问题??但我不知道在哪里设置它?我在我的 buildscript dependencies closeure 中已经有“classpath 'com.eriwen:gradle-css-plugin:1.8.0'” 道歉 - 你可能需要完全限定类型 - 我已经编辑了我的答案【参考方案6】:

再简单不过了。

运行命令:./gradlew clean -PjobId=9999

在 gradle 中使用:println(project.gradle.startParameter.projectProperties)

你会得到线索的。

【讨论】:

什么是-P?为什么我们要把它和 arg 放在一起呢?我们不能做gradlew clean -P myArg=myValue吗?顺便说一句,感谢您简短而干净的回答

以上是关于如何将参数或参数传递到 gradle 任务中的主要内容,如果未能解决你的问题,请参考以下文章

如何在 build.gradle 中将参数传递给 Gradle 任务

如何将参数从 gradle exec 任务传递到命令行

如何从命令行将参数传递给gradle

如何使用 kotlin dsl Gradle 将编译器参数传递给 java Compiler

如何在 Rails 中使用环境将参数传递给 Rake 任务? [复制]

将参数传递给windows计划任务