普段のiOS開発において、ファイルを追加するたびにProject Navigator上のファイルをソートしていると思います。
開発中、ファイル名が正しくソートされていないのを見つけてソートしてみるも、本筋と関係ない project.pbxproj の変更が含まれてレビュアーを困惑させることがあります。
これを解決させるためのスクリプトを作りました。
作ったもの
-
WorldDownTown/SortPbxproj
- Swift Package Managerでコマンドラインツールを作りました
- Homebrewからインストールすることができます
インストール
$ brew install WorldDownTown/taps/sort-pbxproj
使い方
$ sort-pbxproj $SRCROOT/Path/To/Project.xcodeproj
or
$ sort-pbxproj $SRCROOT/Path/To/Project.xcodeproj/project.pbxproj
このようにProject Navigator上のファイルやBuild Phase のCompile Sources 内のファイルもソートされます
before | after |
---|---|
自動化
- XcodeのRun Script や
.git/hooks/pre-commit
などに書けば自動的にソートできるようになります - プロジェクトで共有する場合はコマンドの有無を確認すると優しいですね
if type sort-pbxproj > /dev/null 2>&1; then
sort-pbxproj $SRCROOT/Path/To/project.pbxproj
fi
ベースとなっているもの
-
webkit/sort-Xcode-project-file
- WebKit の開発で使われている Perl スクリプト
- WebKit 固有の要件に合わせたロジックも含まれています
実装について
ロジック
下記のようなシンプルな流れになっています
- pbxprojを一行一行読み込む
- 正規表現でソート対象行を特定
- ソート対象業ではファイルの名前を基準にソート並べ替える
- tmpファイルに書き込んで行く
- すべての行を読み込み終わったら、tmpファイルを
project.pbxporj
にリネームして終了
コマンドライン引数
--no-warnings
オプション
- デフォルトでは 与えられたパスに読み込み可能な
project.pbxproj
があるかチェックしており、見つからなかった場合には終了スクリプトを終了させます - 別名を使っている場合などを考慮して、そのチェックを省略するようなコマンドラインオプション
--no-warnings
を用意しています- 別名を使うことがあるのか正直よくわかりませんが、本家 WebKit版 を踏襲しました
- コマンドラインオプションを実装したかっただけなので、将来消すかもしれません……
実装
- コマンドラインの引数とオプションは CommandLine.arguments から取得できますが、型は
[String]
となっていて、スクリプト名や引数・オプションの区別はないためとても扱いやすいとは言えません -
kylef/Commander を使うことで簡単に実装することができました
- Swift Package Manager の dependencies に含めています
- 引数やオプションを宣言的に書くだけで実装できるうえに、
--help
も自動的に実装されるため実装コストがかなり抑えられました
// main.swift
import Commander
private func main(path: String, suppress: Bool) throws {
// ソート処理
}
command(
Argument<String>("path", description: "File path to *.xcodeproj or project.pbxproj"), // 引数
Flag("no-warnings", description: "ignore file path is valid or not"), // オプション
main).run()
まだやってないこと
- ユニットテスト
- ユーザーに優しいエラーメッセージ表示
- Homebrew の Bottles 対応 (バイナリ形式の配布)
- Project Navigator のグループの中のグループは上にソート並ぶようなオプション
追記
2018/12/05 00:10
Project Navigator のグループの中のグループは上にソート並ぶようなオプション
私の勘違いで webkit/sort-Xcode-project-file でも SortPbxProj でも、オプションではなくデフォルトの機能としてすでに実装されていました😅 (リンク先が該当の処理です)