scala - SBT插件:在运行taskKey之前使用inputTask覆盖settingKey?
问题描述
我有一个task
which takesettingA
和 settingB` 作为运行的输入。
我想要一个inputTask
可以覆盖settingA
并task
使用新值运行的settingA
.
如何做到这一点?
谢谢你。
更多细节:
任务将类似于:
Def.taskDyn {
val settingAValue = settingA.value
val settingBValue = settingB.value
Def.task {
settingAValue + settingBValue
}
}
人们会在他们的build.sbt
:
settingA := 3
settingB := 1
然后sbt task
会产生4
我想要一个inputTask
赞:
Def.inputTaskDyn {
val newValue = customParser.parsed
Def.taskDyn {
val settingCValue = settingC.value
Def.task {
// call task with settingA = newValue ?
}
}
}
编辑:
如果这样更容易,settingA
可能是 aTask
而不是 a Setting
。
解决方案
你可以这样做:
lazy val setting1 = settingKey[String]("")
lazy val setting2 = settingKey[String]("")
lazy val task1 = taskKey[Unit]("")
lazy val inputTask1 = inputKey[Unit]("")
setting1 := "a"
setting2 := "b"
task1 := {
println(setting1.value + setting2.value)
}
inputTask1 := {
val newValue = Parsers.spaceDelimited("arg").parsed.head
val curState = state.value
val updState = Project.extract(curState).appendWithoutSession(
Vector(setting1 := newValue),
curState
)
Project.extract(updState).runTask(task1, updState)
}
基本上,您可以依赖 SBT 构建状态是完全可自省的这一事实,并且可以对其进行修改并以新状态运行任务。
但是,文档建议不要在任务中使用它。一般来说,SBT 模型是所有设置实际上都是不可变的——您不能也不应该在任务执行期间修改它们。相反,建议为此使用命令:
commands += command1
lazy val command1 = Command.args("command1", "") { (state, args) =>
val updState = Project.extract(state).appendWithoutSession(
Vector(setting1 := args.head),
state
)
val (finalState, _) = Project.extract(updState).runTask(task1, updState)
finalState
}
请注意,此命令setting1
在执行后保留设置为提供的值。如果您不想这样做,则应返回原始状态值,或者更好的是,将原始值保存setting1
到局部变量并在任务运行后将其恢复:
lazy val command1 = Command.args("command1", "") { (state, args) =>
val newValue = args.head
val originalValue = Project.extract(state).get(setting1)
val updState = Project.extract(state).appendWithoutSession(
Vector(setting1 := newValue),
state
)
val (nextState, _) = Project.extract(updState).runTask(task1, updState)
Project.extract(nextState).appendWithoutSession(
Vector(setting1 := originalValue),
nextState
)
}
不幸的是,API 不是很直观(例如你必须调用Project.extract
很多),但它是做你想做的事的正确方法。请注意,可以通过多种方式构造命令,包括您拥有自己的Parser
; 为了简单起见,我在Command.args
上面使用过。
推荐阅读
- oracle - PLSQL DBMS_SCHEDULER 等待响应
- tinymce - TinyMCE file_browser_callback 不显示浏览按钮
- ansible - Ansible:从变量中获取组成员
- c# - PInvoke 在返回结构时仅适用于 64 位
- swift - 使用 Swift 呈现下一个 ViewController 以关闭当前的 ViewController
- angular - Angular Mat DatePicker 格式问题
- javascript - Preact + TypeScript 不允许我直接调用 h 函数而不是使用 JSX
- android - 如何将从存储浏览的GIF图像转换为Android中的InputStream?
- python - 仅在存在时按字段过滤,弹性搜索
- spring-boot-actuator - 执行器执行流程