Gradle依赖于多项目中的defaultTasks

时间:2017-01-20 17:17:42

标签: gradle

关于Gradle(版本3.3)如何在多项目设置(使用java子项目)中解决任务依赖关系的一个小问题。我很傻,所以也许这是一个愚蠢的问题......

我希望在编译之前和编译之后实现一个正在执行的任务。

使用defaultTasks它按预期工作。但是在使用dependsOn定义任务时,它不会。

我的根build.gradle文件如下所示:

defaultTasks 'a', 'classes', 'b'

task a {
    doLast {
        println 'before compile'
    }
}

task b {
    doLast {
        println 'after compile'
    }
}

task doIt(dependsOn: [a, 'classes', b]) {
    doLast {
        println('done!')
    }
}

allprojects {
    group = 'foo'

    repositories {
        mavenCentral()
        maven {
            url 'https://maven.atlassian.com/3rdparty/'
        }
    }
}

subprojects {
    ext {
        springVersion = '4.3.5.RELEASE'
    }
    apply plugin: 'java'
    dependencies {
        compile fileTree(dir: 'lib', include: '*.jar')
        testCompile group: 'junit', name: 'junit', version: '4.12'
    }
}

当我执行gradle时,默认任务按预期执行:我得到“编译前”,然后编译所有子项目,然后“编译后”。

当我执行gradle doIt时,我收到以下错误消息

Task with path 'classes' not found in root project 'teambits-core'.

知道为什么会这样吗?

1 个答案:

答案 0 :(得分:1)

使用build.gradle,只需运行'gradle'就会在我的3.3安装中出现同样的错误。

这里有2个问题。

<强> 1。多项目子项目与所有项目

第一个问题是defaultTasks是在main build.gradle中定义的,但是你的java插件只包含在子项目中。

在多项目构建中,“主”项目不是子项目部分的一部分(只有所有项目影响主项目),但您的'defaultTasks'在顶层定义,因此运行'gradle'将调用master项目中的defaultTasks和classes任务失败,因为它没有加载java插件。

要解决此问题,请将“apply plugin”行移至allprojects(但仅限于此插图,通常您不希望在master中加载java插件,因为它通常是关于设置子项目的。)

<强> 2。 defaultTasks vs dependsOn

第二个问题是(假设您移动了apply插件),那么您将达到defaultTasks和dependsOn之间的真正差异。

defaultTasks按您指定的顺序运行任务:

$ gradle
:a
before compile
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:b
after compile

BUILD SUCCESSFUL

Total time: 0.765 secs

但是使用列表顺序运行doIt将导致gradle按字母顺序运行它们(因为它们之间没有依赖关系,在这种情况下它将按字母顺序运行它们。)

$ gradle doit
:a
before compile
:b
after compile
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:doIt
done!

BUILD SUCCESSFUL

Total time: 0.733 secs

使用mustRunAfter修复依赖顺序

在这种情况下,您可以通过向doIt添加以下内容来修复它:

task doIt(dependsOn: [a, 'classes', b]) {
    b.mustRunAfter(':classes')
    doLast {
        println('done!')
    }
}

将强制b任务稍后完成。