【问题标题】:How to set properties for a dependent gradle task如何为依赖的 gradle 任务设置属性
【发布时间】:2019-07-17 06:58:46
【问题描述】:

我想设置一个“通用”任务,它将为多个平台构建应用程序包(它使用 javafxpackager)。任务的机制适用于创建所有平台捆绑包,但不同之处在于任务使用的各种属性。

我原以为我会为每个平台创建单独的更高级别的任务,在其中设置平台特定的属性,然后调用/执行/(在此处替换正确的 gradle 术语)通用任务。例如,

task buildMacBundle(dependsOn: ['macBundleConfig', 'buildAppBundle']) << {
  // set Mac-specific properties (project.ext properties?)
  // call/invoke/execute or whatever the mechanism is called, buildAppBundle task
    buildAppBundle.mustRunAfter macBundleConfig
    println "building a Mac app bundle"
}

task macBundleConfig << {
    println "executing macBundleConfig"
    ext {
        nativeType = "dmg"
        bundleAppName = 'My App'
    }
    delete ("${buildDir.name}/dist/${bundleAppName}.dmg")
}


task buildWindowsBundle << {
  // omitted for brevity, but just like buildMacBundle except for property values
}

task buildAppBundle << {

    println "nativeType: ${project.ext.nativeType}" // it stumbles here!

    def cmd = [
        "${javapackager}",
        "-deploy",
        "-native", "${project.ext.nativeType}",
        "-name",
        "${project.bundleAppName}",
        "-outdir",
        "${buildDir.name}${File.separator}dist",
        "-outfile",
        "MyApp",
        "-srcdir",
        "${buildDir.name}${File.separator}${libsDir.name}",
        "-appclass",
        "org.pf.app.MyApp"
    ]

    println cmd.join(" ")

    def javapackager = exec {
        workingDir "${project.projectDir.absolutePath}"
        commandLine cmd
    }
}

但是当我运行“buildMacBundle”时,我得到了

* What went wrong:
Execution failed for task ':buildAppBundle'.
> cannot get property 'nativeType' on extra properties extension as it does not exist

如何定义特定任务中的属性,然后调用通用任务?

【问题讨论】:

    标签: gradle


    【解决方案1】:

    我遇到了类似的问题,发现如果你切换

    ext {
        nativeType = "dmg"
        bundleAppName = 'My App'
    }
    

    project.ext {
        nativeType = "dmg"
        bundleAppName = 'My App'
    }
    

    它应该工作。 据我所知,这是一个范围界定问题——在第一种情况下,您为Task 设置属性,在第二种情况下,为Project 设置属性。


    顺便说一句,我认为buildAppBundle.mustRunAfter macBundleConfig对你来说运行太晚了,因为它是buildMacBundle任务的一部分,所以运行顺序是:

    1. macBundleConfig
    2. buildAppBundle
    3. buildMacBundle

    只有在 3 期间,buildAppBundle 的配置 mustRunAfter 才会改变。

    【讨论】:

      【解决方案2】:

      我用这个解决了:

      gradle.taskGraph.whenReady {taskGraph ->
          if (taskGraph.hasTask(buildMacBundle)) {
              project.ext.nativeType = "dmg"
          } else if (taskGraph.hasTask(buildWindowsBundle)){
              project.ext.nativeType = "exe"
          }
      }
      

      对我来说,这是最简单的方法,但远非直观。在

      用户指南:6.13。按 DAG 配置(无论 DAG 是什么?)

      我怀疑有一种更简单的方法,但肯定不是在编写插件。如果我要创建用于多个 build.gradle 脚本的东西,我会认为一个插件是正确的方法,但在这里,仅在一个 build.gradle 构建脚本中,它是矫枉过正的。

      【讨论】:

      • 这是错误的方法。我提出的解决方案不涉及实现插件。
      【解决方案3】:

      您可以尝试创建 GradleBuild 任务并使用给定的项目属性调用所需的任务。

      task someTask(type: GradleBuild) {
          tasks = ['taskToParametrize']
          startParameter.projectProperties = ['parameterName': 'parameterValue']
      }
      

      然后就可以查询属性了:

      project.properties['parameterName']    
      

      Gradle build logic docs

      【讨论】:

        【解决方案4】:

        任务不应该配置东西。这就是构建脚本和插件的用途。您可能想要的是一个任务类型(即作为一个类实现的任务“模板”),它具有一些配置属性(nativeTypebundleAppName 等),基于这些属性创建一个应用程序包。然后,构建脚本或插件可以声明该类型的多个任务(例如,每个平台一个)并根据需要对其进行配置。或者,您也可以实现多种任务类型,或许扩展一个公共基类。

        【讨论】:

        • 答案太复杂了。这些任务在 build.gradle “构建脚本”中定义。我不应该编写插件来完成如此简单的事情。在 ANT 中,这非常简单。我认为 gradle 是对 ANT 的进步,但这看起来是逆行的。
        • 我提出的解决方案可以在单个构建脚本中实现,不涉及实现插件。
        • 举个例子会很有帮助。只是从答案,我不知道如何开始。这使得这个答案成为最没有帮助的答案之一,尽管它可能是最好的。
        • 没有例子,这个答案不是很有用
        【解决方案5】:

        我遇到了这个解决方案:

        
        task meta1 {
            doLast {
                user.property="variant1"
            }
        }
        
        task meta2 {
            doLast {
                user.property="variant2"
            }
        }
        
        meta1.finalizedBy buildTask
        meta2.finalizedBy buildTask
        
        

        其中buildTask 是执行工作的任务,在此示例中,必须在任务运行之前设置user.property 以配置目标配置。有两个元任务,每个任务都为属性设置适当的值,然后需要通过finalizedBy 命令在其后运行构建任务。

        分级

        【讨论】:

        • 这正是我想要的(尽管我将 finalizedBy 放在了任务本身中)。像task a { doLast { b.prop="c" } finalizedBy b } 这样的东西。谢谢!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-14
        • 2015-08-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多