我如何将一个 Gradle 脚本导入到另一个中?

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

该脚本工作得非常好,但实际上它是通过六个包含项目和环境信息的映射进行配置的。

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

有没有人能告诉我如何以类似 Ant 任务的方式将一个 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 构建文件的子项目组成。

93443 次浏览

Well, it is hard to tell what serves you best without actually seeing your build file.

I could assume that stetting up your environment as multi-project build should provide you the abstraction you are looking for.

In your project root build.gradle you define all your domain specific stuff as well as the things that apply to all your subprojects:

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()

The project root directory might also contain a gradle.properties file where you define properties used by your projects:

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

Then in an additional file from your project root named settings.gradle you actually point to your subprojects:

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')
...

Each sub-project directory contains a build.gradle file containing the sub-project specific stuff only.

No matter if you invoke gradle from your project root or sub-project directory, gradle will automatically consider all your definitions done in the various files.

Also note that no compile task will be executed for your project root as long as you don't load any plugin beyond the default plugin at the root level.

There is a new feature in 0.9. You can use apply from: 'other.gradle' command.

Read my question about same thing at: Is there a way to split/factor out common parts of Gradle build

The answer to the question turned out to be in the Plugins system, where you can add the desired functionality in a set of plugins which can be groovy files located in the directory buildSrc/src/main/groovy. Plugins can also be bundled as a Jar though I haven't tried this.

Details here: Custom Plugins

This is an example for Kotlin DSL (build.gradle.kts).

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

scripts/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 {
// ...
}
}

See this answer and this answer for how to import a function from another script in Kotlin DSL.

Based off this similar question/answer, the easiest solution I've found after searching for days is using buildscript.sourceFile. It correctly gives the file being run rather than the pwd/cwd/parent-file of said process. I feel like this would solve your issue.