【问题标题】:How to pass arguments from command line to Gradle如何将参数从命令行传递到 Gradle
【发布时间】:2012-07-27 22:34:01
【问题描述】:

我正在尝试将参数从命令行传递给 java 类。我关注了这篇文章:http://gradle.1045684.n5.nabble.com/Gradle-application-plugin-question-td5539555.html 但该代码对我不起作用(也许它不适用于 JavaExec?)。这是我尝试过的:

task listTests(type:JavaExec){
    main = "util.TestGroupScanner"
    classpath = sourceSets.util.runtimeClasspath
    // this works...
    args 'demo'
    /*
    // this does not work!
    if (project.hasProperty("group")){
        args group
    }
    */
}

上述硬编码的 args 值的输出是:

C:\ws\svn\sqe\sandbox\selenium2forbg\testgradle>g listTests
:compileUtilJava UP-TO-DATE
:processUtilResources UP-TO-DATE
:utilClasses UP-TO-DATE
:listTests
Received argument: demo

BUILD SUCCESSFUL

Total time: 13.422 secs

但是,一旦我将代码更改为使用 hasProperty 部分并在命令行上将“demo”作为参数传递,我会收到 NullPointerException:

C:\ws\svn\sqe\sandbox\selenium2forbg\testgradle>g listTests -Pgroup=demo -s

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\ws\svn\sqe\sandbox\selenium2forbg\testgradle\build.gradle' line:25

* What went wrong:
A problem occurred evaluating root project 'testgradle'.
> java.lang.NullPointerException (no error message)

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.GradleScriptException: A problem occurred evaluating root project
 'testgradle'.
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:54)
    at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:127)
    at org.gradle.configuration.BuildScriptProcessor.evaluate(BuildScriptProcessor.java:38) 

http://gradle.1045684.n5.nabble.com/file/n5709919/testgradle.zip 有一个简单的测试项目可以说明问题。

这是使用 Gradle 1.0-rc-3。 NullPointer 来自这行代码:

args group 

我在任务定义之前添加了以下分配,但它并没有改变结果:

group = hasProperty('group') ? group : 'nosuchgroup' 

任何关于如何将命令行参数传递给 gradle 的指针表示赞赏。

【问题讨论】:

标签: gradle gradle-task gradle-properties


【解决方案1】:

从 Gradle 4.9 开始,应用程序插件支持 --args 选项,因此传递参数非常简单:

build.gradle

plugins {
    id 'application'
}

mainClassName = "my.App"

src/main/java/my/App.java

public class App {
    public static void main(String[] args) {
        System.out.println(args);
    }
}

重击

./gradlew run --args='This string will be passed into my.App#main arguments'

或者在 Windows 中,使用双引号:

gradlew run --args="This string will be passed into my.App#main arguments"

【讨论】:

    【解决方案2】:

    您可以在 Gradle 中使用自定义命令行选项:

    ./gradlew printPet --pet="Puppies!"
    

    自定义命令行选项在 Gradle 5.0 中是 incubating feature,但在 Gradle 6.0 中公开。

    Java 解决方案

    按照说明here

    import org.gradle.api.tasks.options.Option;
    
    public class PrintPet extends DefaultTask {
        private String pet;
    
        @Option(option = "pet", description = "Name of the cute pet you would like to print out!")
        public void setPet(String pet) {
            this.pet = pet;
        }
    
        @Input
        public String getPet() {
            return pet;
        }
    
        @TaskAction
        public void print() {
            getLogger().quiet("'{}' are awesome!", pet);
        }
    }
    

    然后注册:

    task printPet(type: PrintPet)
    

    现在你可以这样做了:

    ./gradlew printPet --pet="Puppies!"
    

    输出:

    小狗!太棒了!

    Kotlin 解决方案

    open class PrintPet : DefaultTask() {
    
        @Suppress("UnstableApiUsage")
        @set:Option(option = "pet", description = "The cute pet you would like to print out")
        @get:Input
        var pet: String = ""
    
        @TaskAction
        fun print() {    
            println("$pet are awesome!")
        }
    }
    

    然后注册任务:

    tasks.register<PrintPet>("printPet")
    

    【讨论】:

      【解决方案3】:

      project.group 是预定义的属性。使用-P,您只能设置预定义的项目属性。或者,您可以设置 Java 系统属性 (-D)。

      【讨论】:

      【解决方案4】:

      基于 Peter N 的回答,这是一个示例,说明如何添加(可选)用户指定的参数以传递给 Java 主用于 JavaExec 任务(因为您无法手动设置“args”属性,原因是他引用。)

      将此添加到任务中:

      task(runProgram, type: JavaExec) {
      
        [...]
      
        if (project.hasProperty('myargs')) {
            args(myargs.split(','))
        }
      

      ...并像这样在命令行运行

      % ./gradlew runProgram '-Pmyargs=-x,7,--no-kidding,/Users/rogers/tests/file.txt'
      

      【讨论】:

      • 我怎样才能拥有单独的参数?例如:gradle run -Purl='localhost', -Pport='8080', -Pusername='admin' 我在 build.gradle 中的代码应该是什么样子?
      • @Tomas 我建议为此充实一个顶级问题。 (无论如何,我对这种情况的了解还不够充分,无法自己在这里给出一个快速的内联答案。)
      • 别担心,已经搞定了here
      • 截至 2018 年 7 月,有一种更简单的方法。请参阅下面的this answer
      【解决方案5】:

      如果您需要检查并设置一个参数,您的build.gradle 文件将如下所示:

      ....
      
      def coverageThreshold = 0.15
      
      if (project.hasProperty('threshold')) {
          coverageThreshold = project.property('threshold').toString().toBigDecimal()
      }
      
      //print the value of variable
      println("Coverage Threshold: $coverageThreshold")
      ...
      

      Windows 中的 Sample 命令:

      gradlew clean test -Pthreshold=0.25

      【讨论】:

        【解决方案6】:

        这里有一个很好的例子:

        https://kb.novaordis.com/index.php/Gradle_Pass_Configuration_on_Command_Line

        您可以传递参数然后在 ext 变量中提供默认值的详细信息,如下所示:

        gradle -Dmy_app.color=blue
        

        然后在 Gradle 中引用为:

        ext {
           color = System.getProperty("my_app.color", "red");
        }
        

        然后在您的构建脚本中的任何地方,您都可以将其作为课程引用,您可以将其引用为project.ext.color

        更多提示:https://kb.novaordis.com/index.php/Gradle_Variables_and_Properties

        【讨论】:

          【解决方案7】:

          我的程序有两个参数,args[0] 和 args[1]:

          public static void main(String[] args) throws Exception {
              System.out.println(args);
              String host = args[0];
              System.out.println(host);
              int port = Integer.parseInt(args[1]);
          

          我的 build.gradle

          run {
              if ( project.hasProperty("appArgsWhatEverIWant") ) {
                  args Eval.me(appArgsWhatEverIWant)
              }
          }
          

          我的终端提示:

          gradle run  -PappArgsWhatEverIWant="['localhost','8080']"
          

          【讨论】:

          • 截至 2018 年 7 月,有一种更简单的方法。请参阅下面的this answer
          【解决方案8】:

          我编写了一段代码,将命令行参数以 gradle 期望的格式放置。

          // this method creates a command line arguments
          def setCommandLineArguments(commandLineArgs) {
              // remove spaces 
              def arguments = commandLineArgs.tokenize()
          
                      // create a string that can be used by Eval 
                      def cla = "["
                      // go through the list to get each argument
                      arguments.each {
                              cla += "'" + "${it}" + "',"
                      }
          
              // remove last "," add "]" and set the args 
              return cla.substring(0, cla.lastIndexOf(',')) + "]"
          }
          

          我的任务如下所示:

          task runProgram(type: JavaExec) {
              if ( project.hasProperty("commandLineArgs") ) {
                      args Eval.me( setCommandLineArguments(commandLineArgs) )
              }
          }
          

          要从命令行传递参数,请运行以下命令:

          gradle runProgram -PcommandLineArgs="arg1 arg2 arg3 arg4"    
          

          【讨论】:

            【解决方案9】:

            从命令行传递一个 url 将你的 url 保存在 app gradle 文件中,如下所示 resValue "string", "url", CommonUrl

            并在 gradle.properties 文件中给出一个参数,如下所示 CommonUrl="把你的网址放在这里或者可能是空的"

            并从命令行传递一个命令,如下所示 gradle assembleRelease -Pcommanurl=把你的网址放在这里

            【讨论】:

              【解决方案10】:

              这是 Kotlin DSL (build.gradle.kts) 的解决方案。

              我首先尝试将变量作为属性获取,如果是null,则尝试从操作系统环境变量中获取。

              tasks.create("MyCustomTask") {
                  val songName = properties["songName"]
                      ?: System.getenv("SONG_NAME")
                      ?: error("""Property "songName" or environment variable "SONG_NAME" not found""")
              
                  // OR getting the property with 'by'. Did not work for me!
                  // For this approach, name of the variable should be the same as the property name
                  // val songName: String? by properties
              
                  println("The song name: $songName")
              }
              

              然后我们可以从命令行为属性传递一个值:

              ./gradlew MyCustomTask -PsongName="Black Forest"
              

              我们也可以将add an env variable命名为SONG_NAME,使用我们想要的值,然后运行任务:

              ./gradlew MyCustomTask
              

              【讨论】:

                猜你喜欢
                • 2012-07-26
                • 1970-01-01
                • 2018-06-04
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-08-30
                • 1970-01-01
                • 2019-10-25
                相关资源
                最近更新 更多