LoginSignup
5
3

[Swift] ArgumentParserを使って自作コマンドを作る

Last updated at Posted at 2023-06-04

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

実行してみると、、
スクリーンショット 2023-06-04 16.54.02.png
しっかりとHello worldが出力されています。

また、swift-argument-parserは便利なことに自動でコマンドのヘルプを作成してくれます。
このコマンドのヘルプを出力するには、

$ swift run TestCLITool -h

これを実行すると、
スクリーンショット 2023-06-04 16.55.21.png
このようにヘルプを表示することができました!!

引数, オプション, 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 たけし

これを実行すると、
スクリーンショット 2023-06-04 17.34.26.png
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の両方が利用可能です。
これを実行すると、
スクリーンショット 2023-06-04 18.22.39.png
オプションを追加できました!!
そのほかにも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

これを実行すると、
スクリーンショット 2023-06-04 18.43.44.png
期待した動作になりました。

コマンドをグローバルで使えるようにする

自作したコマンド、$ swift run <コマンド名>じゃなくて$ TestCLITool --goodbyeみたいに使いたい!って方いるとおもいます。
それをするには単にいろんなコマンドが入ってる
/usr/local/bin
にビルドしたバイナリを入れてあげれば良いです。
このようなMakefileを作成します。

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ツールを自作してみましょう!

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3