Gradle 多项目可选子项目的传递依赖应解析为现有子项目 [英] Gradle multiproject optional subproject's transitive dependency should be resolved to an existing subproject

查看:21
本文介绍了Gradle 多项目可选子项目的传递依赖应解析为现有子项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设以下项目.主项目是一个多项目,但较大项目的每个部分都可以单独开发或混合开发:

suppose the following project. the master project is a multi-project, however every part of the larger project can be developed individually or mixed in:

/master/build.gradle
/m1/build.gradle
/m2/build.gradle
/m3/build.gradle

假设 m3 使用 m2 并且 m2 使用 m1 ( m1 <- m2 - m3)

suppose m3 uses m2 and m2 uses m1 ( m1 <- m2 <- m3 )

m2 的存在是可选的,多项目采用以下布局也是合理的

the presence of m2 is optional a multi-project with the following layout also reasonable

/master/build.gradle
/m1/build.gradle
/m3/build.gradle

但在这种情况下 m2 将从工件存储库中提取,这很好......但是 m1m2 这很好,但是我如何告诉 gradle 使用本地版本的 m1 而不是烘焙的工件?

but in this case m2 would be pulled in from the artifact repository which is fine...however m1 was a transitive dependency of m2 which is good, but how can i tell gradle to use the local version of m1 instead of the baked artifact?

我坚持这一点,我有权覆盖这些东西的每个地方 gradle 都给了我只是" ModuleVersionSelector 级别的访问权限,我该如何添加 DefaultProjectDependency 根据到下载的工件传递依赖项?

I'm stuck with this, every place i have access to override these thing gradle gives me "just" ModuleVersionSelector level access, how can i add a DefaultProjectDependency according to the downloaded artifact transitive dependencies?

如果我可以访问存档工件的完整依赖关系图并放入一些覆盖/排除项,我可能会有替代方案.

i may have an alternative if i can access the full dependency graph of the archived artifacts, and put in some overrides/excludes.

我想出的最好的方法是使用使用 resolutionStrategy 的过滤器,我通过进一步开发elastic-deps"项目创建了一个示例

the best i've come up with is using a filter using resolutionStrategy, i've created an example by further developing the 'elastic-deps' project

https://github.com/kgyrtkirk/elastic-deps

推荐答案

elastic-deps开始 并在 this answer 的帮助下(也来自 Peter) 我想出了下面的窍门.

Starting with elastic-deps and with the help of this answer (also from Peter) I came up with the trick below.

在顶层build.gradle()中:

In the top-level build.gradle():

// make sure we've parsed the subproject dependencies
evaluationDependsOnChildren()

def subprojectsByName = subprojects.collectEntries { it -> [it.name, it] }

subprojects.each { p ->
  def hacks = [] // list of changes we're going to make
  p.configurations.each { c ->
    c.dependencies.each { d ->
      if (d.group.startsWith("my.group.prefix")) {
        def sub = subprojectsByName[d.name]
        if (sub != null) {
          hacks.add({
            // can't do this immediately or we'll get ConcurrentModificationExceptions
            c.dependencies.remove(d)
            p.dependencies.add(c.name, sub)
          })
        }
      }
    }
  }
  // Now we can safely apply the changes
  for (hack in hacks) {
    hack()
  }
}

这样做的好处是,与 elastic-deps 不同,您不必修改子项目.

The nice thing about this is that unlike elastic-deps you don't have to modify the subprojects.

这仍然存在一个问题,即一旦遇到二进制依赖项,任何纯传递依赖项都会被解析为二进制.例如,假设我有一个项目 cyan 直接依赖于 greenblue 并通过 green 传递,黄色:

This still has the problem that once you hit a binary dependency, any purely transitive dependencies are resolved as binary. E.g., say I have a project cyan which depends directly on green and blue and transitively, through green, on yellow:

compile - Compile classpath for source set 'main'.
+--- my.shared:blue:+ -> 2.0-SNAPSHOT
+--- my.shared:green:+ -> 2.0-SNAPSHOT
|    +--- my.shared:yellow:+ -> 2.0-SNAPSHOT
|    --- my.shared:blue:+ -> 2.0-SNAPSHOT

现在,如果我将 blueyellow 添加到我的多模块项目中,而不是 green,我会得到:

Now if I add blue and yellow to my multi-module project, but not green, I get:

compile - Compile classpath for source set 'main'.
+--- com.iii.shared:green:+ -> 2.0-SNAPSHOT
|    +--- com.iii.shared:yellow:+ -> 2.0-SNAPSHOT
|    --- com.iii.shared:blue:+ -> project :blue
--- project :blue

请注意,即使是可传递的,blue 也可以正确解析为项目,但 yellow 不是.

Note that blue is resolved correctly to the project even when it's transitive, but yellow isn't.

我个人认为这是一个特性,而不是错误——它反映了分发时实际发生的情况.我可以对 yellow 进行所有我想要的更改,但如果我没有在我的存储库中放置新的 yellow 工件以及更新的 green 使用更新的依赖项,那么 cyan 的实际版本将不会获得这些更改.

Personally I think this is a feature, not a bug -- it reflects what would actually happen at distribution time. I can make all the changes to yellow I want, but if I don't put a new yellow artifact in my repository and also an updated green with the updated dependency, then the actual release of cyan isn't going to get those changes.

这篇关于Gradle 多项目可选子项目的传递依赖应解析为现有子项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆