Sbt 如何在自定义清理任务中排除文件?

Sbt 如何在自定义清理任务中排除文件?,sbt,Sbt,我正在开发一个自定义的TaskKey,它可以使干净,并在target目录中保留一个文件夹-这是一个我不想每次都填充的数据库 所以我试过这样的方法: lazy val cleanOutput = taskKey[Unit]("Prints 'Hello World'") cleanOutput := clean.value cleanKeepFiles in cleanOutput <+= target { target => target / "database" } 但以下工

我正在开发一个自定义的
TaskKey
,它可以使
干净
,并在
target
目录中保留一个文件夹-这是一个我不想每次都填充的数据库

所以我试过这样的方法:

lazy val cleanOutput = taskKey[Unit]("Prints 'Hello World'")

cleanOutput := clean.value

cleanKeepFiles in cleanOutput <+= target { target => target / "database" }
但以下工作:

cleanKeepFiles <+= target { target => target / "database" }
cleankepfiles目标/“数据库”}
为什么会有差异?

有些键可能在不同的范围(项目、配置或任务)中定义了值

可以定义键,即使它未在任何范围内使用,也可以在任何范围内为键指定值。后者并不意味着该值将由特定任务使用。这意味着您可以重用sbt声明的密钥

您需要声明一个新的
taskKey
。您可以将任务定义为调用
clean
。然后在新任务的范围内定义
cleanKeepFiles
,使其等于之前的值加上目标中的数据库目录

该值设置正确,但
clean
任务不会在任务范围内查找该值

您可以通过以下方式进行验证:

> show cleanOutput::cleanKeepFiles  
[info] List(/home/lpiepiora/Desktop/sbt/stack-overflow/q-24020437/target/.history, /home/lpiepiora/Desktop/sbt/stack-overflow/q-24020437/target/database)
此外,您还可以检查:

> inspect *:cleanKeepFiles
[info] Setting: scala.collection.Seq[java.io.File] = List(/home/lpiepiora/Desktop/sbt/stack-overflow/q-24020437/target/.history)
[info] Description:
[info]  Files to keep during a clean.
[info] Provided by:
[info]  {file:/home/lpiepiora/Desktop/sbt/stack-overflow/q-24020437/}q-24020437/*:cleanKeepFiles
[info] Defined at:
[info]  (sbt.Defaults) Defaults.scala:278
[info] Dependencies:
[info]  *:history
[info] Reverse dependencies:
[info]  *:clean
[info] Delegates:
[info]  *:cleanKeepFiles
[info]  {.}/*:cleanKeepFiles
[info]  */*:cleanKeepFiles
[info] Related:
[info]  *:cleanOutput::cleanKeepFiles
您还可以看到,sbt知道,您已经在范围
*:cleanOutput::cleanKeepFiles
中设置了它,它只是没有使用它

它会在哪里找到它?。您可以通过检查
clean
任务来检查它

> inspect clean
[info] Task: Unit
[info] Description:
[info]  Deletes files produced by the build, such as generated sources, compiled classes, and task caches.
// next lines are important
[info] Dependencies:
[info]  *:cleanKeepFiles
[info]  *:cleanFiles
您可以看到其中一个依赖项是
*:cleanKeepFiles
*
表示全局配置。这意味着
clean
任务将在该范围内查找设置。您可以将设置更改为:

cleanKeepFiles += target.value / "database"
这将把它设置在
clean
任务使用的正确范围内

> inspect clean
[info] Task: Unit
[info] Description:
[info]  Deletes files produced by the build, such as generated sources, compiled classes, and task caches.
// next lines are important
[info] Dependencies:
[info]  *:cleanKeepFiles
[info]  *:cleanFiles
编辑 有一个可以重用的函数。有鉴于此,您可以这样定义清理任务:

val cleanKeepDb = taskKey[Unit]("Cleans folders keeping database")

cleanKeepDb := Defaults.doClean(cleanFiles.value, (cleanKeepFiles in cleanKeepDb).value)

cleanKeepFiles in cleanKeepDb += target.value / "database"

很好的解释,但如果我这样做,我会修改
clean
的行为,我希望有一个自定义的clean,它忽略
数据库
文件夹,并保持当前的
clean
任务不变。我已经更新了我的答案,告诉你如何做。这比我做的要好得多。干杯@lpiepiora!