Commander 是一个小型 Swift 框架,允许你以可组合的方式创建美观的命令行界面。
import Commander
let main = command { (filename:String) in
print("Reading file \(filename)...")
}
main.run()
传递给命令函数的闭包接受任何符合 ArgumentConvertible
的参数,Commander 将自动将参数转换为这些类型。如果无法转换,用户将收到一条友好的错误消息,告知他们参数与期望的类型不匹配。
String
、Int
、Double
和 Float
已扩展为符合 ArgumentConvertible
,你可以轻松扩展任何其他类或结构,以便将其用作命令的参数。
command { (hostname:String, port:Int) in
print("Connecting to \(hostname) on port \(port)...")
}
你可以将一组命令组合在一起。
Group {
$0.command("login") { (name:String) in
print("Hello \(name)")
}
$0.command("logout") {
print("Goodbye.")
}
}
用法
$ auth
Usage:
$ auth COMMAND
Commands:
+ login
+ logout
$ auth login Kyle
Hello Kyle
$ auth logout
Goodbye.
你可以描述命令的位置参数和选项,以自动生成帮助信息。这通过传入这些参数的描述符来完成。
例如,对于带有描述的固定位置参数,你可以使用
command(
Argument<String>("name", description: "Your name"),
Argument<String>("surname", description: "Your surname"),
Argument<Int>("count", description: "Number of times to print")
) { name, surname, count in
for _ in 0..<count {
print("Hello \(name) \(surname)")
}
}.run()
请记住,你必须传递 3 个必需的参数。
另一个例子,描述一个接受两个(可选)选项的命令,--name
和 --count
,其中 name 的默认值为 world
,count 的默认值为 1
。
command(
Option("name", default: "world"),
Option("count", default: 1, description: "The number of times to print.")
) { name, count in
for _ in 0..<count {
print("Hello \(name)")
}
}
$ hello --help
Usage:
$ hello
Options:
--name
--count - The number of times to print.
$ hello
Hello world
$ hello --name Kyle
Hello Kyle
$ hello --name Kyle --count 4
Hello Kyle
Hello Kyle
Hello Kyle
Hello Kyle
--myOption value1 value2 value3
count
值,用户只需重复选项并添加额外的值。示例:--myOption value1 --myOption value2
注意:*重要的是在选项和标志之后描述你的参数,以便解析器可以区分 --option value
和 --flag argument
。*
注意:*ArgumentParser
本身是 ArgumentConvertible
,因此你也可以获取原始参数解析器来执行任何自定义解析。*
command { (name:String, parser:ArgumentParser) in
if parser.hasOption("verbose") {
print("Verbose mode enabled")
}
print("Hello \(name)")
}
$ tool Kyle --verbose
Verbose mode enabled
Hello Kyle
你可以通过多种方式安装 Commander,例如使用 SPM (Swift Package Manager)、Conche、CocoaPods 或 CocoaPods-Rome。
重要的是要注意,Commander(以及任何其他依赖项)的 .framework
或动态库文件必须在运行时对你的命令行工具可用。除非你正在使用 SPM。
应用程序将在它们的 rpath
中查找,其中包含期望找到 .framework
的路径。
使用 Swift 脚本,你可以使用 -F
标志来设置框架搜索路径,如下所示
#!/usr/bin/env xcrun swift -F Rome
import Commander
对于编译后的 Swift 代码,你需要添加一个指向你的依赖框架的 rpath,如下所示
$ install_name_tool -add_rpath "@executable_path/../Frameworks/" "bin/querykit"
其中相对于可执行路径的 "../Frameworks" 用于查找框架,而 bin/querykit
是可执行文件。
在其他系统上安装可执行文件时,重要的是复制框架和二进制文件。
CommandType
是命令背后的核心协议,它是一个对象或结构,具有一个接受 ArgumentParser
的 run
方法。
command
函数和 Group
都返回一个符合 CommandType
的命令,它们可以轻松互换。
protocol CommandType {
func run(parser:ArgumentParser) throws
}
便捷的 command
函数为你的命令接受一个闭包,该闭包接受符合 ArgumentConvertible
协议的参数。这使 Commander 可以轻松地将参数转换为你想用于命令的类型。
protocol ArgumentConvertible {
init(parser: ArgumentParser) throws
}
ArgumentParser
是一个允许你提取选项、标志和位置参数的对象。
Commander 在 BSD 许可证下可用。有关更多信息,请参阅 LICENSE 文件。