Gradle:用项目依赖替换模块依赖

时间:2014-08-07 11:07:55

标签: gradle

使用Gradle 1.12,是否可以创建一个解决策略规则,在某些情况下用项目替换模块依赖?

原因是我们公司有很多项目(数十个),我不想用以下内容污染构建脚本:

dependencies {
    elastic "company:somelib:1.0.+", "SomeLib"
}

相反,我希望实现以下目标:

dependencies {
    compile "company:somelib:1.0.+"
}

...

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        if (/* ... Check if project is in build ... */) {
            details.useTarget project(':SomeLib')
        }
    }
}

到目前为止,我还未能在解决方案策略规则中用项目1替换模块依赖项。有没有办法实现这个目标?


编辑:这些是我尝试的内容(都导致了错误):

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        if (/* ... Check if project is in build ... */) {
            details.useTarget project(':SomeLib')

            details.useTarget ':SomeLib'

            // Since I noticed this is how actual project dependencies look like
            details.useTarget 'Project:SomeLib:version'

            details.useTarget new DefaultProjectDependency(...)
        }
    }
}

为了将来参考,这是我最终使用的代码。这个例子实现了我们对这种期望行为的非常具体的味道,但是其他人可以将它作为起点并根据需要进行调整。

gradle.projectsEvaluated {
    def prjMap = [:]
    allprojects.each { prj ->
        prjMap[prj.archivesBaseName] = prj
    }

    allprojects.each { prj ->
        def replace = []

        prj.configurations.each { conf ->
            conf.dependencies.each { dep ->
                if (dep.group == 'company' && prjMap[dep.name] != null) {
                    replace += [conf: conf.name, dep: dep]
                }
            }
        }

        replace.each { rep ->
            println "Replacing:  $prj.name\t$rep.conf\t$rep.dep.name   ==>>   ${prjMap[rep.dep.name].name}"
            prj.configurations.all*.exclude(group: 'company', module: rep.dep.name)
            rep.dep.properties.excludeRules.each { ex ->
                prj.configurations.all*.exclude(group: ex.group, module: ex.module)
            }
            prj.dependencies.add(rep.conf, prjMap[rep.dep.name])
        }
    }
}

请注意,在替换时,我使用了激进的排除语句。这是因为我们有一个地狱依赖的地狱般的噩梦和lib项目将整个应用程序声明为传递dep,因为它们需要一些价值类。在一个更理智的环境中,可以简单地消除之前的依赖项,如下所示:

replace.each { rep ->
    println "Replacing:  $prj.name\t$rep.conf\t$rep.dep.name   ==>>   ${prjMap[rep.dep.name].name}"
    prj.dependencies.remove(rep.dep)
    prj.dependencies.add(rep.conf, prjMap[rep.dep.name])
}

1 个答案:

答案 0 :(得分:1)

不,决议策略不能这样做。有可能实现一种解决方案,该解决方案在配置阶段结束时迭代配置'依赖项并用项目依赖项替换某些外部依赖项。但是不确定是否可以在不使用Gradle内部的情况下完成。