SBT:将输入预先应用到 inputKeys

2023-11-25

在 SBT 中:我想定义一个 inputKey 来读取命令行参数,稍微更改它们并uses结果作为其他 inputKey 的输入。

I tried:

lazy val demo = inputKey[Unit]("A demo input task.")
lazy val root = (project in file(".")).settings(
  libraryDependencies += jUnitInterface
).settings(
  demo := {
    val args: Seq[String] = spaceDelimited("<arg>").parsed
    val one = (run in Compile).fullInput(args(0) + "foo").evaluated
  }
)

但我越来越error: Illegal dynamic reference: args.

我也尝试过:

demo := {
  val args: Seq[String] = spaceDelimited("<arg>").parsed
  System.setProperty("args0", args(0))
  val one = (run in Compile).fullInput(System.getProperty(args0) + "foo").evaluated
}

这根本不提供输入。我怀疑这是一个执行顺序的问题(属性在我想要的时候没有被设置,因为 JVM 可以自由地移动行)。

于是,在绝望中,我什至尝试了残酷的方法:

demo := {
  val args: Seq[String] = spaceDelimited("<arg>").parsed
  try {
    System.setProperty("args0", args(0))
  } finally {
    val one = (run in Compile).fullInput(System.getProperty(args0) + "foo").evaluated
  }
}

强制执行命令。这只会引发 NullPointerException。


正如丹尼尔·C·索布拉尔提到的,parsed and evaluated是宏,定义于InputWrapper.

由于它们是在编译时执行的,并且参数是在运行时检索的,因此它们不能很好地混合。特别是,args 的值仅在运行时真正定义,并且不能由evaluated macro.

EDIT: 与OP聊天后,我确定他的目标是写作的捷径 myTask Foo bar 代替 testOnly *Foo* -- --tests=*bar*,我相应地更新了我的答案。

更新答案

正如所讨论的,因为你基本上想要一个“宏”来编写myTask Foo bar代替testOnly *Foo* -- --tests=*bar*,这是我的解决方案:

val filtersParser = {
    import complete.DefaultParsers._
    (token(Space) ~> token(StringBasic, "<classFilter>")) ~
        (token(Space) ~> token(StringBasic, "<methodFilter>"))
}

lazy val testFiltered = inputKey[Unit]("runs test methods matching *<methodFilter>* within classes matching *<classFilter>*")

testFiltered.in(Test) := Def.inputTaskDyn {
    val (classFilter, methodFilter) = filtersParser.parsed
    runTestsFiltered(classFilter, methodFilter)
}.evaluated

def runTestsFiltered(classFilter: String, methodFilter: String) = Def.taskDyn {
    (testOnly in Test).toTask(s" *$classFilter* -- --tests *$methodFilter*")
}

更详细

您需要一个自定义解析器来检索您期望的两个参数。这是通过以下代码实现的,该代码基本上定义了两个组,“咀嚼”两个空格而不记住它们,以及两个StringBasic参数,它们是解析器的结果(filtersParser属于类型Parser[(String, String)])

val filtersParser = {
    import complete.DefaultParsers._
    (token(Space) ~> token(StringBasic, "<classFilter>")) ~
        (token(Space) ~> token(StringBasic, "<methodFilter>"))
}

然后,您需要一个输入任务来使用解析器的结果并将其转发到测试框架。 这是在下一个片段中完成的(如果比我更有知识的人希望插话使用inputTaskDyn,我很乐意受到启发:))。请注意任务范围的定义.in(Test)它授予对测试依赖项的访问权限。

lazy val testFiltered = inputKey[Unit]("runs test methods matching *<methodFilter>* within classes matching *<classFilter>*")

testFiltered.in(Test) := Def.inputTaskDyn {
    val (classFilter, methodFilter) = filtersParser.parsed
    runTestsFiltered(classFilter, methodFilter)
}.evaluated

最后一段代码只是将参数转发给预先存在的testOnly task:

def runTestsFiltered(classFilter: String, methodFilter: String) = Def.taskDyn {
    (testOnly in Test).toTask(s" *$classFilter* -- --tests *$methodFilter*")
}

之前的回答

但是,您应该能够通过将定义和用法分为两个任务来解决这个问题:

import sbt._
import complete.DefaultParsers._

lazy val loadArgTask = inputKey[Unit]("loads and transforms argument")

lazy val runStuff = taskKey[Unit]("Runs some stuff")

lazy val loadArgIntoPropertyTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
    val myArg = (token(Space) ~> token(StringBasic, "<myArg>")).parsed
    System.setProperty("myArg", myArg + "foo")
}

loadArgTask <<= loadArgIntoPropertyTask

runStuff := {
    println(System.getProperty("myArg"))
}

可以如下使用

> loadArgTask orange
[success] Total time: 0 s, completed [...]
> runStuff
orangefoo
[success] Total time: 0 s, completed [...]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SBT:将输入预先应用到 inputKeys 的相关文章

随机推荐

  • 如何将类属性声明为类名的联合?

    我正在阅读电子表格寻找不同的结构 当我使用 Moose 尝试以下操作时 它似乎做了我想要的事情 我可以创建不同类型的对象 将其分配给找到的成员 并转储 Cell 实例以供审查 package Cell use Moose use Moose
  • Grunt - 监视文件并在文件更改时进行 SFTP

    我正在尝试自动上传 css文件 当它从 Sass 编译时 这就是我的Gruntfile js module exports function grunt Project configuration grunt initConfig pkg
  • 如何调用系统命令并捕获其输出?

    有没有办法调用系统命令 例如ls or fuser在铁锈中 捕获它的输出怎么样 std process Command允许这样做 有多种方法可以生成子进程并在计算机上执行任意命令 spawn 运行程序并返回一个包含详细信息的值 output
  • 无法解析指针:/definitions/Error-ModelName

    我是 Swagger io 的新手 也是 Spring Fox 的新手 我遇到的问题是 由于某种原因 一个对象没有正确引用其模型 The error in the UI 错误是因为 JSON 中的结果如下 schema ref defini
  • Android 真的没有 wchar_t 吗?

    我建立了一个简单的方法 如下所示 wchar t buf 1024 void logDebugInfo wchar t fmt va list args va start args fmt vswprintf buf sizeof buf
  • 使用 JAX-RS 创建 RESTful Web 服务并将其部署到 tomcat

    我正在尝试使用 JAX RS 创建和部署 RESTful Web 服务并将其部署到 tomcat 我不想使用任何 IDE 在 Tomcat 中 我在 webapps 中有以下目录结构 notifire WEB INF gt web xml
  • 显示所有表的所有数据

    我想显示数据库中的所有数据而不编写select对于每个表 我该怎么做 我不想这样做 select from Customer select from Employee select 我正在将 TSQL 与 MSSQL Server 一起使用
  • 在 Swift 中添加和减去时间

    我用伪代码编写了其中一些内容 因为我不知道它的语法 我想要timeLeftLabel text反映 6 小时结束前还剩多少小时 分钟和秒 我最大的问题是我不知道如何加减时间 谁能帮我 var timer NSTimer func timer
  • 如何在 Primefaces DataTable 中使用 Font Awesome(或其他字体图标)而不是 jQuery sprite?

    我正在使用 PrimeFaces 生成数据表 默认的排序图标是 JQuery 库中的 V 形图标 但由于它们不是 Vector 因此看起来很难看 我不想使用像 font Awesome 这样的字体来替换它们 但我不知道如何做到这一点 我可以
  • 如何将 SolrQuery(SOLRJ) 转换为 URL?

    在使用 SOLRJ 时 我想知道如何使用 SOLR 查询语法将 SolrQuery 对象转换为其 URL 表示形式 我尝试使用 toString 方法 但它没有返回正确的查询表示 还有其他方法吗 我建议ClientUtils toQuery
  • 从您的应用程序启动 Facetime?

    我发现您可以通过以下方式从您的应用程序启动 FaceTime UIApplication sharedApplication openURL NSURL URLWithString facetime tel number 我还读到 由于没有
  • 拼接后计算源图像的坐标

    我使用 opencv 的全景拼接算法 将 2 或 3 个图像拼接成一个新的结果图像 我有每个源图像中的点的坐标 我需要计算结果图像中这些点的新坐标是什么 我在下面描述该算法 我的代码类似于示例 缝合 详细 来自 opencv 分支 3 4
  • 数组的 N 重分区,每个分区的总和相等

    给定一个整数数组a 两个数N and M 返回N一组整数从a使得每个组的总和为M 例如 说 a 1 2 3 4 5 N 2 M 5 然后算法可以返回 2 3 1 4 or 5 2 3 或者可能是其他人 我在这里可以使用什么算法 Edit 我
  • 在 iOS 中的 Instagram 上与图像共享文本

    在我的应用程序中 我在 Instagram 上分享了一张图片 它在我的应用程序中运行良好 我正在使用以下代码 property nonatomic retain UIDocumentInteractionController dic CGR
  • ASPNET Boilerplate,扩展审核日志

    我正在尝试延长AuditLog实体在ASPNET样板框架 以便向其添加一些新属性 我曾尝试延长AuditLog class ExtendedAuditInfo 并实现一个定制版本AuditStore Class ExtendedAuditS
  • 如何在 C# 中列出 .zip 文件夹的内容?

    如何在 C 中列出压缩文件夹的内容 例如 如何知道压缩文件夹中包含多少个项目 以及它们的名称是什么 NET 4 5 或更高版本最终具有处理通用 zip 文件的内置功能System IO Compression ZipArchive clas
  • 禁用 Internet Explorer 8 开发人员工具

    有没有办法禁用 Internet Explorer 8 开发人员工具 或者至少更改快捷键映射 我正在开发一个 ASP NET AJAX 应用程序 该应用程序多年来一直使用 F12 键来实现某个功能 它实际上是原始 DOS 应用程序的保留 客
  • 在多层应用程序中定位 Ninject 模块的位置

    我的应用程序包括许多后端程序集 包括实体框架数据存储库层 它们由许多前端程序集 包括 Windows 服务和 MVC3 Web 应用程序 共享 我对 Ninject 绑定过程的理解是 每个包含可注入类型的程序集还应该包含一个定义这些类型的默
  • Bash 最后一个索引

    很抱歉这个蹩脚的 bash 问题 但我似乎无法解决 我有以下简单的情况 我有像这样的变量artifact 1 2 3 zip 我想在连字符和点的最后一个索引之间获取一个子字符串 两者都是互斥的 我的bash技能不太强 我有以下内容 a ar
  • SBT:将输入预先应用到 inputKeys

    在 SBT 中 我想定义一个 inputKey 来读取命令行参数 稍微更改它们并uses结果作为其他 inputKey 的输入 I tried lazy val demo inputKey Unit A demo input task la