今さらですが、プロジェクトに SwiftLint を導入しました。
現在のバージョンは 0.16.1 です。
インストール
Homebrew でも入れましたが、CI のことも考えて CocoaPods で導入しました。
pod 'SwiftLint'
Build Phase で + New Run Script Phase して以下のスクリプトを設定します。
"${PODS_ROOT}/SwiftLint/swiftlint"
実行の順番は Compile Sources の前にしました。エラーがあればコンパイルの前で止まってくれるので。
チェック結果
ソースを修正する前にチェックした結果ですが、警告が出なかったもの。
- class_delegate_protocol
- closing_brace
- closure_parameter_position
- comma
- custom_rules
- dynamic_inline
- empty_parameters
- empty_parentheses_with_trailing_closure
- function_parameter_count
- generic_type_name
- leading_whitespace
- legacy_cggeometry_functions
- legacy_nsgeometry_functions
- mark
- private_unit_test
- redundant_string_enum_value
- redundant_void_return
- return_arrow_whitespace
- statement_position
- unused_enumerated
- unused_optional_binding
- valid_docs
- valid_ibinspectable
- vertical_parameter_alignment
- weak_delegate
エラーや警告が出たもの。
- colon # 変数名などの後ろのコロン (警告 18)
- compiler_protocol_init # Set(arrayLiteral: elem) -> [elem] (警告 2)
- control_statement # if や switch などの式に () は不要 (警告 7)
- cyclomatic_complexity # 関数の循環的複雑度 (エラー 3, 警告 12)
- file_length # ファイルの行数 (警告 12)
- force_cast # as! (エラー 92)
- force_try # try! (エラー 1)
- function_body_length # 関数の行数 (エラー 3, 警告 15)
- implicit_getter # getter だけなら get 不要 (警告 7)
- large_tuple # タプルは2つまで (エラー 1, 警告 1)
- legacy_constant # CGFloat(M_PI) (警告 3)
- legacy_constructor # NSMakeRange (警告 26)
- line_length # 行の長さ (エラー 59, 警告 867)
- nesting # 型のネストが深い (警告 8)
- opening_brace # { の前にはスペース1個 (警告 3)
- operator_whitespace # 演算子を定義する前後にスペース (警告 5)
- redundant_optional_initialization # ?付き型の変数を nil で初期化する必要なし (警告 2)
- shorthand_operator # += や -= を使おう (警告 3)
- syntactic_sugar # Dictionary<K, V> -> [K: V] (警告 1)
- todo # TODO 残ってます (警告 2)
- trailing_comma # 配列などの最後の要素の後ろにコロン (警告 95)
- trailing_newline # ファイルの末尾に空行 (警告 2)
- trailing_semicolon # 行末にセミコロン (警告 2)
- trailing_whitespace # 行末にスペース (警告 1718)
- type_body_length # 型の行数 (エラー 4, 警告 9)
- type_name # 型名は3〜40文字 (警告 11)
- unused_closure_parameter # クロージャの引数を使わないなら _ に (警告 315)
- variable_name # 型名は3〜40文字 (エラー 121, 警告 39)
- vertical_whitespace # 空行が複数連続 (警告 16)
- void_return # -> () を -> Void に (警告 3)
オプトインのもの。
- attributes # @obj などのアトリビュートは独立した行に (警告 63)
- closure_end_indentation # クロージャの最後の } のインデント (警告 72)
- closure_spacing # なし
- conditional_returns_on_newline # なし
- empty_count # .count == 0 -> .isEmpty (エラー 10)
- explicit_init # なし
- file_header # ファイルの先頭のコメントの書式 (警告 52)
- first_where # .filter {...}.first -> .first {...} (警告 9)
- force_unwrapping # ! 使うな (警告 49)
- missing_docs # public にはドキュメント (警告 2)
- nimble_operator # なし
- number_separator # 3桁ごとに _ (警告 40)
- object_literal # UIImage(named: ...) をどうしろと? (警告 100)
- operator_usage_whitespace # 演算子を使用する前後にスペース (警告 6)
- overridden_super_call # メソッドを override したら super を呼ぶ (なし)
- private_outlet # @IBOutlet は private にすべし (警告 44)
- prohibited_super_call # なし
- redundant_nil_coalescing # なし
- sorted_imports # import をアルファベット順に (警告 31)
- switch_case_on_newline # なし
設定
チェック結果を踏まえて、とりあえず以下の設定としましたが、随時見直す予定です。
# MyAppフォルダのソースのみを対象とする。
included:
- MyApp
# 無効にするルール。
disabled_rules:
- cyclomatic_complexity
- file_length
- force_cast
- force_try
- function_body_length
- legacy_constant
- legacy_constructor
- large_tuple
- line_length
- nesting
- operator_whitespace
- redundant_optional_initialization
- todo
- trailing_comma
- type_body_length
- type_name
- unused_closure_parameter
- variable_name
- vertical_whitespace
# デフォルト無効のルールのうち、有効にするもの。
opt_in_rules:
- closure_spacing
- conditional_returns_on_newline
- explicit_init
- nimble_operator
- operator_usage_whitespace
- overridden_super_call
- prohibited_super_call
- redundant_nil_coalescing
- switch_case_on_newline
# 空行のスペースを許容する。
trailing_whitespace:
ignores_empty_lines: true
空行のスペースについては、最初は以下の custom_rules でやろうと思いましたが、SwiftLint の Issues を検索してこの pull request で ignores_empty_lines を知りました。
(ちなみに、custom_rules の regex は .dotMatchesLineSeparators が有効になっているので、改行にマッチしたくない場合は . の代わりに [^\n] を使う必要があります。)
disabled_rules:
- trailing_whitespace
custom_rules:
trailing_whitespace_in_non_empty_line:
regex: "[^ \t\n][ \t]+$"
各ルールの設定については、swiftlint rules の結果にも書いてありました。
$ swiftlint rules
+-----------------------------------------+--------+-------------+------------------------+-----------------------------------------------------------------------------------------------------+
| identifier | opt-in | correctable | enabled in your config | configuration |
+-----------------------------------------+--------+-------------+------------------------+-----------------------------------------------------------------------------------------------------+
...
| trailing_whitespace | no | yes | yes | warning, ignores_empty_lines: false, ignores_comments: true |
...
+-----------------------------------------+--------+-------------+------------------------+-----------------------------------------------------------------------------------------------------+
(select * from rules where opt-in = no とかできればいいのに…。)