sbt多项目构建场景下如何获取其他项目的setting配置值
sbt多项目跨项目获取配置的解决方案
错误原因
你遇到的IllegalArgumentException是sbt的任务宏解析限制导致的:Def.task 闭包内不支持在动态遍历得到的变量(如你代码中flatMap循环里的projectRef)上直接调用.value。sbt需要在项目加载阶段就确定所有任务的依赖关系,动态生成的ProjectRef对应的.value调用无法被宏正确识别代理,因此抛出异常。
解决方案
使用sbt提供的Def.taskDyn(动态任务)即可解决该问题,它支持动态生成任务依赖,绕开普通任务的宏解析限制。针对你要获取当前子项目依赖的其他项目的libraryDependencies的需求,实现代码如下:
import sbt._ import Keys._ val hierarchyDeps = taskKey[Seq[ModuleID]]("查看当前子项目依赖的其他项目的libraryDependencies") val hierarchyDepsImpl = Def.taskDyn { // 获取当前项目的所有直接依赖项目 val directDeps = buildDependencies.value.classpath(thisProjectRef.value).map(_.project) // 为每个依赖项目生成获取libraryDependencies的任务 val depTasks = directDeps.map(projRef => (projRef / libraryDependencies).get) // 合并所有依赖的配置结果返回 Def.task { depTasks.flatMap(_.value) } } val cmn = project.in(file("cmn")) val subA = project.in(file("sub_a")).dependsOn(cmn).settings(hierarchyDeps := hierarchyDepsImpl.value) val subB = project.in(file("sub_b")).dependsOn(cmn).settings(hierarchyDeps := hierarchyDepsImpl.value)
通用跨项目取配置方法
如果需要获取任意项目的任意setting值,只需要将上面代码中的libraryDependencies替换为对应的settingKey即可。如果需要递归获取依赖的依赖的配置,自行添加递归逻辑遍历buildDependencies返回的项目依赖树即可。
内容的提问来源于stack exchange,提问作者baloo325i
相关产品推荐
相关产品推荐

