在SBT 0.13中,scalaVersion是否仍然控制用于编译,运行和测试的scala版本?

jtp*_*jtp 8 scala sbt

当我们将构建从12.4升级到13.1时,我观察到虽然指定了构建scalaVersion := "2.10.2",但是生成的存档(通过sbt-pack插件创建)包含scala-library-2.10.3.jar.快速检查确认12.4版本包含scala-library-2.10.2.jar.

似乎sbt 0.13包含一个将scala库视为正常依赖关系的更改,其结果是如果项目依赖项是使用稍后的2.10.x版本的scala构建的,则该传递依赖关系将"赢得"常春藤依赖项解析冲突解决方案,编译,测试和运行类路径将包含更高版本的scala库.

这是期望的行为,还是sbt 0.13中的错误?

如果是所需的行为,那么这是否意味着我必须使用机制来"强制/覆盖"冲突解决方案以使用我想要的scala库版本?(如果是这样,scalaVersion配置设置似乎有点无意义....)

这是一个非常极小的测试用例来说明行为:

test-proj/
  build.sbt
  project/
    build.properties
Run Code Online (Sandbox Code Playgroud)

build.sbt:

scalaVersion := "2.10.2"
//scalaVersion := "2.10.3"

libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.3.0"
//libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.2.4"
Run Code Online (Sandbox Code Playgroud)

build.properties:

sbt.version=0.13.1
Run Code Online (Sandbox Code Playgroud)

Akka 2.2.4是针对scala 2.10.2构建的,因此启动sbt并运行"update","show update","show compile:dependencyClasspath","show test:dependencyClasspath"和"show runtime:dependencyClasspath"都显示scala -library 2.10.2在类路径上.

切换到针对scala 2.10.3构建的Akka 2.3.0,导致scala-library 2.10.3出现在所有类路径上,"show update"清楚地显示2.10.2被Ivy的冲突解决方案驱逐.

有趣的是(并且不一致),在两种情况下(通过sbt控制台命令)输入REPL会导致使用scala 2.10.2.

根据文件,在0.13

scalaVersion配置用于编译的Scala版本.默认情况下,sbt还会在此版本的Scala库中添加依赖项.

基于此,我希望上面的编译类路径在两种情况下都包含2.10.2.

但是,0.13的发布说明

Scala依赖项(如scala-library和scala-compiler)现在可以通过常规更新任务解决

这至少解释了观察到的行为.

Eug*_*ota 8

sbt 0.13.0更改

你写了:

似乎sbt 0.13包含一个将scala库视为正常依赖关系的更改,其结果是如果项目依赖项是使用稍后的2.10.x版本的scala构建的,则该传递依赖关系将"赢得"常春藤依赖项解析冲突解决方案,编译,测试和运行类路径将包含更高版本的scala库.

sbt 0.13.0这个问题的变化有点矛盾.功能,修复,兼容性影响的更改部分说:

  • sbt不再覆盖依赖项中的Scala版本.这允许独立配置依赖于不同的Scala版本,并将scala-library之外的 Scala依赖视为普通依赖项.但是,对于其他Scala库,它可能会导致除scalaVersion之外的已解析版本.

解决Scala依赖项部分说:

Scala依赖项(如scala-library和scala-compiler)现在可以通过正常update任务解决.

(由Eugene强调)所以快速回答你的"这是期望的行为,还是0.13中的错误?" 正如你已经回答的那样:在sbt 0.13.x中,这种行为似乎是有意的.Akka 2.3.0依赖于scala-library 2.10.3,而Ivy已经驱逐了scala-library 2.10.2而支持2.10.3.

dependencyOverrides

要解决此问题,您可以使用dependencyOverrides如下设置:

dependencyOverrides += "org.scala-lang" % "scala-library" % scalaVersion.value
Run Code Online (Sandbox Code Playgroud)

之前:

sbt-so-22551430> show fullClasspath
[info] List(... Attributed(/Users/xxx/.sbt/0.13/boot/scala-2.10.3/lib/scala-library.jar) ...)
Run Code Online (Sandbox Code Playgroud)

后:

sbt-so-22551430> show fullClasspath
[info] List(... Attributed(/Users/xxx/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.10.2.jar) ...)
Run Code Online (Sandbox Code Playgroud)

这种行为是否可取?

你的问题不是这是否符合设计要求,而是否是可取的.我认为当前的行为是相当令人惊讶的,并且sbt应该至少改进通知构建用户这种行为.并且可能将其默认的Ivy冲突管理策略更改force()为指定的版本scalaVersion.以下是我创建的两个GitHub问题: