如何为依赖的Gradle任务设置属性

9
我希望设置一个“通用”任务,可以为多个平台构建应用程序包(使用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
我该如何定义特定任务中的属性,以便调用通用任务?
5个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
8
我遇到了类似的问题,我发现如果您切换

标记和
    标记的顺序,可以解决这个问题。
    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 才会被更改。


5

我用以下方法解决了这个问题:

gradle.taskGraph.whenReady {taskGraph ->
    if (taskGraph.hasTask(buildMacBundle)) {
        project.ext.nativeType = "dmg"
    } else if (taskGraph.hasTask(buildWindowsBundle)){
        project.ext.nativeType = "exe"
    }
}
对我而言,这是最简单的方法,但离直观还有很大差距。我在Google上搜索了很多次才偶然发现了这个用户指南中的6.13.按DAG配置(DAG是什么?)。我猜测可能有更简单的方法,但肯定不是编写插件。如果我要创建一个将用于多个build.gradle脚本的东西,我会考虑创建一个插件,但在这里,只有一个build.gradle构建脚本,这显然是过度杀伐了。

这种方法是错误的。我提出的解决方案不涉及实现插件。 - Peter Niederwieser

2
我遇到了这个解决方案:


task meta1 {
    doLast {
        user.property="variant1"
    }
}

task meta2 {
    doLast {
        user.property="variant2"
    }
}

meta1.finalizedBy buildTask
meta2.finalizedBy buildTask

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

Gradle


这正是我正在寻找的(尽管我将 finalizedBy 放在了任务本身内部)。类似于 task a { doLast { b.prop="c" } finalizedBy b }。谢谢! - nitrogen

2

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

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

然后您可以查询属性:

project.properties['parameterName']    
请查看Gradle构建逻辑文档。链接:Gradle build logic docs

0

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


回答太过复杂了。这些任务在build.gradle“构建脚本”中已经定义好了。我不应该写一个插件来完成这么简单的事情。在ANT中,这非常直截了当。我原以为Gradle是ANT的升级版,但这看起来相反。 - pfurbacher
我提出的解决方案可以在一个构建脚本中实现,而不需要实现插件。 - Peter Niederwieser
13
举个例子会很有帮助。仅凭答案,我不知道该如何开始。尽管这个答案可能是最好的,但它是最没有帮助的之一。 - Michael Schmeißer
1
没有示例,这个答案不是很有用。 - Andrés Alcarraz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,