我们有一个大型多项目,我们使用sbt构建了许多模块。事实证明,我们有很多关于被包装的不需要的罐子的问题。作为解决问题的第一步,我们创建了一个全球地图"使用过的工件的定义如下:
project/Build.scala
:
type PartialFunction2[-T1,-T2,+R] = PartialFunction[Tuple2[T1,T2],R]
lazy val dependenciesManager = settingKey[PartialFunction2[String, String, ModuleID]]("a setting containing versions for dependencies. if we only use it to declare dependencies, we can avoid a lot of version collisions.")
root中的 build.sbt
:
dependenciesManager in Global := {
case ("ch.qos.logback","logback-classic") => "ch.qos.logback" % "logback-classic" % "1.1.1"
case ("com.typesafe","config") => "com.typesafe" % "config" % "1.2.0"
case ("com.typesafe","scalalogging-slf4j") => "com.typesafe" %% "scalalogging-slf4j" % "1.1.0"
case ("com.typesafe.akka",art) => "com.typesafe.akka" %% art % "2.2.4"
case ("com.typesafe.play", art) => "com.typesafe.play" %% art % "2.2.3"
...
}
这允许我们在任何模块中使用自己的build.sbt
文件,语法如下:
libraryDependencies <++= (dependenciesManager)(dm => Seq(
dm("com.typesafe.akka","akka-cluster"),
dm("com.typesafe.akka","akka-contrib"),
dm("com.typesafe.play","play"),
dm("ch.qos.logback","logback-classic")
))
没有提到依赖版本。 但是,由于传递依赖性仍然会导致问题,它只能解决部分问题。
所以我在想,如果,我可以以某种方式定义一个像上面那样的依赖关系图,sbt的解析机制会经历它&#34;通过它&#34;它可能会改变所要求的依赖性。
例如,让我们说logback
与slf4j-api
一起使用,我想要log4j
或{{1}的传递依赖要添加到类路径中,而是添加到commons-logging
之类的桥。像上面这样的地图可以解决这个问题。
另外,不会加载不同的版本。以及任何可能已更改其名称的工件(如jcl-over-slf4j
,现在称为google-collections
或guava
groupID已更改为org.jboss.netty
)赢得了&#39;是一个问题。
当然,只要给出的依赖关系不是所要求的依赖关系,就应该在屏幕上打印一个警告,并且每当添加新的依赖关系时,用户都应该手动将其添加到地图中并具有所有它的传递依赖关系。还没有(或者会引发匹配错误)
所以我的问题是,有可能实现这样的目标吗? 如果是这样,怎么样?
io.netty
任务或ivyReport
任务:根据我的理解,sbt会创建一个IvyReport xml文件,根据此文件,ivy会获取所请求的工件。我想以某种方式修改update任务或生成的报告,因此传递依赖关系将是我想要的,而不是最初提取的。update
标记为ModuleID
,但(以某种方式)获取其依赖关系,并且也可以获取它们(在映射到想要的工件之后)