(这很长,所以滚动到底部以获得更简短的摘要。)
我在 Gradle 版本目录中遇到了一些奇怪的行为。我不确定是否 我正在以正确的方式做事,但我也很确定我发现了一个错误 Gradle 和/或 IntelliJ。
我们的 Gradle 构建当前使用
gradle.properties
来存储所有版本
我们所有依赖项的信息。我们从以前就一直这样做
版本目录已存在。我现在正在迁移我们的构建以使用版本目录
反而。大部分迁移过程相当轻松。
此迁移的一个棘手部分与 gradle-jooq-plugin 有关。我们需要将版本传递给它 我们用作参数的 jOOQ 库的,以便它将使用 jOOQ 代码生成器的匹配版本。对于属性文件,这是 非常简单(虽然有点冗长):
# All gradle build snippets are using Kotlin DSL
jooq {
version = project.property("jooq_version") as String
我无法找到任何有关如何执行等效操作的文档 版本目录。然而,在 IntelliJ 自动完成的帮助下,我发现了这一点, 这似乎做了正确的事情:
jooq {
version = libs.versions.jooq.version
在我们的
gradle.properties
文件中,我们的所有内容都有一个 _version
后缀
版本:
jooq_version = 3.19.4
起初,我在我们的版本目录中使用了相同的名称:
[versions]
jooq_version = "3.19.4"
...
[libraries]
jooq = { module = "org.jooq:jooq", version.ref = "jooq_version" }
但是,当我一切正常后,我意识到这个后缀不是 确实需要,因为版本位于自己的命名空间中。看例子 版本目录确认约定似乎是命名版本 在它们的版本之后,名称中没有任何内容表明它是 版本。
事情开始变得有点奇怪。我尝试删除
_version
后缀...
...
jooq = "3.19.4"
...
jooq = { module = "org.jooq:jooq", version.ref = "jooq" }
...
...一切似乎都正常 除了将 jooq 版本传递给 插件。 Gradle 失败并显示:
Script compilation errors:
Line 68: version = libs.versions.jooq.version
^ Function invocation 'version(...)' expected
Line 68: version = libs.versions.jooq.version
^ Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public infix fun PluginDependencySpec.version(version: String?): PluginDependencySpec defined in org.gradle.kotlin.dsl
public infix fun PluginDependencySpec.version(version: Provider<String>): PluginDependencySpec defined in org.gradle.kotlin.dsl
奇怪的是,IntelliJ 没有突出显示该行的任何问题。
我尝试删除
.version
后缀,以反映删除
toml 文件中的 _version
后缀...
jooq {
version = libs.versions.jooq
...但随后 IntelliJ 将该行突出显示为错误,而 Gradle 仍然 抱怨,但有不同的错误:
Line 68: version = libs.versions.jooq
^ Val cannot be reassigned
Line 68: version = libs.versions.jooq
^ No applicable 'assign' function found for '=' overload
Line 68: version = libs.versions.jooq
^ Type mismatch: inferred type is LibrariesForLibs.JooqVersionAccessors! but Property<String!>! was expected
在 IntelliJ 中,如果我导航到
libs.versions.jooq
并从那里导航到
它的返回类型,JooqVersionAccessors,我明白了:
public static class JooqVersionAccessors extends VersionFactory {
private final JooqGradleVersionAccessors vaccForJooqGradleVersionAccessors = new JooqGradleVersionAccessors(providers, config);
public JooqVersionAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Returns the version associated to this alias: jooq.version (3.19.4)
* If the version is a rich version and that its not expressible as a
* single version string, then an empty string is returned.
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getVersion() { return getVersion("jooq.version"); }
/**
* Returns the group of versions at versions.jooq.gradle
*/
public JooqGradleVersionAccessors getGradle() {
return vaccForJooqGradleVersionAccessors;
}
}
因此,至少根据 IntelliJ 的说法,那里有 is 一个公共
getVersion()
,但是
Gradle 没有看到它。我还尝试了方法语法只是为了确定......
jooq {
version = libs.versions.jooq.getVersion()
再次强调,IntelliJ 对此感到满意,而 Gradle 则不满意:
Cannot access 'getVersion': it is protected in 'JooqVersionAccessors'
因为似乎 IntelliJ 和 Gradle 对于什么有不同的想法
libs.versions.jooq
的类型看起来像,以便更好地了解什么是
继续我尝试使用反射来打印 libs.versions.jooq
: 上的方法
methods of class org.gradle.accessors.dm.LibrariesForLibs$JooqVersionAccessors
asProvider(param: org.gradle.accessors.dm.LibrariesForLibs.JooqVersionAccessors): org.gradle.api.provider.Provider<kotlin.String!>!
getGradle(param: org.gradle.accessors.dm.LibrariesForLibs.JooqVersionAccessors): org.gradle.accessors.dm.LibrariesForLibs.JooqGradleVersionAccessors!
equals(param: org.gradle.accessors.dm.LibrariesForLibs.JooqVersionAccessors, other: kotlin.Any?): kotlin.Boolean
hashCode(param: org.gradle.accessors.dm.LibrariesForLibs.JooqVersionAccessors): kotlin.Int
toString(param: org.gradle.accessors.dm.LibrariesForLibs.JooqVersionAccessors): kotlin.String
getVersion(param: org.gradle.accessors.dm.LibrariesForLibs.JooqVersionAccessors, name: kotlin.String!): org.gradle.api.provider.Provider<kotlin.String!>!
findVersionConstraint(param: org.gradle.accessors.dm.LibrariesForLibs.JooqVersionAccessors, name: kotlin.String!): org.gradle.api.internal.artifacts.ImmutableVersionConstraint!
有一个
asProvider()
方法看起来很有希望,所以我尝试了:
jooq {
version = libs.versions.jooq.asProvider().get()
这有效,并且我确认它传递了正确的值,但是 IntelliJ 将
asProvider
突出显示为“未解决的参考”。
在
build.gradle.kts
内,我需要获取以下版本(并且仅是版本)
版本目录中定义的特定依赖项,因此可以将其作为
任务配置的参数。这样做的正确方法是什么? (链接
官方文档将不胜感激。)
上述差异是 Gradle、IntelliJ 或两者中的错误吗?
为什么当版本有
libs.versions.foo.version
时 _version
可以工作
后缀,但如果不加后缀,事情的表现就会完全不同?
Gradle Jooq 插件扩展中
version
的类型是 Property<String>
(请参阅 GitHub),目录中 libs.versions.jooq
的类型是 Provider<String>
。
鉴于此,在 Gradle 中您可以设置
version
,不是通过分配它,而是通过编写:
jooq {
version.set(libs.versions.jooq)
}
关于错误,我认为我无法解释您的所有问题,但也许您之前在 TOML 目录中尝试生成的一些 Kotlin 代码以某种方式保留在 IntelliJ 索引中。