この記事では、アップル公式ドキュメントのブートストラップを日本語で整理した
コマンドラインツールを構築すれば、例えばこんなものが作れる ↓
- 開発者向けツール: ソースコードのフォーマットや静的解析を行うツール
- 自動化スクリプト: 複数のコマンドをまとめて実行するスクリプト
- デプロイツール: サーバーへのアプリケーションのデプロイを自動化するツール
Swift でコマンドラインツールを構築する
以下のコマンドを実行し、SwiftPM による新規プロジェクトを作成する。
$ mkdir MyCLI
$ cd MyCLI
$ swift package init --name MyCLI --type executable
すると、下記の構成で MyCLI ディレクトリができる。
.
├── Package.swift
└── Sources
└── main.swift
Package.swift
はマニフェストファイルで、依存関係のようなプロジェクトのメタデータが記載される。Sources/main.swift
は SwiftCLI のエントリーポイントとして実行コードが記載される。初期設定で "Hello, world" を出力する状態になっているので、以下のコマンドを実行して確認することができる。
$ swift run MyCLI
Building for debugging...
[3/3] Linking MyCLI
Build complete! (0.68s)
Hello, world!
依存関係を追加する
Package.swift
を拡張して、依存関係を追加する。ここでは、ASCII アートを作成してみることとする。
import PackageDescription
let package = Package(
name: "MyCLI",
dependencies: [
.package(url: "https://github.com/apple/example-package-figlet", branch: "main"),
],
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: "MyCLI",
dependencies: [
.product(name: "Figlet", package: "example-package-figlet"),
],
path: "Sources"
),
]
)
以下のコマンドを実行すると、SwiftPM が立ち上がり、先ほどの依存関係を追加、並びにコードがビルドされる。
$ swift build
すると、下記の構成でディレクトリが更新される。Package.resolved
は、現在使用している依存関係のバージョンが載ったスナップショットである。
.
├── Package.swift
├── Package.resolved
└── Sources
└── main.swift
ASCII アートを表示する
エントリーポイントの実行コードを編集し、先ほど追加した Figlet (↑)を使用する。ここで、main.swift
あるいは @main
の修飾子の記載されたファイルがエントリーポイントになることができる。試しに main.swift
を消して、新たに myCLI.swift
ファイルを作成し、以下のように編集する。
import Figlet
@main
struct FigletTool {
static func main() {
Figlet.say("Hello, Swift!")
}
}
$ swift run MyCLI
...
_ _ _ _ ____ _ __ _ _
| | | | ___ | | | | ___ / ___| __ __ (_) / _| | |_ | |
| |_| | / _ \ | | | | / _ \ \___ \ \ \ /\ / / | | | |_ | __| | |
| _ | | __/ | | | | | (_) | _ ___) | \ V V / | | | _| | |_ |_|
|_| |_| \___| |_| |_| \___/ ( ) |____/ \_/\_/ |_| |_| \__| (_)
|/
コマンドライン引数を取れるようにする
コマンドラインツールで引数をパースできるようにするために、新たな依存関係として Swift Argument Parser(↑)を追加する。Swift Argument Parser は、Swiftでのコマンドライン引数解析を型安全かつ簡単にする公式ライブラリで、自動ヘルプ生成や複数コマンドのサポートも提供されている。
import PackageDescription
let package = Package(
name: "MyCLI",
dependencies: [
.package(url: "https://github.com/apple/example-package-figlet", branch: "main"),
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
],
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: "MyCLI",
dependencies: [
.product(name: "Figlet", package: "example-package-figlet"),
.product(name: "ArgumentParser", package: "swift-argument-parser"),
],
path: "Sources"
),
]
)
ParsableCommand に準拠させて、@Option
などの修飾子をプロパティに付加することで引数を処理できる。例えば、@Option(help:)
を使用すると、コマンドラインツールのオプションに対して説明文を付加できる。
import Figlet
import ArgumentParser
@main
struct FigletTool: ParsableCommand {
@Option(help: "Specify the input")
public var input: String
public func run() throws {
Figlet.say(self.input)
}
}
$ swift run MyCLI --input 'Hello, world!'
_ _ _ _ _ _ _
| | | | ___ | | | | ___ __ __ ___ _ __ | | __| | | |
| |_| | / _ \ | | | | / _ \ \ \ /\ / / / _ \ | '__| | | / _` | | |
| _ | | __/ | | | | | (_) | _ \ V V / | (_) | | | | | | (_| | |_|
|_| |_| \___| |_| |_| \___/ ( ) \_/\_/ \___/ |_| |_| \__,_| (_)
|/
$ MyCLI --help
USAGE: MyCLI [--verbose] [--filePath <filePath>]
OPTIONS:
--input Specify the input
-h, --help Show help information.