SwiftではArgumentParserを使用すると簡単にSwiftで自作コマンドの作成が可能です。
ArgumentParserとはAppleが作った公式のライブラリで、リポジトリはこちらです。
今回はSwift Package ManagerとArgumentParserを使用してコマンドを作る方法を紹介します!
導入
まず新しくコマンド用にディレクトリを作成して、そこで以下のようなコマンドを叩きます。
swift package init --name <コマンドの名前> --type executable
叩いたら、次にArgumentParserをPackage.swiftに追加していきます。
import PackageDescription
let package = Package(
name: "TestCLITool",
products: [
.executable(name: "TestCLITool", targets: ["TestCLITool"])
],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.2.2")
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.executableTarget(
name: "TestCLITool",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser")
]
),
]
)
今回はTestCLIToolという名前のCLIツールを作成することにしました。
実装
とりあえずHello Worldを出力するCLIツールを作成してみましょう。
import Foundation
import ArgumentParser
@main
struct TestCLITool: ParsableCommand {
mutating func run() throws {
print("Hello World!!")
}
}
mutating func run()
のところにコマンドが呼ばれた時に実行したい処理を記述します。
実行
このコマンドで作ったCLIツールを呼び出すことができます。
$ swift run TestCLITool
実行してみると、、
しっかりとHello worldが出力されています。
また、swift-argument-parserは便利なことに自動でコマンドのヘルプを作成してくれます。
このコマンドのヘルプを出力するには、
$ swift run TestCLITool -h
これを実行すると、
このようにヘルプを表示することができました!!
引数, オプション, Flagを追加する
ArgumentParserはPropertyWrapperを使用することで、簡単にコマンドに引数、オプションを追加することが可能です。
引数
まずは引数を追加していきます。
import Foundation
import ArgumentParser
@main
struct TestCLITool: ParsableCommand {
@Argument(help: "名前を入力")
var text: String
mutating func run() throws {
print("Hello! \(text)")
}
}
PropertyWrapperのArgumentを使うことで引数を追加できます。
また、引数にhelpの情報を付け足すことができます。コマンドのヘルプを実行すると、
USAGE: test-cli-tool <text>
ARGUMENTS:
<text> 名前を入力
OPTIONS:
-h, --help Show help information.
このようにヘルプが追加されていることがわかります。
$ swift run TestCLITool たけし
これを実行すると、
Hello! たけし
と出力されていることがわかります。
オプション
次にオプションを追加する方法をご紹介します。
import Foundation
import ArgumentParser
@main
struct TestCLITool: ParsableCommand {
@Option(name: .shortAndLong, help: "名前を入力")
var text: String?
mutating func run() throws {
if let text {
print("Hello! \(text)")
} else {
print("Hello World!")
}
}
}
PropertyWrapperのOptionを使うことでコマンドのオプションを追加できます。
今回はnameに.shortAndLong
を指定しているので、
$ swift run TestCLITool -t たけし
$ swift run TestCLITool --text たけし
このように、--text
とその短縮版の-t
の両方が利用可能です。
これを実行すると、
オプションを追加できました!!
そのほかにもname
には以下が指定可能です。
name | 意味 |
---|---|
long | lowerCamelCaseで書かれたproperty名をハイフン区切りにのオプションにしてくれる |
short | 短縮版 |
shortAndLong | shortとlong |
customLong(_:withSingleDash:) | オプション名をカスタムで指定できる |
customShort(_:allowingJoined:) | オプション名をカスタムで1文字指定できる |
Flag
次にFlagを追加する方法についてご紹介します。
import Foundation
import ArgumentParser
@main
struct TestCLITool: ParsableCommand {
@Flag(name: [.customLong("goodbye"), .customShort("g")], help: "Goodbye Worldを出力するかどうか")
var goodbyeWorld: Bool = false
mutating func run() throws {
if goodbyeWorld {
print("Goodbye world!")
} else {
print("Hello World!")
}
}
}
PropertyWrapperのFlagを使用することで、コマンドにフラグを追加できます。
以下のいずれかでコマンドを実行できます。
$ swift run TestCLITool --goodbye
$ swift run TestCLITool -g
コマンドをグローバルで使えるようにする
自作したコマンド、$ swift run <コマンド名>
じゃなくて$ TestCLITool --goodbye
みたいに使いたい!って方いるとおもいます。
それをするには単にいろんなコマンドが入ってる
/usr/local/bin
にビルドしたバイナリを入れてあげれば良いです。
このようなMakefileを作成します。
COMMAND_NAME = TestCLITool
.PHONY: release
release:
swift build -c release
sudo cp .build/release/$(COMMAND_NAME) /usr/local/bin/$(COMMAND_NAME)
$ make release
と打つことで、ターミナルでこのコマンドが使えるようになります。
これはこの記事を参考にしました。
コマンド名を変える
このようにしてコマンド名を変えます。
import Foundation
import ArgumentParser
@main
struct TestCLITool: ParsableCommand {
static var configuration = CommandConfiguration(commandName: "ryu-test")
mutating func run() throws {
print("Hello World!")
}
}
他にもCommandConfigurationを使用してさまざまなコマンドの設定を変更可能となっています。
さいごに
今回はArgumentParserを使用して自作CLIツールの作成の仕方を解説しました。簡単にCLIツールを作ることができました!
自分は他にもさまざまなCLIツールを自作しているので、よかったら自分のGithubを見ていただけると嬉しいです。
CLIツール自作するのめっちゃ楽しいので、みなさんもこれを機にCLIツールを自作してみましょう!