首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >访问当前作用域下的SBT设置

访问当前作用域下的SBT设置
EN

Stack Overflow用户
提问于 2014-03-26 15:11:17
回答 2查看 1.5K关注 0票数 9

我很难理解sbt中的范围概念。我希望任务在特定范围下运行,并能够访问作用域设置,即

build.sbt

代码语言:javascript
复制
name := "Superapp"

name in Test := "Testapp"

val printScopedKey = TaskKey[Unit]("psk", "Print Scoped Key")

printScopedKey := println("***** [APP NAME] " + name.value)

我希望有以下几点:

代码语言:javascript
复制
> test:psk
> ***** [APP NAME] Testapp

而不是实际的:

代码语言:javascript
复制
> ***** [APP NAME] Superapp

我怎样才能在sbt做到这一点?这可能吗?

EN

回答 2

Stack Overflow用户

发布于 2014-03-29 21:41:05

OP写道:“我希望有以下几点:

代码语言:javascript
复制
> test:psk
> ***** [APP NAME] Testapp

在没有在psk配置中实际定义Test任务的情况下,sbt将首先在Global配置中查找psk任务,然后按照项目的configurations顺序(默认情况下为Seq(Compile, Runtime, Test, Provided, Optional) )查找psk任务。

下面(以及@Jacek的答案)描述了如何在不重复代码的情况下将任务定义为多个作用域。一个设置可以以三个轴(项目、配置和任务)为作用域。项目部分没有发挥那么大的作用,所以我们将在这里讨论配置和任务。

建议将特定于任务的设置范围限定为任务,以鼓励密钥的重用。例如:

代码语言:javascript
复制
test in assembly := {}

在上面的test中,键的作用域是assembly任务,以控制在创建胖JAR之前运行的测试。您可以定义一个“任务生成器”方法,该方法将获取一个键并在其周围创建一个设置图:

代码语言:javascript
复制
def assemblyTask(key: TaskKey[File]): Initialize[Task[File]] = Def.task {
  val t = (test in key).value
  val s = (streams in key).value
  Assembly((outputPath in key).value, (assemblyOption in key).value,
    (packageOptions in key).value, (assembledMappings in key).value,
    s.cacheDirectory, s.log)
}

我使用它来定义assemblypackageScalapackageDependency任务。

代码语言:javascript
复制
lazy val baseAssemblySettings: Seq[sbt.Def.Setting[_]] = Seq(
  assembly                   := Assembly.assemblyTask(assembly).value,
  packageScala               := Assembly.assemblyTask(packageScala).value,
  ....
)

到目前为止,baseAssemblySettings是配置中立的.

如果我想在像CompileTest这样的配置中查看它,我会这样调用inConfig(conf)(settings)

代码语言:javascript
复制
lazy val assemblySettings: Seq[sbt.Def.Setting[_]] =
  inConfig(Compile)(baseAssemblySettings) ++
  inConfig(Test)(baseAssemblySettings)

现在,您可以在多个配置中获得多个任务图。

票数 8
EN

Stack Overflow用户

发布于 2014-03-26 20:29:39

谢谢你的提问!我一开始以为我会知道答案,然后意识到这并不是那么简单。我不得不四处寻找解决方案。

我使用sbt 0.13.2-RC1

代码语言:javascript
复制
> about
[info] This is sbt 0.13.2-RC1
[info] The current project is {file:/C:/dev/sandbox/0.13.2/}root-0-13-2 0.1-SNAPSHOT
[info] The current project is built against Scala 2.11.0-RC3
[info] Available Plugins: org.sbtidea.SbtIdeaPlugin, de.johoop.jacoco4sbt.JacocoPlugin, com.timushev.sbt.updates.UpdatesPlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.3

我在Mark Harrah's response to a similar question on the sbt mailing list中找到的解决方案归结为build.sbt中的以下更改

代码语言:javascript
复制
scalaVersion := "2.11.0-RC3"

name := "Superapp"

name in Test := "Testapp"

name in Runtime := "Runtimeapp"

lazy val psk = taskKey[Unit]("Print Scoped Key")

val pskSetting = psk := println("***** [APP NAME] " + name.value)

// https://groups.google.com/d/msg/simple-build-tool/A87FFV4Sw4k/KPtygikQvogJ
val myPsks = Seq(Compile, Test, Runtime) flatMap { conf =>
  inConfig(conf)( Seq(pskSetting) )
}

myPsks

当加载构建文件时,sbt将自动知道,当您执行psk时,它的依赖项是name in Compile,而test:psk依赖于name in Test。相当聪明。

代码语言:javascript
复制
> psk
***** [APP NAME] Superapp
[success] Total time: 0 s, completed 2014-03-26 21:27:37
> test:psk
***** [APP NAME] Testapp
[success] Total time: 0 s, completed 2014-03-26 21:27:41
> runtime:psk
***** [APP NAME] Runtimeapp
[success] Total time: 0 s, completed 2014-03-26 21:27:44

使用inspect进行更深入的挖掘。了解它是如何工作的总是非常有用的(一旦您开始使用正确的工具(比如inspect),这并不难理解)。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22665235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档