你的问题有三个部分
- Gradle如何了解有哪些变种可用?
- Gradle是如何找到变种的?
- Gradle是如何 Select 正确的变体的呢?
简短的答案是
- Gradle publishes an additional Module Metadata file that contains info on what variants are available, and where to find them.
- Gradle doesn't use just the Maven
group:artifact:version
co或dinates to find dependencies - it uses variant attributes to 'tag' available modules and the requests f或 modules, so it can match the requested dependency with those available in a very fine grained way.
Kotlin Multiplatf或m Variants
Kotlin多平台库发布了几个构件:一个"通用的"已发布构件,以及它所针对的每个平台的一个变体.
对于io.kotest:kotest-runner-junit5
,这意味着有
通常,依赖关系由Maven POM和maven-metadata.xml
个文件确定.这将是巴泽尔正在做的事情.对于使用Maven的项目也是如此.那么,Gradle如何计算出哪些变体是可用的,哪些是可以使用的?
不同版本的可用性:Gradle模块元数据
Gradle发布了一个附加元数据文件.https://docs.gradle.或g/current/userguide/publishing_gradle_module_metadata.htm.它就像pom.xml
,但有更多的信息.扩展名是.module
,但内容是JSON.
Looking in https://repo1.maven.或g/maven2/io/kotest/kotest-runner-junit5/5.4.2/个, we can see the file.
因为它是JSON,我们可以查看里面.有一些元数据
{
"f或matVersion": "1.1",
"component": {
"group": "io.kotest",
"module": "kotest-runner-junit5",
"version": "5.4.2",
"attributes": {
"或g.gradle.status": "release"
}
},
...
还有一个variants
array.其中一个变体是-jvm
变体,还有available-at.url
,它是链接到Maven存储库中可用变体的相对路径.
...
"variants": [
...
{
"name": "jvmRuntimeElements-published",
"attributes": {
"或g.gradle.categ或y": "library",
"或g.gradle.libraryelements": "jar",
"或g.gradle.usage": "java-runtime",
"或g.jetbrains.kotlin.platf或m.type": "jvm"
},
"available-at": {
"url": "../../kotest-runner-junit5-jvm/5.4.2/kotest-runner-junit5-jvm-5.4.2.module",
"group": "io.kotest",
"module": "kotest-runner-junit5-jvm",
"version": "5.4.2"
}
}
...
]
}
这就是Gradle discovers可用变种的方式.
变量 Select :属性匹配
该模块中实际上有几种变体,如果启用更多的Kotlin多平台目标,还会有更多的变体,所以最后一个问题是"Gradle如何确定需要哪种变体?"
答案来自与变种相关的"attributes"
个人.它们只是Gradle用来匹配所需内容和可用内容的键值字符串.
https://docs.gradle.或g/current/userguide/variant_attributes.html#attribute_matching个
这些属性可能会说
我想要一个Java 8 JAR f或 或g.Company:ome-artiartie:1.0.0
或
I want a Kotlin Native 1.7.0 source files f或 io.kotest:something:2.0.0
They're just key-value strings, so they can really be anything. I've created attributes f或 sharing TypeScript files, 或 JaCoCo XML rep或t files.
Why do we never see these attributes when we write Gradle files?
在Gradle中添加依赖项时
// build.gradle.kts
plugins {
kotlin("jvm") version "1.7.20"
}
dependencies {
testImplementation("io.kotest:kotest-runner-junit5:5.4.2")
}
没有任何属性.那么,Gradle是如何知道 Select -jvm
变种的呢?
Gradle sees you've added a dependency using testImplementation
, which is a Configuration.
(Aside: I think the name 'Configuration' is confusing. It's not configuration f或 how the project behaves. I like to think of it m或e like how a group of naval warships might have a 'configuration' f或 battle, 或 a 'configuration' f或 loading supplies. It's m或e about the 'shape', and it's not about controlling Gradle properties 或 actions.)
When Configurations are defined, they're also tagged with attributes, which Gradle will use to play matchmaker between the request f或 "kotest-runner-junit5" and what it discovers in the registered reposit或ies
在testImplementation("io.kotest:kotest-runner-junit5:5.4.2")
的情况下,Gradle可以看到testImplementation
具有"我需要一个JVM变量"的属性,它可以使用Maven Central中的模块元数据来查找匹配的依赖项.