如何在不修改settings.gradle的情况下添加gradle项目依赖项

时间:2018-05-04 23:00:36

标签: gradle dependencies build.gradle gradle-plugin

背景

(请记住,为了讨论的目的,我已经简化了问题)

  • 我有一组应用程序和依赖库,类似这样(每个都有一个src/目录和build.gradle):

    appa/
    appb/
    libx/
    liby/
    libz/
    
  • build.gradle中,依赖关系当前声明如下:

    appa/build.gradle:
       compile "com.asdf:libx:1.0"
       compile "com.asdf:liby:1.0"
    appb/build.gradle:
       compile "com.asdf:liby:1.0"
    liby/build.gradle:
       compile "com.asdf:libz:1.0"
    

我想解决什么问题

  • 说我正在appa工作,我需要对libx进行更改。我需要做多个步骤:
    1. 从源代码管理中提取libx并在本地进行更改
    2. 重建并推送更改到某些仓库(不是产品!)
    3. 重建appa(从repo中提取最近更新的libx
  • 如果我的测试显示libx中的错误,我必须重复这一点。
  • 在像Eclipse这样的IDE中工作时,这非常烦人,即使我的项目在逻辑上使用其他项目,我仍然必须使用工件作为依赖项。
  • 如果我可以在本地拉出项目,那会不会很好,而逻辑上依赖它的项目会自动使用源项目而不是工件进行构建?

到目前为止我做了什么

  • 我已经编写了一个小gradle插件(在每个项目build.gradle中引用),用于标识com.asdf个依赖关系,并使用dependency substitution替换具有项目依赖性的工件依赖项,如果该项目存在于本地。

    configurations.all {
        resolutionStrategy.dependencySubstitution {
            all { DependencySubstitution dependency ->
                if (dependency.requested instanceof ModuleComponentSelector && dependency.requested.group == 'com.asdf') {
                    def targetProject = findProject(":${dependency.requested.module}")
                    if (targetProject != null) {
                        dependency.useTarget targetProject
                    }
                }
            }
        }
    }
    
  • 耶!通过对settings.gradle的一些修改(见下文),我完成了我的目标......除了......

我被困的地方

  • 我需要修改settings.gradle以便为每个依赖项包含这样的行(否则findProject在构建期间不解析依赖项目):

    include ':libx'
    project(':libx').projectDir = new File(settingsDir, '../libx')
    
  • 虽然可能通过所有settings.gradle个文件并执行此操作(我已经完成了一些文件,因为我的证明了-concept),它是丑陋的,重复的,并且在逻辑上是传递给compile依赖项的build.gradle参数的相同信息。

    • 当有人添加新的依赖关系但没有更新settings.gradle或在它们之间引入拼写错误时,它也容易出错。
  • 我还尝试让settings.gradle只为它在该级别找到的所有目录定义项目,但随后构建任何项目将变成所有项目的大型构建。
  • (我已经尝试了其他一些事情,但我的问题已经很久了)

我的问题

settings.gradlebuild.gradle之间没有重复信息的情况下,更好的方法是什么?我想这样做,所以添加新的依赖项仍然像在compile中添加build.gradle引用一样简单,而不会触及settings.gradle ...

我仍然很喜欢groovy / gradle,所以也许我错过了对经验丰富的gradle主人来说显而易见的东西?

1 个答案:

答案 0 :(得分:1)

我相信你的用例是Composite Builds的动机。

我有一个演示here,它写入jars文件夹作为工件的模拟发布。请务必查看README.md,因为该演示是一个小型实验室,用于在复合构建之前和之后尝试用例。

在演示mainBuildappa; utilslibxmainBuild/settings.gradlehere)中的关键语法是:

includeBuild '../utils'

这告诉Gradle使用本地代码库而不是已发布的工件。当然,人们不会将这一行提交给源代码控制。