为什么在执行clean后sbt每次都要运行依赖项解析?

25

即使项目依赖管理配置没有更改,SBT在每次执行clean后都会运行依赖项解决方案。当在CI服务器上运行时,这需要耗费时间。

但是文档说:

  1. 通常情况下,如果自上次成功解析以来未更改依赖项管理配置且检索的文件仍然存在,则sbt不会要求Ivy执行解析。

我该如何停止使用sbt clean publish-local构建项目时,sbt每次都进行依赖项解决方案?

更新

我发现当我进入交互模式sbt时,sbt也会运行解决方案。

更新2

正如@Ezhik所指出的那样,如果我可以保留target/resolution-cache,则sbt将不会在清理后解决依赖关系。因此,我尝试将resolution-cache移出目标目录:

ivyConfiguration <<= (externalResolvers, ivyPaths, offline, checksums, appConfiguration, target, streams) map { (rs, paths, off, check, app, t, s) =>
        val resCacheDir = t / ".." / "resolution-cache"
        new InlineIvyConfiguration(paths, rs, Nil, Nil, off, Option(lock(app)), check, Some(resCacheDir), s.log)
      }

现在,在Build.scala中,解决方案缓存被放置在项目根目录中,因此即使在执行clean命令后也会得到保留,但还是会进行解决方案的处理。因此我认为这种方法是错误或不足够的。

4个回答

9

由于目录target/resolution-cache中包含了Ivy报告。显然在执行clean操作时,您需要删除所有target内容。

在我看来,如果您想保留解析状态,您必须将其指向项目以外的某个位置。

已更新。

与SBT.0.12.4.RC1相比。

  1. Find where resolution-cache is used - in IvyConfiguration
  2. Inspect where IvyConfiguration located - in project scope

    > inspect ivy-configuration
    [info] Task: sbt.IvyConfiguration
    [info] Description:
    [info]  General dependency management (Ivy) settings, such as the resolvers and paths to use.
    [info] Provided by:
    [info]  {file:/home/ezh/projects/sbt/}xsbt/*:ivy-configuration
    [info] Dependencies:
    [info]  xsbt/*:offline
    
  3. Fix it in build.sbt.

    ivyConfiguration <<= (ivyConfiguration, baseDirectory) map {
      case (c: InlineIvyConfiguration, b) => import c._
        new InlineIvyConfiguration(paths, resolvers, otherResolvers, moduleConfigurations,
         localOnly, lock, checksums, resolutionCacheDir.map(_ => b / "123"), log)
      case (other, _) => other // something unknown
    }
    

4个测试...哎呀...解决方案仍然有效...调查一下。 ->

target/scala-2.10/cache/default-920e5d/global/update/output缓存包含指向resolution-cache的指针 :)

  1. Fix it.

    cacheDirectory <<= baseDirectory / "234"
    

测试。明白了。分辨率被跳过。

所需配置的摘要更改:

ivyConfiguration <<= (ivyConfiguration, baseDirectory) map {
  case (c: InlineIvyConfiguration, b) => import c._
    new InlineIvyConfiguration(paths, resolvers, otherResolvers, moduleConfigurations,
     localOnly, lock, checksums, resolutionCacheDir.map(_ => b / "123"), log)
  case (other, _) => other // something unknown
}
cacheDirectory <<= baseDirectory / "234"

与SBT 0.13.x相比

@deprecated("Use the cacheDirectory provided by streams.", "0.13.0")

https://github.com/sbt/sbt/issues/1208


1
用你自己的双手?SBT非常表达性。好的,特别为了你 :))) 以及对于我来说是个有趣的案例。 - Ezhik
3
+1,@Ezhik 的回答很棒。不幸的是,这个解决方案在 sbt 0.13 版本中不起作用。 cacheDirectory 已被弃用(就依赖解析的解决方法而言,cacheDirectory 已被有效地删除)。我尚未找到可行的解决方案,让 sbt 在每次 clean/compile 中都检查更新非常令人沮丧。 - virtualeyes
1
@virtualeyes:解决0.13.x的工作方案有什么进展吗? - Erik Kaplun

6
这对我来说在0.13.1上有效。
cleanKeepFiles ++= Seq("resolution-cache", "streams").map(target.value / _)

在我的0.13.2版本中可以工作,你需要将该行代码添加到所有子项目中。 - sam

6
也许您有SNAPSHOT依赖项。它们随时可能会发生变化,因此必须在每次运行时解决。您可以使用以下方法来抑制这种情况:
    offline := true

我知道快照。但这不是这种情况。Sbt会运行所有可用依赖项的解析。 - Oleksandr.Bezhan
对不起,我应该在哪里应用这行代码 build.sbt?您能提供一些上下文吗? - khebbie
@khebbie 在你的sbt命令行(REPL)中运行set offline := true,或者使用sbt "set offline := true" run来运行sbt。理论上,您也可以将其添加到build.sbt中,但这样您就必须始终编辑您的构建文件以切换离线模式。 - stefan.schwetschke

5
你可以通过这个设置来防止clean删除某些文件:
// path should be adapted for newer sbt versions
cleanKeepFiles <+= cacheDirectory / "update"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接