SwiftLintはDangerと組み合わせてこそ初めて真価を発揮してくれる


TL;DR

  • SwiftLintの設定方法
  • fastlaneのdangerアクション
  • Bitriseにトークン設定
  • Pull Requestに対して勝手にレビュー!

前書き

Swiftの開発だけでなく, 集団で開発するときに静的解析ツール(Lint)いれますよね.
例に漏れず, SwiftにもLintが存在しますが, Lintは導入しても一時的にオフにして開発などをされてしまうと効果を発揮しない場合があります.

そしてそのままPRで上がってきたときに, 本来Lintの時点で直すべきところをレビューしなきゃいけなくなってしまうことがあるんですよね.
これ言う側も言われる側もけっこう嫌だと思うんですよ笑
なので, PRが出た時点でDangerを使うことで精神衛生を保とうね, というのが目的です.

※ 今回はBitrise/fastlaneを使うことを前提としています

SwiftLint

SwiftLintとは?

改めてSwiftLintについてですが, Swift用の静的解析ツールです.
ネストの深さ, KeyValueのコロンの後はスペース一つ開ける, などのルールを自分の開発環境に合わせてチェックさせることができます.

SwiftLintのGitHubリポジトリ
https://github.com/realm/SwiftLint

設定方法

まずはGemfileとPodfileの設定をします

Gemfile
gem 'danger'
gem 'danger-swiftlint' 
Podfile
# Uncomment the next line to define a global platform for your project
platform :ios, '10.0'

target 'MyApp' do
  use_frameworks!

  pod 'SwiftLint'
end

次にアプリケーションのディレクトリ直下に.swiftlint.ymlファイルを用意します.

.swiftlint.yml
excluded:
  - Carthage
  - Pods

opt_in_rules:
  - empty_count
  - explicit_init
  - closure_spacing
  - overridden_super_call
  - redundant_nil_coalescing
  - private_outlet
  - nimble_operator
  - attributes
  - operator_usage_whitespace
  - closure_end_indentation
  - first_where
  - object_literal
  - number_separator
  - prohibited_super_call
  - fatal_error_message

disabled_rules:
  - trailing_whitespace
  - cyclomatic_complexity
  - function_body_length
  - type_name
  - shorthand_operator
  - multiple_closures_with_trailing_closure
  - closure_end_indentation
  - empty_count
  - identifier_name
  - force_cast
  - file_length
  - type_body_length
  - unused_setter_value
  - function_parameter_count
# Custom rules
identifier_name:
  min_length: 1
force_cast: warning
force_try:
  severity: warning
number_separator:
  minimum_length: 5
large_tuple: 3

Lintのルールに関してはすべて説明はしきれないので, ぜひ公式のリポジトリをご覧ください.
SwiftLintの導入はここまでです.

もし開発中のビルドの度に静的解析を行うのであれば, Xcode上で設定を行うのですが, 今回はその説明は割愛します.
あくまでもGitHub上での静的解析の方法の説明とさせていただきます.

fastlaneのdanger action

fastlaneではデフォルトでdangerをサポートしていて, .swiftlint.ymlを使って静的解析をすることが可能です.

fastlane dangerの公式ドキュメントはこちら.

Stepは二つでとても簡単です.

1. Dangerfileを準備

アプリケーションのディレクトリ直下にDangerfileを配置します.

Dangerfile
# Check and comment on swiftlint only in the range corrected by PR
github.dismiss_out_of_range_messages
swiftlint.config_file = '.swiftlint.yml' # ここで.swiftlint.ymlのパスを指定
swiftlint.lint_files inline_mode: true

2. Fastfileでdanger actionを記述

今回はPull Request時にDangerを発火させたいので, Pull Request時に走るlaneの中にdanger actionを記述しましょう.

Fastfile
desc "Pull Request時に走るlane"
  lane :run_when_pr do |options|
    cocoapods

    danger # <- ここでdanger actionを記述!

    match

    gym

    crashlytics
  end

基本的にはオプションを指定しなくても, このように書くだけで動くはずです.
danger以外のactionは適当なので, 適宜設定してください.

Bitriseにトークン設定

BitriseのWorkflowのSecretsタブにDANGER_GITHUB_API_TOKENを設定します.

GitHubのトークンの取得の仕方は↓の記事にわかりやすくまとめられています.
GitHub「Personal access tokens」の設定方法

Pull Requestに自動レビュー

あとはPull Requestを出してみましょう.
静的解析にひっかかると, こんな感じで勝手にレビューしてくれるようになります!

まとめ

SwiftLint, せっかく導入するのであれば確実に機能させたいということで, Pull Request時に行えるのはとても有益なのではないかと思います.
レビューを自動化することで小さなイライラを減らして, 精神的に健康な開発ライフを送りましょう!