日本人のための SwiftFormat【導入編】

以前の`概要編`・`ルール編` に続き今回は導入編をやっていきたいと思います。ただ、導入方法は、以前の記事で CocoaPods で導入しますと書いていましたが、Swift Package Manager(以降: SwiftPM) で導入していこうかと思います👨‍💻

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292456/39004d63-81ff-fde7-6c8b-c293e4059bca.png)


## 導入手順

今回は、以前の記事でも書いたように [Xcode build phase](https://github.com/nicklockwood/SwiftFormat#xcode-build-phase) + SwiftPM で導入してくので、手順は下記のようなかたちになります。

1. `Package.swift` のセットアップ
2. `.swiftformat` ファイルのセットアップ
3. プロジェクトの `.gitignore` を修正
4. SwiftFormat を実行する Run Script をプロジェクトに追加
5. ビルドして確認


## 作業開始👨‍💻

### 1. `Package.swift` のセットアップ

まずは、SwiftFormat-CLI をインストールするために Swift Package Manager で依存先を指定します。今回は SwiftFormat の [README.md](https://github.com/nicklockwood/SwiftFormat) にあるようにプロジェクトルートに BuildTools ディレクトを作り、その配下に `Package.swift` を作成したいと思います。

```
$ mkdir BuildTools
$ cd BuildTools
$ touch Package.swift
```

ファイルが作成できたら下記のように `Package.swift` に SwiftFormat の依存先情報を書いていきます。

```swift
// swift-tools-version:5.1
import PackageDescription

let package = Package(
    name: "BuildTools",
    platforms: [.macOS(.v10_11)],
    dependencies: [
        .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.41.2"),
    ],
    targets: [.target(name: "BuildTools", path: "")]
)
```

これで、Package.swift のセットアップは完了です。

### 2. `.swiftformat` ファイルのセットアップ

次にプロジェクトルートに SwiftFormat のルール・オプションを定義するための `.swiftformat` ファイルをセットアップします。なおルール・オプションともにデフォルトで問題ないという場合は必要ないですが、プロジェクトで途中から SwiftFormat を導入する場合は、細かくルールを導入していった方がフォーマットの自動更新で異常が発生した時に見つけやすいので、なるべくセットアップした方がいいかと思います。

ファイルを生成します。

```
$ touch .swiftformat
```

今回は [`andOperator`](https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md#andOperator) のみ使用したいので下記のようにファイルを編集します。

```
# file options
--exclude Pods

# opt in rules
--rules andOperator

# enable rules
--enable andOperator
```

`--exclude` で SwiftFormat を適用したくないディレクトリを指定します。また、無効にしたルールについては `--disable` というオプションもあり、特定のルールを無効にできるらしいのですが筆者が試して使って見たところなぜが上手く動作していなかったので、基本的に使用したいルールのみ `--rules` でオプトインするのがベターかと思います🔨 また、デフォルトでは大体のルールが有効になっていますが、一部デフォルトで無効になっているルールなどもあるので、使いたいルールに関しては全て `--enable` で有効化しておくのがいいかと思います。


### 3. プロジェクトの `.gitignore` を修正

次に `BuildTools/.build` と `BuildTools/.swiftpm` をプロジェクトの `.gitignore` に追加しておきます。

```.gitignore

# SwiftFormat
BuildTools/.build
BuildTools/.swiftpm

```

.git でプロジェクトを管理していない場合がこの作業は必要ありませんが、管理している場合はほぼ必須でした方がいいかと思います。特に `BuildTools/.build` 配下の checkout には SwiftPM がクローンしてきたリポジトリがそのまま入るので、依存関係をインストールした後に差分を追加しようとすると、.git の submodule として追加する必要があり面倒くさい思いをします。基本的にはチーム開発する際には Package.swift で記述されたバージョニングで依存関係が統一されるので、追跡対象から外しておきましょう。

### 4. SwiftFormat を実行する Run Script をプロジェクトに追加

次にビルドした時に SwiftFormat を実行できるように Xcode プロジェクトに Run Script を追加していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292456/b19d5750-7e45-e14c-79e0-08b94fe91bc7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292456/dd608baf-74b8-c784-f909-b7ff58e70a47.png)


```
cd BuildTools
SDKROOT=macosx
#swift package update #Uncomment this line temporarily to update the version used to the latest matching your BuildTools/Package.swift file
swift run -c release swiftformat "$SRCROOT"
```

これで、ビルド時に SwiftFormat が実行されるようになりました。


### 5. ビルドして確認

最後に下記のようなコードを追加してちゃんとルールが適用されるか確認してみましょう。

```swift
    func formatTest() {
        let isApple = true
        let isPencil = true

        if isApple && isPencil {
            print("This is Apple Pencil ✍️")
        }
    }
```

ビルドが正常に完了して、下記のようにちゃんとルール通りにフォーマットされることが確認できました🎉

```diff
+    func formatTest() {
+        let isApple = true
+        let isPencil = true
+
+        if isApple, isPencil {
+            print("This is Apple Pencil ✍️")
+        }
+    }
```