【问题标题】:Gradle custom task which runs multiple tasks运行多个任务的 Gradle 自定义任务
【发布时间】:2015-12-30 16:05:10
【问题描述】:

我想同时运行多个 gradle 任务。所以不是

./gradlew clean build publish

我想要一个自定义任务

./gradlew cleanBuildPublish

按顺序执行clean buildpublish

这怎么可能?

这不起作用

task cleanBuildPublish {
    dependsOn 'clean'
    dependsOn 'build'
    dependsOn 'publish'
}

【问题讨论】:

  • 你在用java插件吗?
  • @SantoshGokak 是的,我愿意

标签: gradle


【解决方案1】:

尝试以下方法使 cleanBuildPublish 依赖于其他任务

build.gradle

task clean{
    println "lets clean"
}

task build {
    println "lets build"
}

task publish {
    println "lets publish"
}

task cleanBuildPublish{
    println 'lets do all'
}


cleanBuildPublish.dependsOn clean
cleanBuildPublish.dependsOn build
cleanBuildPublish.dependsOn publish

输出

$ gradle cleanBuildPublish
lets clean
lets build
lets publish
lets do all
:build UP-TO-DATE
:clean UP-TO-DATE
:publish UP-TO-DATE
:cleanBuildPublish UP-TO-DATE

BUILD SUCCESSFUL

Total time: 2.738 secs

查看https://docs.gradle.org/current/userguide/more_about_tasks.html#addDependencyUsingTask了解更多详情

【讨论】:

【解决方案2】:

如果您需要按预定义的顺序执行某些任务,那么您不仅需要设置dependsOn,还需要为此任务设置mustRunAfter属性,如以下代码:

task cleanBuildPublish {
    dependsOn 'clean'
    dependsOn 'build'
    dependsOn 'publish'
    tasks.findByName('build').mustRunAfter 'clean'
    tasks.findByName('publish').mustRunAfter 'build'
}

dependsOn 没有定义任务执行的顺序,它只是让一个任务依赖于另一个任务,而mustRunAfter 定义了。

【讨论】:

  • 这样还能单独执行任务吗?
  • 我收到此错误Cannot invoke method mustRunAfter() on null object
  • 另外,您的 cleanBuildPublish 任务必须放在构建脚本中的所有 3 个依赖任务之后
  • 确保在定义完所有单个任务后放置cleanBuildPublish。似乎 gradle 任务是从上到下读取的。这解决了我对Cannot invoke method mustRunAfter() on null object 的问题
  • 重要的是要提到 gradle 不等待任务完成
【解决方案3】:

如果发布任务在名为 subProjectName 的子项目中,

...
tasks.findByPath(':subProjectName:publish').mustRunAfter 'build'
...

【讨论】:

    【解决方案4】:

    尝试在 build.gradle 中添加 defaultTasks。例如。 defaultTasks 'clean', 'build', 'publish'

    【讨论】:

      【解决方案5】:

      您也可以使用名为GradleBuild的任务基类

      在这里你可以用GradleBuild做到这一点

      Groovy DSL:

      task cleanBuildPublish(type: GradleBuild) {
           tasks = ['clean', 'build', 'publish']
      }
      

      Kotlin DSL:

      tasks.register<GradleBuild>("cleanBuildPublish") {
          tasks = listOf("clean", "build", "publish")
      }
      

      【讨论】:

      • 那么任务会按照提到的顺序执行吗?
      • kotlin 版本的吗?
      • Kotlin 版本会非常相似。您只想使用project.tasks.register 来创建您的任务,仅此而已。
      • Gradle 项目特别建议不要这样做:docs.gradle.org/current/userguide/…
      • 注意嵌套调用:运行gradlew cleanBuildPublish somethingElse时,可以先运行somethingElse
      【解决方案6】:

      我的方法是

      task cleanBuildPublish (type: GradleBuild, dependsOn: ['clean', 'build', 'publish']) { 
      }
      

      这对我有用。

      【讨论】:

      【解决方案7】:

      这是我使用 Kotlin 脚本的方法,同时使用了 dependsOn 和 mustRunAfter。这是运行两个任务的示例,一个(自定义注册的“importUnicodeFiles”任务)在“this”项目中,另一个(预定义的“run”任务)在名为“:unicode”的同级项目中:

      tasks.register("rebuildUnicodeFiles") {
          description = "Force the rebuild of the `./src/main/resources/text` data"
          val make = project(":unicode").tasks["run"]
          val copy = tasks["importUnicodeFiles"]
          dependsOn(make)
          dependsOn(copy)
          copy.mustRunAfter(make)
      }
      

      Gradle 开发人员通常反对这种方法(他们说强制排序不好,从其他项目执行任务不好),并且正在研究一种在项目之间发布结果的方法;见:https://docs.gradle.org/current/userguide/cross_project_publications.html

      【讨论】:

        【解决方案8】:

        获取它的通用方法如下:

        task cleanBuildPublish {
          def containedTasks = [clean, build, publish]
          dependsOn containedTasks
          placeTasksInOrder(containedTasks)
        }
        
        def placeTasksInOrder(List tasks) {
          for (int i=0; i < tasks.size() -1; i++) {
            def earlierTask = tasks.get(i)
            def laterTask   = tasks.get(i +1)
            laterTask.mustRunAfter(earlierTask)
          }
        }
        

        dependsOn 使其他任务在运行cleanBuildPublish 时运行,辅助函数placeTasksInOrder 通过调用mustRunAfter 将任务按顺序排列

        执行gradlew cleanBuildPublish somethingElse时,顺序为clean, build, publish, somethingElse


        小心
        如果您有嵌套的 gradle 调用,则以下解决方案不会工作

        task cleanBuildPublish(type: GradleBuild) {
             tasks = ['clean', 'build', 'publish']
        }
        

        执行gradlew cleanBuildPublish somethingElse时,可能会首先调用somethingElse
        所以最好使用mustRunAfterconfiguration。

        【讨论】:

          【解决方案9】:

          我的解决方案如下,它适用于我。

          task cleanBuildPublish {
          
              task _clean {
                  dependsOn 'clean'
              }
          
              task _build {
                  dependsOn '_clean'
                  dependsOn 'build'
              }
          
              dependsOn '_build'
              dependsOn 'publish'
          }
          

          【讨论】:

            猜你喜欢
            • 2019-06-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多