最近業務でESLintをいじっていて、そういえばSwiftにもLinterってあるのかなと思って調べたらあった。
Realmがつくっているんですね
Linterとは
ざっくばらんにいえばコードの品質チェックツールみたいなもので、具体的には「1行における文字数が長すぎないか」「ネストが深すぎないか」みたいなことをチェックしてくれます。動的型言語(少なくともJavascript)ではかなり使われるのではないかと思います。
またコードレビューにおいて書き方がコーディング規約に沿っていないかをレビュアーが目視するよりも、Linterにまかせてしまおうという考え方もあると思います
実行環境
- Xcode
7.0 (7A220) - SwiftLint
0.3.0
インストール
homebrewを使う
brew install swiftlint
ソースからビルドする
SwiftLintをcloneしてきて
git submodule update --init --recursive; make install
セットアップ
Build PhasesのRun Scriptにて、以下のスクリプトをコピペする(わかりづらかったらREADME直接みてください!)
if which swiftlint >/dev/null; then
swiftlint
else
echo "SwiftLint does not exist, download from https://github.com/realm/SwiftLint"
fi
Lintをかけてみる
インストール、セットアップが済んだら早速ビルドしてみましょう。
個人でリリースしているTwitter読み上げクライアントアプリ**Twitilized**のプロジェクトで試してみたのですが、こんな感じの警告やエラーが出るようになりました
↑「クラス内の行数は200行以内におさめるべきだけど423行になっています」と。
↑「1行の文字数は100字以内におさめるべきだけど285文字になっています」と。
厳しすぎる!!w
下のものに至っては、デフォルトで生成されるコメントだし・・・。
ということで、SwiftLintでは「各チェック項目のパラメータのカスタマイズ」や「そもそもこのチェック項目はうちのプロジェクトでは適用しない」などの設定ができるので、それをやってみたいと思います
設定ファイル
プロジェクトのルートディレクトリに.swiftlint.ymlというファイルをつくります。中身としては、以下のようなものになります
disabled_rules: # 適用したくないチェック項目を記述
- line_length
included: # Lint対象のファイルのあるパスを記述、通常はプロジェクト名になると思います
- Twitilized
excluded: # Lint対象から外すファイルのあるパスを記述、CocoaPodsやCarthage
- Pods
# パラメータ(ここではline_lengthの値)をカスタマイズする、warningを出す値でerrorは出なくなる
line_length: 360
# パラメータ(ここではtype_body_lengthの値)をカスタマイズする、最初の値がwarningで2つ目の値がerror
type_body_length:
- 400 # warning
- 500 # error
ということでdisabled_rulesにline_lengthを書いてあげて、included, excludedともに正しく設定して保存し、再度ビルドしてみます。これでさきほどのエラーが消えるかなと思ってやってみると・・・とくに変わりなし。
色々やってみて、どうも設定ファイルが効いていないみたいだなと思ってissuesをみてみると、以下のようなissueがあった
少なくとも自分が試したときだと、homebrewでインストールしたものだと正しく動かなかったので、ソースからインストールしなおすと、、、.swiftlint.ymlが正しく反映されて、無事エラーも消えた!!
チェック項目
基本的にはGithubのスタイルガイドを参考にしているらしく、
swiftlint rules
で確認できます。以下そのまま貼っておきます
- Line Length (line_length): Enforce maximum line length
- Leading Whitespace (leading_whitespace): This rule checks that there's no leading whitespace in your file.
- Trailing Whitespace (trailing_whitespace): This rule checks whether you don't have any trailing whitespace.
- Returning Whitespace (return_arrow_whitespace): This rule checks whether you have 1 space before return arrow and return type. Newlines are also acceptable.
- Trailing Newline (trailing_newline): Files should have a single trailing newline.
- Operator Function Whitespace (operator_whitespace): Use a single whitespace around operators when defining them.
- Force Cast (force_cast): This rule checks whether you don't do force casts.
- File Line Length (file_length): Enforce maximum file length
- Todo (todo): This rule checks whether you removed all TODOs and FIXMEs.
- Colon (colon): This rule checks whether you associate the colon with the identifier.
- Type Name (type_name): Type name should only contain alphanumeric characters, start with an uppercase character and between 3 and 40 characters in length.
- Variable Name (variable_name): Variable name should only contain alphanumeric characters, start with a a lowercase character and be between 3 and 40 characters in length. In an exception to the above, variable names may start with a capital letter when they are declared static and immutable.
- Type body Length (type_body_length): Enforce maximum type body length
- Function Body Length (function_body_length): Enforce maximum function length
- Nesting (nesting): Types should be nested at most 1 level deep, and statements should be nested at most 5 levels deep.
- Control Statement (control_statement): if,for,while,do statements shouldn't wrap their conditionals in parentheses.
- Opening Brace Spacing (opening_brance): Check whether there is a space before opening brace and it is on the same line.
- Comma Spacing (comma): One space before and no after must be present next to any comma.
- Statement Position (statement_position): This rule checks whether statements are correctly positioned.