やること
- Swiftでコマンドラインツールを作る
- プロジェクト構成などがCarthageとだいたい同じものを作る
- 依存管理にCarthageを使用する
やらないこと
- 自分で作ったコマンドを
brew install
出来るようにする
Github
大体同じ手順で作業してcommitしたので、多少参考になるかもしれない。
XcodeでProjectを作る
最初に作るのはCocoa Applicationです。
今回は凄いツールを作ります。適宜自分が作るプロジェクトに置き換えて下さい。
Cocoa Framework
のTargetを追加する
Frameworkの名前はプロジェクト名にKitを付けたやつにします。適宜変更したりいろいろして下さい。
作ったTargetのschemeを共有設定にする
方法は適宜ぐぐって下さい。
全てをまとめるWorkspaceを作る
さっき作ったxcodeprojを一旦閉じてSugoiTool.xcworkspace
を作り、SugoiTool.xcodeproj
を追加します。
ここからはWorkspaceを見て作業します。
Carthage
github "Carthage/Commandant"
$ carthage update --use-submodules --platform mac
carthage update
してCheckoutされたプロジェクトをSugoiTool.xcworkspace
に追加します。
SugoiToolKit
にFrameworkを追加する
Carthage/Build/Macの中の**.framework*をSugoiToolKit
のGeneral -> Linked Frameworks and Librariesにドラッグアンドドロップする。
↓Build PhasesにCopy Filesを追加してFrameworkがコピーされるようにする。
SugoiTool
のファイルを一通り消す
プロジェクトをここまで手順通りにやっていればInfo.plist
を残して全て消す。
main.swift
を追加する
SugoiTool
にmain.swift
を追加する。
main.swift
にprint("Hello")
とか書いて、Cmd+RでHello
って出力されるはず。
コマンドを実装する
プロジェクトの構成的に、SugoiToolKit
にコマンドの実装とテストを置いて、SugoiTool
の方からそれを使うというような感じにする。
SugoiToolKit
にコマンドの中身を実装する
public struct Sugoi {
public let isSugoi: Bool
public init(isSugoi: Bool) {
self.isSugoi = isSugoi
}
public func command() -> String {
if isSugoi {
return "凄い"
}
return "普通"
}
}
適宜テストを書いて下さい。
テストを実行する
import XCTest
@testable import SugoiToolKit
class SugoiTests: XCTestCase {
func testSugoi() {
let sugoi = Sugoi(isSugoi: true)
XCTAssertEqual(sugoi.command(), "凄い")
}
func testSugokunai() {
let sugoi = Sugoi(isSugoi: false)
XCTAssertEqual(sugoi.command(), "普通")
}
}
SugoiToolKitTests
のGeneral -> Host ApplicationをNone
にするとテスト実行できるようになる
SugoiTool
にコマンドを実装する
import Commandant
import SugoiToolKit
import Result
public struct SugoiCommand: CommandType {
public let verb = "sugoiCommand"
public let function = "このコマンドが凄いかどうかを表示する"
let sugoi = Sugoi(isSugoi: true)
public func run(options: NoOptions<NSError>) -> Result<(), NSError> {
print(sugoi.command())
return .Success(())
}
}
main.swift
でコマンドを登録する
import Commandant
let registry = CommandRegistry<NSError>()
registry.register(SugoiCommand())
let helpCommand = HelpCommand(registry: registry)
registry.register(helpCommand)
registry.main(defaultVerb: "help") { error in
fputs("\(error)\n", stderr)
}
ここまで来たら、ビルドは通るけど実行するとUnrecognized command
とか表示される状態になってると思います。
コマンドラインから実行できるようにする
Makefile
を追加する
これを追加します。
SugoiTool
にComponents.plist
を追加する
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>BundleIsVersionChecked</key>
<false/>
<key>BundleOverwriteAction</key>
<string>upgrade</string>
<key>ChildBundles</key>
<array>
<dict>
<key>BundleOverwriteAction</key>
<string></string>
<key>RootRelativeBundlePath</key>
<string>Library/Frameworks/SugoiToolKit.framework/Versions/A/Frameworks/Commandant.framework</string>
</dict>
<dict>
<key>BundleOverwriteAction</key>
<string></string>
<key>RootRelativeBundlePath</key>
<string>Library/Frameworks/SugoiToolKit.framework/Versions/A/Frameworks/Result.framework</string>
</dict>
</array>
<key>RootRelativeBundlePath</key>
<string>Library/Frameworks/SugoiToolKit.framework</string>
</dict>
</array>
</plist>
XcodeからComponents.plist
を追加して、↑これと同じ状態になるようにして下さい。
ChildBundlesは適宜変更して下さい。
make install
してみる
$ make install
$ /usr/local/bin/SugoiTool
dyld: Library not loaded: @rpath/Commandant.framework/Commandant
Referenced from: /usr/local/bin/SugoiTool
Reason: image not found
[1] 55628 trace trap /usr/local/bin/SugoiTool
😵
SugoiTool
, SugoiToolKit
の設定を変える
SugoiToolKit
Build Settings -> Embedded Content Contains Swift Code
Yes
にする
Build Settings -> Runpath Search Paths
$(inherited)
@executable_path/../Frameworks
@loader_path/../Frameworks
の3つを設定する
SugoiTool
Build Settings -> Runpath Search Paths
@executable_path/.
@executable_path/SugoiToolKit.framework/Versions/Current/Frameworks
/Library/Frameworks
/Library/Frameworks/SugoiToolKit.framework/Versions/Current/Frameworks
$(inherited)
の5つを設定する。SugoiToolKit
の部分は適宜変更する
make install
してみる
$ make install
$ /usr/local/bin/SugoiTool
Available commands:
help Display general or command-specific help
sugoiCommand このコマンドが凄いかどうかを表示する
$ /usr/local/bin/SugoiTool sugoiCommand
凄い
すごい!!!!!!!!!!!!!!!!!!!!!!!!!!
参考
-
https://github.com/Carthage/Carthage
- Runpathはまるっとそのままコピペしたので、不要な設定もあるかもしれない
- Makefileを編集して使った
-
Components.plist
を編集して使った