背景:
我们正在尝试迁移到Gradle的Kotlin DSL,主要是为了增加类型安全性。
我们的一些库定义相当大(在某些极端情况下调用20个以上的exclude
),因此我们目前有一个巨大的dependencies.gradle
Groovy脚本,它声明了所有库的巨大映射,然后可以像libraries.blah
一样使用。我正试图想出一种在科特林也能做到这一点的工作方法。
调查:
依赖项约束(java-platform
插件)允许集中依赖项的版本号,但这对排除没有任何作用,并且排除是我们案例中的大部分问题。(我相信我们最终也会在某个时候使用java-platform
。)
我发现的最优雅的解决方案是在这篇博客文章中,它建议声明Kotlin对象,比如:
object Libraries {
val guava = "..."
}
然后,您可以假定使用类似Libraries.guava
的对象。但这实际上并不起作用,至少在Gradle 6.9.1中是这样,因为Kotlin本身存在问题。(我假设它在一些旧版本上运行,但被Kotlin编译器升级所破坏。)
票证上指定的解决方法如下:
class Libraries(dependencies: DependencyHandler) {
val guava = dependencies.create(...)
}
val libraries by project.extra { Libraries(dependencies) }
这使我更接近于一个有效的解决方案,因为我的dependencies.gradle.kts
文件现在正在编译,但我仍然找不到使用我定义的Libraries
类的方法。如果你这样做:
val libraries: Libraries by project.extra
Kotlin抱怨Libraries
没有定义。因此,就好像一个构建脚本甚至不能导出类供另一个构建剧本使用一样。
更多上下文
实际的项目结构相当复杂,看起来有点像:
─ repo root
├─ mainproject1
│ ├─ subproject11
│ │ └─ build.gradle.kts
│ ├─ subproject12
│ │ └─ build.gradle.kts
│ ├─ build.gradle.kts (references dependencies.gradle.kts)
│ └─ settings.gradle.kts
├─ mainproject2
│ ├─ subproject21
│ │ └─ build.gradle.kts
│ ├─ subproject22
│ │ └─ build.gradle.kts
│ ├─ build.gradle.kts (references dependencies.gradle.kts)
│ └─ settings.gradle.kts
└─ shared
└─ gradle
└─ dependencies.gradle.kts
问题:
其他身材魁梧的人和>100个依赖项解决了这个问题?
解决方法:使用buildSrc
实例化Libraries
对象。
- 创建以下目录结构:
.
├── buildSrc
│ ├── build.gradle.kts
│ └── src
│ └── main
│ └── kotlin
│ └── Libraries.kt
├── settings.gradle.kts
└── build.gradle.kts
buildSrc/build.gradle.kts
是最小的:
plugins {
`kotlin-dsl`
}
repositories {
mavenCentral()
}
Libraries.kt
:
object Libraries {
const val guava = "com.google.guava:guava:31.0.1-jre"
}
- 用法(根
build.gradle.kts
):
plugins {
`java-library`
}
dependencies {
implementation(Libraries.guava)
}
repositories {
mavenCentral()
}