SwiftLintで特定のルールを特定のディレクトリだけ除外する方法

やりたいこと

「テストクラス(≒テストディレクトリ)ではfatal_error_message(fatal errorを投げる時はメッセージ付きにすること)ルールは除外する」というように、特定のルールを特定のディレクトリだけ除外するということをやりたかったのでその方法について説明します。

結論から言うと、Nested Configurationsを使って基本は有効にするものの、特定のディレクトリでは無効にするという設定を.swiftlint.ymlという作業をすれば良いです。

解決方法

このissueの情報を元に書きます。

前提知識:Nested Configurations

今回Nested Configurationsの知識があった方がわかりやすいので、SwiftLint0.22で導入されたNested Configurationsについて図を使いつつ説明しておきます。
※図は過去の登壇資料から持ってきています。

■0.22より前

子ディレクトリ内では子ディレクトリに存在するswiftlint.ymlしか適用されませんでした。

■0.22以降

子ディレクトリで適用される.swiftlint.ymlは、親ディレクトリの.swiftlint.ymlとマージされたものが適用されます。

yml記述例

Nested Configurationsがわかったところで、実際の解決方法に入っていきます。今回はデフォルトでDisabledのfatal_error_messageを、テストディレクトリのみdisabledにします。

まずルート直下の.swiftlint.ymlは以下のように記述します。

opt_in_rules:
  - fatal_error_message

次にテストディレクトリ直下に以下の.swiftlint.ymlを置きます。

disabled_rules:
  - fatal_error_message

テストディレクトリに.swiftlint.ymlを置いていなければfatal_error_messageが全てのディレクトリで有効になってしまいますが、上記の通りにすることによって2つのymlがマージされた時にどうやらdisabledの方が優先されるらしく、結果的にテストディレクトリではfatal_error_messageを適用対象外にすることができます。

おまけ:exculedではダメ?

.swiftlint.ymlにはexculedというキーワードがあります。
最初これでできたりするんじゃないかと思ったのですが、どうやらSwiftLint側ですでに用意しているルールに対してexculedキーワードを使う場合は「除外する文字列」が記述対象のようです。

SwiftLintのConfigurationより

既存ルールへのexculedの使用例
identifier_name:
  excluded: # excluded via string array
    - id
    - URL

一方カスタムルールにおけるexculedは「除外するパス」が記述対象のようです。

SwiftLintのDefining Custom Rulesより

カスタムルールへのexculedの使用例
custom_rules:
  pirates_beat_ninjas: # rule identifier
    excluded: ".*Test\\.swift" # regex that defines paths to exclude during linting. optional

おまけ:ディレクトリ単位ではなくファイル単位で指定する場合は?

Disable rules in codeに書かれているように、次のコメントでdisableにするルールを指定すれば良いです。
// swiftlint:disable <rule1> [<rule2> <rule3>...]
このコメントで無効にされたルールは、以下のコメントが出て来るまで無効になります。
// swiftlint:enable <rule1> [<rule2> <rule3>...]

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.