本文介绍了如何缓存 sbt TaskKey 的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我需要在测试中参考一项昂贵的任务

I have an expensive task that I need to reference in my tests

lazy val exampleSources = TaskKey[Seq[File]]("exampleSources", "for use in tests")

exampleSources := (updateClassifiers in Test).value.select(
  artifact = artifactFilter(classifier = "sources")
)

(然后我可以将 exampleSources.value 作为参数传递给我的分叉测试)

(and then I can pass exampleSources.value as a parameter to my forked tests)

但是,每次我运行测试时,都会调用此任务,并且会调用updateClassifiers(昂贵的).但我很高兴在第一次调用时缓存该值,然后在会话中使用它.

However, every time I run a test, this task is called, and updateClassifiers (expensive) is called. But I'm happy caching the value on first call and then using that for the session.

不用自己写缓存,有没有办法使用内置的 sbt 对象来做到这一点?

Without writing the cache myself, is there any way to do this using built-in sbt objects?

更新:这不起作用.第二次评估具有 CACHE=true 但解析任务仍在运行.

UPDATE: this doesn't work. Second evaluation has CACHE=true but the resolution tasks still run.

lazy val infoForTests = TaskKey[Seq[String]]("infoForTests", "for use in tests")

val infoForTestsCache = collection.mutable.Buffer[String]()

infoForTests := {
  println("CACHE=" + infoForTestsCache.nonEmpty)
  if (infoForTestsCache.isEmpty) {
    infoForTestsCache ++= Seq[String](
      "-Densime.compile.jars=" + jars((fullClasspath in Compile).value),
      "-Densime.test.jars=" + jars((fullClasspath in Test).value),
      "-Densime.compile.classDirs=" + classDirs((fullClasspath in Compile).value),
      "-Densime.test.classDirs=" + classDirs((fullClasspath in Test).value),
      "-Dscala.version=" + scalaVersion.value,
      // sorry! this puts a source/javadoc dependency on running our tests
      "-Densime.jars.sources=" + (updateClassifiers in Test).value.select(
        artifact = artifactFilter(classifier = "sources")
      ).mkString(",")
    )
    println("CACHE=" + infoForTestsCache.nonEmpty)
  }
  infoForTestsCache
}

推荐答案

您可以使用 FileFunction.cached 缓存结果并执行仅在输入更改时工作.

You can use FileFunction.cached to cache the results and doing work only if input changes.

只是链接的 sbt 文档中的一个示例:

Just an example from linked sbt documentation:

// define a task that takes some inputs
//   and generates files in an output directory
myTask := {
    // wraps a function taskImpl in an uptodate check
    //   taskImpl takes the input files, the output directory,
    //   generates the output files and returns the set of generated files
    val cachedFun = FileFunction.cached(cacheDirectory.value / "my-task") { (in: Set[File]) =>
      taskImpl(in, target.value) : Set[File]
    }
    // Applies the cached function to the inputs files
    cachedFun(inputs.value)
}

您可能还想查看我对类似问题的回答:如何列出增量重新编译输出的文件.

You may also want to check my answer to a similar question : How to list files output by incremental recompilation.

这篇关于如何缓存 sbt TaskKey 的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 22:00