Могут ли команды быть написаны для поддержки многострочных аргументов, то есть с новыми строками в них, как heredocs?

обзор

Как можно написать команду sbt, которая поддерживает аргументы с символами новой строки в них какheredocs?

Я хотел бы иметь команду sbt, где пользователь может вставить многострочный блок текста, который затем обрабатывается / преобразуется во что-то еще. Эксперименты пока что показывают, что sbt пытается разобрать команду сразу после появления новой строки.

Пример использования

Примечание: это всего лишь пример использования для объяснения желаемой функциональности SBT. яне ищет другие механизмы для обработкиpom.xml файлы в SBT; скорее, как реализовать пользовательскую команду с многострочными аргументами.

Предположим, я хотел бы, чтобы пользователь мог вставить фрагмент кода XML из POM-файла Maven в 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("\"", "\" % \"", "\"")
        })
    }
}

С этим установленным плагином можно запустить следующее в SBT REPL:

pom2sbt "<dependency><groupId>org.foo</groupId><artifactId>megalib</artifactId><version>1.1.1</version></dependency>"

или же

pom2sbt """<dependency><groupId>org.foo</groupId><artifactId>megalib</artifactId><version>1.1.1</version></dependency>"""

и получить:

"org.foo" % "megalib" % "1.1.1"

Что является правильным выводом, но переформатирование входной строки для размещения на одной строке сводит на нет большинство преимуществ утилиты.

Желаемая возможность - (в данном случае и в общем случае многострочного аргумента команды) набратьpom2sbt """вставьте весь многострочный текстовый блок и завершите"""и иметь SBT задержку синтаксического анализа всей команды до закрытия разделителя heredoc, например:

pom2sbt """<dependency>
<groupId>org.foo</groupId>
<artifactId>megalib</artifactId>
<version>1.1.1</version>
</dependency>"""

Однако даже при использованииStringVerbatim синтаксический анализатор, как в примере кода, SBT выдает ошибку разбора после первой новой строки:

> 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]   <
...

Ответы на вопрос(1)

Ваш ответ на вопрос