Scala 是否可以编写命令以支持多行参数,即其中包含新行,如heredocs? 概述
如何编写一个sbt命令来支持带有换行符的参数 我希望有一个sbt命令,用户可以在其中粘贴一个多行文本块,然后将其处理/转换为其他内容。迄今为止的实验似乎表明,sbt会在遇到换行符后立即尝试解析命令 用法示例 注意:这只是一个解释所需SBT功能的用例。我不是在寻找其他机制来处理SBT中的Scala 是否可以编写命令以支持多行参数,即其中包含新行,如heredocs? 概述,scala,sbt,Scala,Sbt,如何编写一个sbt命令来支持带有换行符的参数 我希望有一个sbt命令,用户可以在其中粘贴一个多行文本块,然后将其处理/转换为其他内容。迄今为止的实验似乎表明,sbt会在遇到换行符后立即尝试解析命令 用法示例 注意:这只是一个解释所需SBT功能的用例。我不是在寻找其他机制来处理SBT中的pom.xml文件;而是如何实现具有多行参数的自定义命令 假设我希望用户能够将Maven POM文件中的XML代码片段粘贴到SBT REPL中,并让它将所有依赖项转换为SBT语法。如果XML代码都在一行上,那么下面
pom.xml
文件;而是如何实现具有多行参数的自定义命令
假设我希望用户能够将Maven POM文件中的XML代码片段粘贴到SBT REPL中,并让它将所有依赖项转换为SBT语法。如果XML代码都在一行上,那么下面是一个有效的实现:
// NB: Requires SBT >= 0.13.5
package pomhelpers
import sbt._
import Keys._
import sbt.complete.Parser
import sbt.complete.DefaultParsers._
/**
* Plugin to install an SBT command to assist in converting Maven dependency syntax
* to SBT DSL.
*/
object ExtractMvnDependencies extends AutoPlugin {
override def trigger = allRequirements
override lazy val projectSettings = Seq(commands ++= Seq(pomLibs2Sbt))
val Pom2SbtCommand = "pom2sbt"
val Pom2SbtHelp = "<pom-xml-fragment>"
// **How should this be constructed to handle mult-line inputs?**
val MultiLineCommandInputParser: Parser[String] =
OptSpace ~> (StringBasic | StringVerbatim)
lazy val pomLibs2Sbt = Command(
Pom2SbtCommand,
Help((Pom2SbtCommand, Pom2SbtHelp)))(_ => MultiLineCommandInputParser) { (state , xmlFrag) =>
val sbtdeps = pomXml2SbtDsl(xmlFrag)
println(sbtdeps.mkString("\n"))
state
}
/** Convert POM string to SBT form. */
private def pomXml2SbtDsl(xmlFrag: String): Seq[String] = {
import scala.xml._
val deps = XML.loadString(xmlFrag) \\ "dependency"
deps map ((dependency) => {
val coords = Seq("groupId", "artifactId", "version", "scope")
val coordParts = coords.map(coord => (dependency \ coord).text.trim).filter(_.nonEmpty)
coordParts.mkString("\"", "\" % \"", "\"")
})
}
}
这是正确的输出,但将输入字符串重新格式化以适合一行会使大多数实用程序的好处付诸东流
所需的功能是(在这种情况下,以及在一般多行命令参数情况下)键入pom2sbt”“
,粘贴整个多行文本块,以”“”
结束,并让SBT延迟整个命令的解析,直到关闭herdoc分隔符,如下所示:
pom2sbt """<dependency>
<groupId>org.foo</groupId>
<artifactId>megalib</artifactId>
<version>1.1.1</version>
</dependency>"""
我怀疑这里的问题在于命令行处理程序(使用jline)过早地将命令行值传递给sbt。在unix上,您需要转义新行以避免shell执行命令,我认为这里也会发生同样的情况 不过,我不知道是否有办法避免执行模式并进入多行模式。我也不认为sbt提供了这个功能 经过更仔细的调查,显示了所有的线路处理。我对它在sbt中如何使用的理解告诉我,在输入击键或特殊值之前,无法指示sbt继续读取行
内部命令的作用是实例化FullReader,然后读取行,以便在代码中看到它,机器就是在代码中实例化的。您能否演示用户应该如何在sbt shell或命令行中执行这样的命令?或者你想要一个输入任务吗?只是用工作代码更新了问题以澄清用例。不确定一个
inputAsk
是否是我想要的…也许一个答案会澄清在实现这种事情时,人们何时会在命令上使用inputAsk
,这确实是我需要知道的。现在更清楚了。谢谢在任何方面都会有帮助,或者您的唯一要求是使用%
s将pom deps完全转换为ModuleID的sbt格式?pom转换用例只是一个示例,用于解释我想要的内容(从一些使用文件解析器的内部代码改为)。我真的想确定是否有一种方法可以通过自定义sbt命令进入“herdoc”或“粘贴”模式,而不考虑使用情况。我怀疑这里的问题是当命令行(jline)将命令行值传递给sbt时。在unix上,您需要转义新行以避免shell执行命令,我认为这里也会发生同样的情况。我不知道是否有办法避免执行模式并进入多行模式。太棒了。非常感谢你的帮助@JoshSuereth还就此事发表了一些评论。
pom2sbt """<dependency><groupId>org.foo</groupId><artifactId>megalib</artifactId><version>1.1.1</version></dependency>"""
"org.foo" % "megalib" % "1.1.1"
pom2sbt """<dependency>
<groupId>org.foo</groupId>
<artifactId>megalib</artifactId>
<version>1.1.1</version>
</dependency>"""
> pom2sbt """<dependency>
[error] Expected '"""'
[error] pom2sbt """<dependency>
[error] ^
> <groupId>org.foo</groupId>
[error] Expected symbol
[error] < usage:
[error]
[error]
[error] More command help available using 'help <command>' for:
[error] <
...