Help us understand the problem. What is going on with this article?

Swift lint

More than 3 years have passed since last update.

Swift lintを使ってみる

これ使ってみてーってswift lintと、それを紹介している勉強会の動画を渡されたけど、最後まで聞くことに耐えられなれなかった、、、
何度か目の再生停止で、原文当たった方が幸せじゃない?と気付いたので、ついでに自分なりにまとめておく。

ちなこれ
realm/SwiftLint: A tool to enforce Swift style and conventions.

なにそれ

lintってのは聞いたことはあった。文法解析して、なんかエラー出すやつ。それのswift版。らしい。
うまく設定することで、指定したルールに沿わない書き方を見つけるとエラーやワーニングとして騒いでくれるとのこと。全く余計なお世話 ありがたや。
チーム作業でコーディング規約を強制させたい場合にきっと便利。

セットアップ

Homebrewは気持ち悪いので使いません。
どうせ自分では使わないだろうしプロジェクトのgitにそのまま突っ込む。

cd <project_dir>
git submodule add https://github.com/realm/SwiftLint.git

するとディレクトリが作れられてくれるので、インストールしとく。途中で管理者権限を要求されます

cd swiftLint; make install

続いて、Xcode Projectに呼び出しを仕込む。
TargetのBuild Phaseを開いて、左上の「+」でNew Run Script Phaseを追加。エラー文をちょっと弄ってある。

if which swiftlint >/dev/null; then
  swiftlint
else
  echo "warning: SwiftLint not installed. To install, run 'cd <proj_dir>/swiftLint; make install'"
fi

lintなので、Compile Sourcesの次くらいに実行されるように
マウスドラッグで移動させておく。

cmd-bでビルドして、エラーとワーニングが山のように量産されてlint氏ね わーすごいやーってなったら成功。

設定ファイルを作る

設定ファイルはプロジェクトのディレクトリに.swiftlint.ymlを置いとけばいいらしい。

とりあえずPodsとSwiftLintを排除。

cd <project_dir>
vi .swiftlint.yml
# Swift Lint Rules

excluded: # excluded directory
  - Pods
  - SwiftLint

ちなみにコード中に特定記法のコメントを書くことでも操作できるらしいけど、どうせやらない。し、本来的にやるべきでもない。

// swiftlint:disable <rule>
// swiftlint:enable <rule>
let noWarning2 = NSNumber() as! Int // swiftlint:disable:this force_cast

設定を書いてく

ワーニング うぜええええええ!!!!
…となるので、順番に殺していく。

trailing_whitespace.png

最後の(trailing_whitespace)に注目。これがルール名らしい。

ルールについてはソース読んでね!という公式の投げっぷり

See the Source/SwiftLintFramework/Rules directory to see the currently implemented rules.

なので、もうなんとでもなーれ、って気持ちで眺めましょう。

// SwiftLint/Source/SwiftLintFramework/Rules/TrailingWhitespaceRule.swift
public func validateFile(file: File) -> [StyleViolation] {
        return file.lines.filter {
            $0.content.hasTrailingWhitespace()
        }.map {
            StyleViolation(ruleDescription: self.dynamicType.description,
                severity: configuration.severity,
                location: Location(file: file.path, line: $0.index))
        }
    }

なんだ、このクソ実装...
空行の場合は例外視とか普通つけるでしょ、、、なんで設定の余地ないの?

こういうケースの時とか…
emptyline_tailingspace.png

というような場合は disabled_rules: に書いてあげるとルールが無効になり、平和が訪れます。

disabled_rules:
  trailing_whitespace #since has no option to treat empty line,,,

追記した後にもう一回cmd-bしてみると、ちゃんとワーニングが消えます。
よしよし。

あとは無意味に厳しい行数制限をテキトーに緩めたりとか

line_length: #max length of each line
  warning: 200
  error: 500

type_body_length: #max line num of class body
  warning: 1000
  error: 3000

と、いうように、まずはルールを殺戮し尽くすところから始めるべきらしい。です。

とりあえず、現状、こんな感じ。完全に個人的な主観です。

disabled_rules:
# vvv will never enable
  - trailing_whitespace
  - opening_brace
  - closing_brace
  - statement_position
  - todo
  - force_cast
  - force_try
  - file_length
  - cyclomatic_complexity
# vvv may enable in someday
  - return_arrow_whitespace
  - control_statement
# vvv may enable in nearday
  - legacy_constructor
  - legacy_constant
  - trailing_newline
#

カスタムルール

ここまでで標準のルールの残念さ加減に気付いた皆さんに嬉しいお知らせで、なにやらカスタムルールも定義できるらしいです。
正規表現を書いてあげると良いらしい。

例えば、こんな感じ。
classやfuncの宣言の間には1行空行を入れましょう、というやつ。

custom_rules:

  spacer_line:
    name: "Spacer Line"
    regex: "(\}\n)([ \t]*)((public )|(private )|(internal )|(override ))*((class)|(func))"
    message: "Need empty line between func or class"
    severity: error

あとmatch_kinds形態分析結果ので絞り込めるっぽいのだけど、どれがどんな要素として扱われるのかがナゾで使い物にならないのが残念。
(現時点では)気合の正規表現で無理やり誤魔化すしかなさそう。

感想

最初のエラーの数には呆れたけど、いらないのをガンガンとブラックリストに突っ込んで機能を絞り込めばそこそこ使えそう。
warning/errorがXcode上で扱えるので、ビルド遅くなる以外は良さそう。

コロンがどこにあろうと(読み易ければ)なんでもいいや、な自分としては、規約違反はwarning出すようにしといて、commit前にちょろっと整えるようにするくらいで使うと結構便利かもしれない。
なお、自分は{をifの次行に書くことは許さない教なので、そういったところは戦争・・・もとい、事前の話し合いが重要かと思います。

その他

すっげーたくさんエラー出てるなあ。でもコードに見覚えないなー、、、
と思ったらSwiftLintが自分自身のコードに対して評価してワーニングとエラー吐きまくってたの、すっごくロックだわね…

touta
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした