我有一个多模块 Java / Gradle 项目,其中每个模块都有相同的配置,所以我想将其移动到约定插件作为预编译脚本插件。问题是所有模块都使用 liquibase-gradle-plugin,这似乎实现起来并不简单。
首先,liquibase 插件实现了自己的依赖范围
liquibaseRuntime
,但我的插件不知道该范围。这是我的依赖项块(使用版本目录):
dependencies {
implementation libs.plugins.jooq.liquibase
implementation libs.plugins.gradle.liquibase
liquibaseRuntime libs.postgresql
liquibaseRuntime libs.liquibase
liquibaseRuntime libs.jooq
liquibaseRuntime libs.picocli
}
但这会产生错误
Caused by: org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method liquibaseRuntime() for arguments [map(valueof(DependencyValueSource))] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
at org.gradle.internal.metaobject.AbstractDynamicObject$CustomMissingMethodExecutionFailed.<init>(AbstractDynamicObject.java:190)
at org.gradle.internal.metaobject.AbstractDynamicObject.methodMissingException(AbstractDynamicObject.java:184)
at org.gradle.internal.metaobject.ConfigureDelegate.invokeMethod(ConfigureDelegate.java:80)
如果我将
liquibaseRuntime
更改为 implementation
错误就会消失,但我不想导出这些依赖项,它们只是用于 liquibase 插件。
其次,实际的插件配置需要这样的配置闭包:
liquibase{
activities {
main {
changeLogFile "src/main/liquibase/changelog.xml"
// more config
}
}
}
如果我在插件中写下这个,我会收到错误
Caused by: java.lang.RuntimeException:
org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException:
Could not find method liquibase() for arguments [precompiled_EsrJooqLiquibase$_run_closure3@664b65b8] on project ':moduleA' of type org.gradle.api.Project.
如何以编程方式从外部创建这样的配置闭包?
为了在预编译脚本插件中使用外部插件,您需要将包含这些插件的 JAR 添加到插件构建脚本中插件的类路径中,就像普通代码一样(文档)。
如果您在
buildSrc
中编写插件,这将位于文件 buildSrc/build.gradle
中。
与常规库一样,插件 JAR 的 Maven 坐标1 用于此目的。这些应该添加到 implementation
配置中:
// buildSrc/build.gradle
repositories {
gradlePluginPortal()
}
dependencies {
implementation 'org.liquibase:liquibase-gradle-plugin:2.2.1'
}
我们还将 Gradle 插件门户注册为存储库,以便 Gradle 知道在哪里可以找到 JAR。现在您可以在预编译的脚本插件中应用该插件,并且您应该可以访问所有常用的配置选项:
// Precompiled script plugin code
plugins {
id 'org.liquibase.gradle'
}
这里不需要插件版本,因为插件代码已经通过之前的设置位于类路径中。
1 Maven 坐标(即 groupId:artifactId:version)与插件 id 不同(后者是用于在 Gradle 中应用插件的标识符)。在 Gradle 插件门户上发布的插件的 Maven 坐标在插件页面上声明(例如Liquibase)作为用于“旧版插件应用程序”的坐标。