1

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

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

假设m3使用m2m2使用m1m1 <- m2 <- m3 )

的存在m2是可选的 具有以下布局的多项目也合理

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

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

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

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

编辑:

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

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

4

2 回答 2

2

elastic-deps开始,在这个答案的帮助下(也来自Peter),我想出了下面的技巧。

在顶层 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不同,您不必修改子项目。

这仍然存在一个问题,一旦您遇到二进制依赖项,任何纯粹的传递依赖项都会被解析为二进制。例如,假设我有一个项目cyan,它直接依赖于greenblue传递地,通过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

现在,如果我将blueand添加yellow到我的多模块项目中,但不是green,我得到:

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不是。

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

于 2014-05-09T22:28:26.073 回答
1

使用 Gradle 构建的动态子集是一项计划功能。与此同时,我想出的最佳解决方案是引入一种新的依赖表示法,它可以动态映射到项目依赖项或外部依赖项。您可以在此处找到概念验证:https ://github.com/pniederw/elastic-deps

PS:在开始自己实现此功能之前,请重新考虑此时是否真的需要它。等到它得到官方支持,你可能会省去一些麻烦。

于 2014-01-20T17:30:49.670 回答