groovy 如何将一个Gradle脚本导入另一个Gradle脚本?

pn9klfpd  于 2022-11-01  发布在  其他
关注(0)|答案(5)|浏览(247)

我有一个复杂的Gradle脚本,它包含了大量功能,用于构建大量NetBeans项目并将其部署到大量环境中。
脚本运行得非常好,但本质上它都是通过半打保存项目和环境信息的Map进行配置的。
我想把任务抽象到另一个文件中,这样我就可以在一个简单的构建文件中定义我的Map,然后从另一个文件导入任务。这样,我就可以在多个项目中使用相同的核心任务,并使用一组简单的Map配置这些项目。
有谁能告诉我如何以与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 build文件的大型项目使用。

yuvru6vn

yuvru6vn1#

在0.9中有一个新特性。你可以使用apply from: 'other.gradle'命令。
请在以下网址阅读我关于同一问题的问题:Is there a way to split/factor out common parts of Gradle build

ttygqcqt

ttygqcqt2#

这个问题的答案就在Plugins系统中,在这里你可以在一组插件中添加所需的功能,这些插件可以是位于buildSrc/src/main/groovy目录下的groovy文件。插件也可以捆绑成Jar,虽然我还没有尝试过。
详细信息:自定义插件

iecba09b

iecba09b3#

如果不实际查看构建文件,很难判断什么最适合您。
我可以假设,将您的环境设置为多项目构建应该可以为您提供所需的抽象。
在项目根目录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都将自动考虑您在各个文件中完成的所有定义。
另外请注意,只要您没有在根级别加载默认插件之外的任何插件,就不会为您的项目根执行编译任务。

ou6hu8tu

ou6hu8tu4#

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

apply(from = "scripts/my-script.gradle.kts")
  • 脚本/我的脚本.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 {
        // ...
    }
}

请参阅this answerthis answer,了解如何从KotlinDSL中的另一个脚本导入函数。

e1xvtsh3

e1xvtsh35#

基于这个类似的问题/答案,我在搜索了几天后找到的最简单的解决方案是使用buildscript.sourceFile。它正确地给出了正在运行的文件,而不是所述进程的pwd/cwd/parent-file。我觉得这会解决你的问题。

相关问题