使用 Swift Package Manager 建立 Command line tool
Command line tool 有時候可以方便的處理一些常見的任務,有時候可以將開放中遇到的瑣碎事情自動化處理,例如 XcodeGen就是一個有趣的應用。這篇文章將教你如何使用 Swift Package Manager(SPM) 與 Linux/Unix 互動。
先備知識
- 基礎 Swift 語法知識,若以 Swift.org 的Language guide 目錄為標準,則是
The Basic
至Methods
。 - 基礎 Swift
Package.init
參數使用,如name
,dependencies
,targets
。 - 基礎 Linux 語法知識,如
ls -alR
,Date
,whoami
。
建立可執行的SPM - Hello world
我們可以使用 Swift package manager 來建立一個新的 Package project。 如果你對 terminal 熟悉的話,可以閱讀更詳細的文件: Swift-package-manager/Usage.md。
$ swift package init --type executable --name helloworld
這段指令執行了一下事情: 在當前目錄建立一個名為 helloworld
的 可執行的Swift package。
你可以看到當前目錄建立了一些檔案,下面是使用 tree
的檔案夾結構:
.
├── Package.swift
├── README.md
├── Sources/
│ └── helloworld/
│ └── main.swift
└── Tests/
├── LinuxMain.swift
└── helloworldTests/
├── XCTestManifests.swift
└── helloworldTests.swift
這時我們可以透過以下指令直接執行這個程式
$ swift build
$ swift run
Hello, world!
如此一來就完成基礎的 Command line tool 了!
Package.swift
取代了 .xcodeproj
若是你有 Xcode 11, 可以直接打開 Package.swift
就會自動 link 所有檔案並建立 .swiftpm
$ open Package.swift
可以看到 Package.swift 成為在 XCode 的第一個檔案,以往熟悉的 .xcodeproj
不見了。
在執行檔使用第三方函式庫
在這裏我們為 helloworld 增加讀取 arguments 的功能,我們可以使用其他已經完善的第三方函式庫,這次我們使用 SPMUtility
, 這是來自 Apple 的開源專案,SPM 可以透過 Git 目錄的讀取,執行套件管理並安裝到專案中。我們在 Package.swift
中套用以下的修改:
// swift-tools-version:5.1
import PackageDescription
let package = Package(
name: "helloworld",
dependencies: [
.package(url: "https://github.com/apple/swift-package-manager.git", from: "0.1.0")
],
targets: [
.target(
name: "helloworld",
dependencies: ["SPMUtility"]),
.testTarget(
name: "helloworldTests",
dependencies: ["helloworld"]),
]
)
因為函式庫的大小較大,建議網路速度較慢的讀者在這裏先回到 terminal 執行
swift build
。
要注意一旦編輯 Package.swift
檔後,必須使用主動儲存變更,XCode 才會更新專案,我們可以使用 File > Save 來主動儲存。
使用 SPMUtility
讀取 Arguments 與支援其他應用。
為了實現讀取 Arguments 的功能,我們要到 main.swift
編寫程式碼!
首先,通過 import Foundation,我們取得使用者輸入的 Arguments。
import Foundation
import SPMUtility
let arguments = ProcessInfo.processInfo.arguments[1...]
print("Hello, world!")
使用 ArgumentParser 使 Swift 可以讀取 Arguments。
let parser = ArgumentParser(usage: "<options>", overview: "A Swift command-line tool to say hello")
let nameArgument = parser.add(option: "--name", shortName: "-n", kind: String.self, usage: "The name to greeting")
let repeatArgument = parser.add(option: "--repeat", shortName: "-r", kind: Int.self, usage: "The repeat count of Hello")
我們建立了單一 Parser,加入兩個可用的參數,--name
和 --repeat
,透過 shortName 的參數建立各自的別名,kind 則建立指定的 Swift 型別。
接下來我們透過邏輯完成這個應用程式。
import SPMUtility
import Foundation
let arguments = ProcessInfo.processInfo.arguments[1...]
let parser = ArgumentParser(usage: "<options>", overview: "A Swift command-line tool to say hello")
let nameArgument = parser.add(option: "--name", shortName: "-n", kind: String.self, usage: "The name to greeting")
let repeatArgument = parser.add(option: "--repeat", shortName: "-r", kind: Int.self, usage: "The repeat count of Hello")
do {
let parsedArguments = try parser.parse(Array(arguments))
let name = parsedArguments.get(nameArgument) ?? "world"
var repeatCount = parsedArguments.get(repeatArgument) ?? 0
repeatCount = repeatCount > 0 ? repeatCount : 1
var helloRepeat = ["Hello"]
for _ in 1..<repeatCount {
helloRepeat.append("hello")
}
let holloSentence = helloRepeat.joined(separator: ", ")
print("\(holloSentence), \(name)")
} catch {
print("helloworld greeting failed: \(error)")
}
現在,我們來測試看看!在 terminal 裡執行以下指令,你應該看到應用程式的結果。
$ swift run helloworld --name yu --repeat 3
Hello, hello, hello, yu
ArgumentParser 同時也提供 --help
的功能。
$ swift run swift run helloworld --help
OVERVIEW: A Swift command-line tool to say hello
USAGE: helloworld <options>
OPTIONS:
--name, -n The title to greeting
--repeat, -r The repeat count of Hello
--help Display available options
將 SPM 打包並安裝到 Unix 上
在經歷了各種測試後,我們的 helloworld 已經可以作為一個日常的使用工具,透過以下的方式,將執行檔安裝到 terminal 上。
$ swift build --configuration release
$ cp -f .build/release/helloworld /usr/local/bin/helloworld
如此一來,就可以使用了!
$ helloworld --help
OVERVIEW: A Swift command-line tool to say hello
USAGE: helloworld <options>
OPTIONS:
--name, -n The title to greeting
--repeat, -r The repeat count of Hello
--help Display available options
以上,就是如何製作一個CLI!