Gradle:有没有办法在可传递依赖项中禁止版本范围?

Gradle:有没有办法在可传递依赖项中禁止版本范围?,gradle,Gradle,当我在Gradle配置中声明了快照存储库时,是否有方法防止版本范围从解析到快照版本的可传递依赖关系?或者,我可以完全禁止可传递依赖中的版本范围吗?例如,考虑这个非常简单的分级项目: 存储库{ mavenCentral() 马文{ url'https://oss.sonatype.org/content/repositories/snapshots/' } } 应用插件:“java” 依赖关系{ 编译“org.reactfx:reactfx:1.4” 编译“org.fxmisc.undo:undo

当我在Gradle配置中声明了快照存储库时,是否有方法防止版本范围从解析到快照版本的可传递依赖关系?或者,我可以完全禁止可传递依赖中的版本范围吗?例如,考虑这个非常简单的分级项目:

存储库{
mavenCentral()
马文{
url'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
应用插件:“java”
依赖关系{
编译“org.reactfx:reactfx:1.4”
编译“org.fxmisc.undo:undofx:1.0.1”
}
这将导致版本冲突和解决方案,因为
undofx
依赖于
reactfx
,版本为
[1.4,1.5)
(可用的最新1.4.x版本)。以下是
reactfx
的依赖性细节:

gradlew dependencyInsight——dependency reactfx
org.reactfx:reactfx:1.4.1-SNAPSHOT(冲突解决)
org.reactfx:reactfx:1.4->1.4.1-SNAPSHOT
\---编撰
org.reactfx:reactfx:[1.4,1.5)->1.4.1-SNAPSHOT
\---org.fxmisc.undo:undofx:1.0.1
\---编撰
Maven还将
reactfx:1.4.1-SNAPSHOT
解析为
undofx
的依赖项。然而,一旦
reactfx
依赖项添加到项目中,Maven似乎会使用我声明为一级依赖项的版本来解决冲突。下面是我用来测试它的Maven POM:


4.0.0
例子
例子
1.0-快照
马文中心酒店
http://repo1.maven.org/maven2
oss快照
https://oss.sonatype.org/content/repositories/snapshots/
真的
org.fxmisc.undo
undofx
1.0.1
org.reactfx
reactfx
1.4
这也是我对Gradle期望的解决行为,但只是基于假设。我认为如果
undofx
允许任何
1.4.x
版本的
reactfx
,并且唯一其他声明版本的
reactfx
在该范围内,那么冲突将通过使用我声明的版本来解决

但是,如果任何可传递的依赖项使用范围内的版本,我对冲突解决的兴趣不如对构建失败的兴趣。我更喜欢识别这些依赖项并将它们设置为特定版本。如果我没有创建上述冲突,我想我不会注意到这一个使用版本范围

使用版本范围识别和处理可传递依赖关系的最简单方法是什么

更新 根据Peter的回答,下面是我用来完成此操作的代码的完整列表。请注意,它使用的是Gradle API中标记为
@Incubating
的功能

import org.gradle.api.artifacts.component.ModuleComponentSelector
if(!project.plugins.hasPlugin(JavaPlugin)){
应用插件:“java”
}
存储库{
mavenCentral()
马文{
url'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
依赖关系{
编译“org.fxmisc.undo:undofx:1.0.1”//取决于reactfx:[1.4,1.5)
}
配置{
//无检查功能检查
全部{
/*
解决所有配置中的依赖项后,请检查
已解析的所有模块(非项目)组件的版本
成功。将跳过已使用强制版本的模块。
*/
incoming.afterResolve{//ResolvableDependencies
it.resolutionResult.allDependencies{//DependencyResult
如果(它是ResolvedPendencyResult的实例
&&it.requested instanceof ModuleComponentSelector){
如果(!it.selected.selectionReason.forced){
检查版本((ModuleComponentSelector)it.requested)
}
}
}
}
}
}
/**
*检查所请求模块的版本,如果不正确,则引发和异常
*使用版本范围。
*
*@param请求模块组件进行检查。
*/
无效检查版本(请求ModuleComponentSelector){
def版本=请求的版本
if(version.endsWith(“)”)
||版本。等于(“最新”)
||版本。等于(“发布”)){
抛出新的梯度异常(
“${requested}使用版本范围。请尝试强制。”)
}
}

您可以使用
configuration.getIncoming()
API来比较声明的版本和解析的版本(例如,在
configuration.getIncoming().afterResolve()
hook中),如果它们不相同,则会失败。获取“声明的版本”的Maven冲突解决行为(而不是Gradle的“最高版本赢”),您可以使用
configuration.getResolutionStrategy().force()
API。要强制明确解决每个版本冲突(使用
force()
),请使用
configuration.getResolutionStrategy().failOnVersionConflict()
。有关API的详细信息,请参阅。

我使用基于该API的解决方案更新了问题。感谢您为我指明了正确的方向。