在方法中将gradle任务添加到子项目

时间:2017-07-06 08:15:03

标签: gradle build.gradle multi-project

我有一个包含一些子项目的项目。一些子项目是实用项目,有些项目是实际应用程序。

“application”子项目应该都生成一个带有给定主类等的jar文件。为了解决这个问题,我将以下内容放在父build.gradle中:

def configureApplication(project, mainClass) {
    project.jar { ... }
}

从每个子项目的build.gradle中,我调用configureApplication(project, "my.main.Class")

现在我想向所有应用程序子项目添加deploy任务,以便我可以使用./gradlew deploy部署所有应用程序。我试图通过将它放在父build.gradle中来模仿上述方法:

def configureDeploy(project) {
    project {
        task deploy {
            println "Deploying!"
        }
    }
}

但我正在参加:

Could not find method call() for arguments [build_51pn93...closure3@334ebcaa] on project ':subproj'.

过去一小时我尝试了大约一百个其他变种而没有成功。

问题:如何在不在每个子项目的build.gradle中重复自己的情况下向一些子项目添加任务? (另外,使用父build.gradle中的方法是实现这一目标的合理方法,还是有更多的习惯方式呢?)

3 个答案:

答案 0 :(得分:2)

我阅读了之前的答案及其评论,特别是以下陈述:

  

我非常希望通过子项目build.gradle将部署任务添加到每个相关子项目中(同时将代码重复保持在最低限度)。

这听起来像是插件的完美用例。 Gradle允许您在buildSrc subproject of your root project中定义插件。只需将您的插件源代码放在<rootProjectDir>/buildSrc/src/main/groovy中即可。您可以在the docs中找到更多详细信息。

您的用例的示例插件可能如下所示:

class MyDeployPlugin implements Plugin<Project> {
    void apply(Project project) {
        // you can access the project instance this plugin is applied to
        project.task('deploy') {
            // configure your task
        }
    }
}

现在,您可以在子项目build.gradle文件中应用该插件:

apply plugin: MyDeployPlugin

deploy {
     // configure your task project-specific
}

最后一条建议:与Maven和Gradle共同工作的人经常说,Gradle通过脚本编写的灵活性是最大的优势。在Maven中,如果要添加或更改功能,通常需要编写插件。在Gradle中,您可以简单地编写功能脚本,但如果经常发生这种情况,它将产生clusterfuck和不可重用的代码。因此,每当您需要为多个(子)项目添加相同的功能时,请使用插件。您甚至可以将插件发布到Maven或您自己的存储库。

答案 1 :(得分:1)

在父build.gradle文件中添加子项目的任务确实很常见。

编辑:每条评论,目标是将其应用于所有子项目,而不是选择性项目。

考虑以下settings.gradle

include 'appA', 'appB', 'utilityC'

这是根build.gradle。它为每个应用程序定义了一个自定义DeployTask(doc here)(使用subprojects),但没有对其进行配置:

class DeployTask extends DefaultTask {
    String appName
    String destDir

    @TaskAction
    def deploy() {
        if (appName != null && destDir != null) {
            println "deploying ${appName} to ${destDir}"
        }
    }
}

subprojects { 
    task deploy(type: DeployTask) {}
}

以下为build.gradle的{​​{1}}:

appA

以下为deploy() { appName = "Application A" destDir = "~/server/appA" } 的{​​{1}}:

build.gradle

在这个简单示例中,appB没有deploy() { appName = "Application B" destDir = "~/web/appB" }

示例输出:

utilityC

build.gradle

$ gradle :appA:deploy 
deploying Application A to ~/server/appA

答案 2 :(得分:0)

我强烈建议您使用可配置参数在buildSrc中创建自定义groovy类。然后在gradle中配置它们。

class DeployTask extends DefaultTask {

    def deploymentName, targets, source, deploymentPlan

    @TaskAction
    def deploy() {
       // your stuff using above variables                
    }

}

您可以使用主subprojects{}中的build.gradle来指定所有内容,而不是重复自己。

subprojects { project ->

    if (project.name.contains('application1')) {

        task deploy (type: package.DeployTask) {
            source          = ""
            deploymentName  = ""
            targettype      = ""
        }

    }

    if (project.name.contains('application2')) {

        task deploy (type: package.DeployTask) {
            source          = ""
            deploymentName  = ""
            targettype      = ""
        }

    }

}

或者只是将其添加到项目本身。

这将遍历settings.gradle中指定的所有子项目,并为满足上述条件的每个子项目创建任务部署。

我看到 @Michael Easter 确实在一个单独的答案中解释了它,我同意我的应用程序以完全相同的方式部署到Weblogic。