103

我有一个复杂的 Gradle 脚本,它包含围绕构建和部署多个 NetBeans 项目到多个环境的大量功能。

该脚本运行良好,但本质上它都是通过包含项目和环境信息的六张地图配置的。

我想将任务抽象到另一个文件中,这样我就可以在一个简单的构建文件中简单地定义我的地图,并从另一个文件中导入任务。通过这种方式,我可以为多个项目使用相同的核心任务,并使用一组简单的地图配置这些项目。

谁能告诉我如何以类似于 Ant 任务的方式将一个 Gradle 文件导入另一个文件?到目前为止,我已经搜索了 Gradle 的文档,但无济于事。

附加信息

在汤姆下面的回应之后,我想我会试着澄清我的意思。

基本上我有一个运行多个子项目的 Gradle 脚本。但是,子项目都是 NetBeans 项目,并带有自己的 ant 构建脚本,所以我在 Gradle 中有任务来调用每个项目。

我的问题是我在文件顶部有一些配置,例如:

projects = [
    [name:"MySubproject1", shortname: "sub1", env:"mainEnv", cvs_module="mod1"],
    [name:"MySubproject2", shortname: "sub2", env:"altEnv", cvs_module="mod2"]
]

然后我生成任务,例如:

projects.each({
    task "checkout_$it.shortname" << {
         // Code to for example check module out from cvs using config from 'it'.
    }
})

我有很多这样的任务生成片段,它们都是通用的——它们完全取决于项目列表中的配置。

所以我想要的是一种将它放在一个单独的脚本中并以下列方式导入它的方法:

projects = [
    [name:"MySubproject1", shortname: "sub1", env:"mainEnv", cvs_module="mod1"],
    [name:"MySubproject2", shortname: "sub2", env:"altEnv", cvs_module="mod2"]
]

import("tasks.gradle") // This will import and run the script so that all tasks are generated for the projects given above.

因此,在此示例中,tasks.gradle 将包含所有通用任务生成代码,并将针对主 build.gradle 文件中定义的项目运行。这样,tasks.gradle 是一个可供所有大型项目使用的文件,这些大型项目由许多具有 NetBeans ant 构建文件的子项目组成。

4

4 回答 4

140

0.9 中有一个新功能。你可以使用apply from: 'other.gradle'命令。

阅读我关于同一件事的问题:Is there a way to split/factor out common parts of Gradle build

于 2010-04-07T05:48:46.810 回答
17

问题的答案原来是在插件系统中,您可以在其中将所需的功能添加到一组插件中,这些插件可以是位于目录中的 groovy 文件buildSrc/src/main/groovy。插件也可以捆绑为 Jar,虽然我没有尝试过。

此处的详细信息:自定义插件

于 2011-08-30T09:48:54.183 回答
4

好吧,如果没有实际看到您的构建文件,很难说出什么对您最有用。

我可以假设将您的环境设置为多项目构建应该为您提供您正在寻找的抽象。

在您的项目根目录 build.gradle中,您定义所有特定于域的内容以及适用于所有子项目的内容:

repositories {
    add(new org.apache.ivy.plugins.resolver.FileSystemResolver()) {
        name = 'destRepo'
        addIvyPattern( file( project.properties['repo.dest.dir']).absolutePath + '/[organisation]/[module]/ivys/ivy(-[revision]).xml')
        addArtifactPattern( file( project.properties['repo.dest.dir']).absolutePath + '/[organisation]/[module]/[type]s/[artifact](-[revision]).[ext]')
        descriptor = 'optional'
        checkmodified = true
    }
    ...
}
...
subprojects {
    sourceCompatibility = 1.5
    targetCompatibility = 1.5
    group = 'my.group'
    version = '1.0'
    uploadArchives {
        uploadDescriptor = true
        repositories {
            add rootProject.repositories.destRepo
        }
    }
    apply{ type my.group.gradle.api.plugins.MyPlugin }
    ...
}

dependsOnChildren()

项目根目录还可能包含一个gradle.properties文件,您可以在其中定义项目使用的属性:

buildDirName=staging
repo.dest.dir=/var/repo
...

然后在您的项目根目录中的一个附加文件中,您settings.gradle实际上指向您的子项目:

include 'my-first-component',
        'my-second-component'
...
project(':my-first-component').projectDir = new File(rootDir, 'path/to/first/component')
project(':my-second-component').projectDir = new File(rootDir, 'path/to/second/component')
...

每个子项目目录都包含一个build.gradle仅包含子项目特定内容的文件。

无论您gradle是从项目根目录还是子项目目录调用,gradle 都会自动考虑您在各个文件中完成的所有定义。

另请注意,只要您没有在根级别加载默认插件之外的任何插件,就不会为您的项目根执行任何编译任务。

于 2010-02-19T00:19:01.353 回答
0

这是 Kotlin DSL (build.gradle.kts) 的一个示例。

apply(from = "scripts/my-script.gradle.kts")

脚本/my-script.gradle.kts

println(
    """
    I am defined at the top level of the script and
    executed at the configuration phase of build process
    """
)

tasks.create("MyTask") {
    println(
        """
        I am defined in a task and
        run at the configration phase of build process"""
    )
    doLast {
        // ...
    }
}

有关如何从 Kotlin DSL 中的另一个脚本导入函数的信息,请参阅此答案此答案。

于 2022-02-17T18:20:04.393 回答