1

我想使用(或类似但基于 Scala)声明所需的子命令。scopt

例如,我想有以下概要(类似于man git,例如):

mycli [--version] [--help] <command> [<args>]

需要<command>是子命令之一,例如,和。类似于以下内容:subAsubB

private val parser = new OptionParser[Config]("mycli") {
  head(s"${BuildInfo.name} v${BuildInfo.version} is © 2014 by ${BuildInfo.organization}")
  help("help")       text("prints this usage text")
  version("version") text("FIXME”)
  cmd("command") required() action {(c, config) => c match {
    case "subA" => config.copy(mode = "subA") children(
      arg[String]("<files>...") unbounded() optional() action {(rs, config) => config.copy(files = config.files :+ rs) },
      opt[Unit]  ("with-optA")                         action {(_ , config) => config.copy(optA  = true)},
      opt[Unit]  ("with-optB")                         action {(_ , config) => config.copy(optB  = true)})
    case "subB" => //...
    case _      => // ERROR! 
  } }
}

有什么提示吗?

在此先感谢您的帮助!

4

1 回答 1

4

当然这有点棘手,它可以导致许多级别的儿童选择。

这是我的配置类:

case class Config(cmd:String="", subcmd:String="")

这是我的解析器:

val parser = new scopt.OptionParser[Config]("MyCLI") {
  head("Foo")
  cmd("cmdA") action { (_, c) => c.copy(cmd = "cmdA")
  } children(
    cmd("subA1") action { (_, c) => c.copy(subcmd = "subA1")},
    cmd("subA2") action { (_, c) => c.copy(subcmd = "subA2")}
    )
  cmd("cmdB") action { (_, c) => c.copy(cmd = "cmdA")
  } children(
    cmd("subA1") action { (_, c) => c.copy(subcmd = "subA1")},
    cmd("subA2") action { (_, c) => c.copy(subcmd = "subA2")}
    )
  checkConfig { c => c match {
    case Config("", _) => failure("No command given.")
    case Config(_, "") => failure("Must Choose a subcommand.")
    case _ => success

  }}
}

我希望这有帮助。我会Config.cmd用密封的特征和对象代替。我没有这样做,所以这将是可复制的。

每个子命令都可以有自己的子命令,以及另一个命令、选项或参数。

调用checkConfig非常重要,否则如果没有给出命令,应用程序将静默退出。

于 2014-02-01T23:26:39.940 回答