Command Cougar

一个优雅的纯 Swift 库,用于构建命令行应用程序。

Build Status

特性

要求


安装

Swift Package Manager

dependencies: [
.Package(url: "https://github.com/surfandneptune/CommandCougar.git", from: "1.0.0")
]

用法

CommandCougar 支持主命令以及子命令。这非常类似于 swift package manager 的接口。

命令

命令是一个 struct,用于概述命令行界面的结构。它可以有一个子命令列表或一个(.required | .optional) 参数列表。

创建 Command

var helloCommand = Command(
    name: "hello",
    overview: "Say Hello",
    callback: { print($0.options, $0.parameters) },
    options: [
        Option(flag: .short("v"), overview: "Increase verbosity"),
        Option(flag: .short("w"), overview: "Wave hello")
    ],
    parameters:[.optional("Name")])

评估 Command

一旦创建了一个命令,就可以针对一系列参数对其进行评估,通常这些参数来自 CommandLine.arguments。 evaluate 函数创建并返回一个 CommandEvaluation

let arguments = ["hello", "-v", "Mr.Rogers"]
let helloEvaluation = helloCommand.evaluate(arguments: arguments)

通常,参数的输入将由 CommandLine.arguments 提供。请注意,CommandCougar 会自动删除第一个参数。

let helloEvaluation = helloCommand.evaluate(arguments: CommandLine.arguments)

读取 CommandEvaluation

CommandEvaluation 是一个 struct,用于表示针对参数列表评估 Command 的结果。

helloCommand.options        // ['-v', '-w']
helloEvaluation.options     // ['-v']
helloEvaluation.parameters  // ['Mr.Rogers']

请注意,评估仅包括参数列表中看到的选项。

执行回调

回调将 CommandEvaluation 作为输入传递给在评估之前在 Command 中设置的函数。

try helloEvaluation.performCallbacks()

自动生成帮助菜单

帮助菜单是自动生成的,并且该选项已添加到命令选项集中。

$ hello --help
OVERVIEW: Say Hello

USAGE: hello [option] <command>

COMMANDS:

OPTIONS:
   -h, --help                    The help menu
   -v                            Increase verbosity
   -w                            Wave hello

选项

选项可以有一个短标志(例如 -v)或一个长标志(例如 --verbose)。 选项允许有一个可选的参数。 标志和参数必须用 = 连接,例如 --path=/tmp

// will match -v
Option(flag: .short("v"), overview: "verbose")

// will match -v | --verbose
Option(flag: .both(short: "v", long: "verbose"), overview: "verbose")

// will match --path=/etc
Option(flag: .long("path"), overview: "File path", parameterName: "/etc")

子命令

许多命令行界面,如 gitswift package manager 允许使用子命令。 CommandCougar 也允许表达这一点。 一个需要注意的规则是,具有子命令的命令不允许也具有参数。

考虑这个命令
swift package -v update --repin

swift 是主命令。

packageswift 命令的子命令,带有 -v 选项。

updatepackage 命令的子命令,带有 --repin 选项。

表达此参数列表的命令如下所示

/// Used for callback
func echo(evaluation: Command.Evaluation) throws {
  print(
    "\(evaluation.name) evaluated with " +
    "options: \(evaluation.options) " +
    "and parameters \(evaluation.parameters)"
    )
}

let swiftCommand =
Command(
    name: "swift",
    overview: "Swift Program",
    callback: echo,
    options: [],
    subCommands: [
        Command(
            name: "package",
            overview: "Perform operations on Swift packages",
            callback: echo,
            options: [
                Option(
                    flag: .both(short: "v", long: "verbose"),
                    overview: "Increase verbosity of informational output"),
                Option(
                    flag: .long("enable-prefetching"),
                    overview: "Increase verbosity of informational output")
            ],
            subCommands: [
                Command(
                    name: "update",
                    overview: "Update package dependencies",
                    callback: echo,
                    options: [
                        Option(
                            flag: .long("repin"),
                            overview: "Update without applying pins and repin the updated versions.")
                    ],
                    subCommands: [])
            ])
    ])

评估 Subcommands

当评估根命令时,所有子命令也将被评估,并且它们的回调将被触发。

do {
    // normally CommandLine.arguments
    let args = ["swift", "package", "-v", "update", "--repin"]
    let evaluation: Command.Evaluation = try swiftCommand.evaluate(arguments: args)
    try evaluation.performCallbacks()
} catch {
    print(error)
}

// Output
// swift evaluated with  options: []  and parameters []
// package evaluated with  options: [-v]  and parameters []
// update evaluated with  options: [--repin]  and parameters []

访问 CommandEvaluation 的值

直接访问返回的 CommandEvaluation 的值

evaluation["package"]?.name  // results in "package"

evaluation["package"]?.options["v"] // results in Option.Evaluation

evaluation["package"]?.options["v"]?.flag.shortName // results in "v"

evaluation["package"]?.options["enable-prefetching"] // results in nil

evaluation["package"]?["update"]?.options["repin"]?.flag.longName // results in "repin"

使用 throw 访问

要通过索引访问参数,您可以使用 parameter(at: Int) throws -> String。 如果该参数不存在,将抛出 parameterAccessError

这将变成

func callback(evaluation: CommandEvaluation) throws {
    guard let first = evaluation.parameters.first else {
    throw CommandCougar.Errors.parameterAccessError("Parameter not found.")
	}
}

变成

func callback(evaluation: CommandEvaluation) throws {
    let first = try evaluation.parameter(at: 0)
}

子命令的帮助菜单不同

也会为子命令生成帮助

$ swift package --help
OVERVIEW: Perform operations on Swift packages

USAGE: swift package [option] <command>

COMMANDS:
   update                        Update package dependencies

OPTIONS:
   -v, --verbose                 Increase verbosity of informational output
   --enable-prefetching          Enable prefetching in resolver
   -h, --help                    The help menu

EBNF

CommandCougar 支持的语言的 EBNF 如下所示

<command> ::= <word> {<option>} ([<command>] | {<parameter>})
<option> ::= <single> | <double>
<single> ::= -<letter>=[<parameter>]
<double> ::= --<word>=[<parameter>]
<parameter> ::= <word>
<word> ::= <letter>+
<letter> ::= a | b | c | d | e...

CLOC

代码行数分解,以显示项目的总体大小

-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Swift                           11            133            411            451
-------------------------------------------------------------------------------
SUM:                            11            133            411            451
-------------------------------------------------------------------------------

交流

许可证

CommandCougar 是在 MIT 许可证下发布的。 有关详细信息,请参见 LICENSE。