最近業務で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.