我想要一个 sbt 任务,我可以运行它来生成一些代码。我不想在每次运行时都生成这个,只是偶尔手动运行一次这个任务。我创建了一个骨架项目来解释(https://github.com/jinyk/sbtmanagedsrc)。
构建.sbt:
lazy val root = (project in file("."))
.settings(scalaVersion := "2.11.8")
.settings(gensomecode := genSomeCodeTask.value)
/////////////////////////////////////////////////////////////
// fugly way to get managed sources compiled along with main
.settings(unmanagedSourceDirectories in Compile += baseDirectory.value / "target/scala-2.11/src_managed/")
/////////////////////////////////////////////////////////////
lazy val gensomecode = taskKey[Seq[File]]("gen-code")
lazy val genSomeCodeTask = Def.task {
val file = (sourceManaged in Compile).value / "SomeGenCode.scala"
println("file: " + file)
IO.write(file, """object SomeGenCode {
| def doSomething() {
| println("Hi!")
| }
|}""".stripMargin)
Seq(file)
}
Run Code Online (Sandbox Code Playgroud)
因此,使用上面的 build.sbt,我可以运行sbt gensomecode
它创建
target/scala-2.11/src_managed/main/SomeGenCode.scala
sbt 放置“托管源”的默认位置。
我想让它SomeGenCode
可用于根项目。
src/main/scala/Main.scala:
object Main extends App {
SomeGenCode.doSomething()
}
Run Code Online (Sandbox Code Playgroud)
我唯一能想到的就是sourceManaged
在根项目中包含默认目录unmanagedSourceDirectories
(参见注释build.sbt:line 4
下方的行fugly way...
)。这太丑了,看起来不像是应该如何处理托管源。
我可能不了解有关 sbt 的托管源概念或如何处理创建 sbt 任务以生成源的情况的基本知识。
我错过了什么?
有我熟悉的三个选项:
生成到非托管源目录中。
通过添加在每次运行时生成sourceGenerators in Compile <+= gensomecode
与 (2) 类似,但使用缓存,这样就不会在每次编译时生成文件。完整示例如下。
在此示例中,缓存基于 的内容build.sbt
,因此每当该文件发生更改时,它都会重新生成该文件。
lazy val root = (project in file("."))
.settings(scalaVersion := "2.11.8")
.settings(gensomecode <<= genSomeCodeTask)
sourceGenerators in Compile <+= genSomeCodeTask
lazy val gensomecode = taskKey[Seq[File]]("gen-code")
def generateFile(sourceManaged: java.io.File) = {
val file = sourceManaged / "main" / "SomeGenCode.scala"
println("file: " + file)
IO.write(file, """object SomeGenCode {
| def doSomething() {
| println("Hi!")
| }
|}""".stripMargin)
Set(file)
}
def genSomeCodeTask = (sourceManaged in Compile, streams).map {
(sourceManaged, streams) =>
val cachedCompile = FileFunction.cached(
streams.cacheDirectory / "mything",
inStyle = FilesInfo.lastModified,
outStyle = FilesInfo.exists) {
(in: Set[java.io.File]) =>
generateFile(sourceManaged)
}
cachedCompile(Set(file("build.sbt"))).toSeq
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2337 次 |
最近记录: |