久しぶりの投稿となります。
今月から現場が変わってメンテするプロジェクトが変わりました。
私のしばらくの業務は既存のソースコードに溜まっている技術的負債を返済するタスクになるそうです。
で、実際にソースコードを確認したのですが、これを自分がメンテするにはまずはSwiftLint
を導入しないとダメだなと思い先週からSwiftLint
の導入方法を調査していました。
というのも今までは既にSwiftLint
を導入しているプロジェクトに参画していたので自分では導入したことはなかったのですね。
ということ今回はこのSwiftLint
の調査と導入する過程で得られた知見を備忘録として残したいと思います。
SwiftLintについて
ではそもそもSwiftLint
ってなんぞやということから紹介します。
簡単にいうとSwiftのソースコードで独自ルールを設定してそれに沿って既存のソースコードを自動修正していくツールです。ツールですが、実際にはライブラリですので導入にはCocoapodsを使います。
Githubページに移れば分かりますがモバイルアプリのDBでお世話になるRealm
社が提供しているライブラリになります。
このSwiftLintを既存コードに導入するとどのようなメリットがあるかというと
例えば、以下のソースコードがあったとします。
import UIKit
import UIKit // 重複import です
class MainViewController:UIViewController {
@IBOutlet var button:UIButton!
override func viewDidLoad(){
super.viewDidLoad()
}
func sampleMethod()->Int{
var count:Int = 1
count += 1
return count
}
}
パッと見あんまり見たくないコードですよね。できればコードフォーマッタを使って型
のスペース部分とかを修正したいかと思います。その気持ちがあれば十分だと思います。
こういったクラスが2,3個だけならいいのですが、数百個レベルになると個人的には辛くなってくると思います。
そんなあなたにとってはSwiftLint
は大きな味方です。
SwiftLintに既にあるデフォルトのルールを適用させるだけでも上記のコードを綺麗に整えることができます。
例えば、上記のコードは正確には
import UIKit
class MainViewController: UIViewController {
@IBOutlet var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
func sampleMethod() -> Int {
var count: Int = 1
count += 1
return count
}
}
このように修正されます。
これがSwiftLintのパワーです。
あなたがメンテしているコードで上記の部分が該当している場合にはチームリーダーに相談してSwiftLintを導入して見ましょう。
そんなSwiftLintの導入の仕方を紹介します。
SwiftLintの導入方法について
簡単にまとめると
- Cocoapodsに
Swiftlint
を追加するimportする - Run Scriptを追加してとあるコードを差し込む
- ルートディレクトリに
.swiftlint.yml
を追加して最初のルールを簡単に記載する - Terminalで
swiftlint autocorrect
を叩く
たったこれだけの作業でSwiftLintを導入して既存コードを修正していくことができます。
ではそれぞれ説明していきます。
CocoapodsにSwiftLint
を追加してimportする
githubページの解説に従ってpodsを使ってライブラリをimportしましょう。
まずはMacにHomebrew
がない場合はHomebrew
をインストールします。
https://brew.sh/ のトップページにある下記のコマンドを叩いてHomebrew
をインストールしましょう。
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Homebrew
が無事にインストールできたら次のコマンドを叩きます。
brew install swiftlint
これでMacにswiftlintがインポートされます。
それが完了したらCocoaPods
を使ってSwiftLintをインポートします。
pod 'SwiftLint'
そしてterminalで
pod install
を叩くことで無事にSwiftLintがプロジェクトファイルに入ります。
Run Scriptを追加してとあるコードを差し込む
次にSwiftLintを正常に動かすためにプロジェクトファイルのTargets
のところでBuild Phases
の部分で
Run Script
を追加します。
そのRun Scriptを追加してシェル上に次のコードを差し込みます。
if which "${PODS_ROOT}/SwiftLint/swiftlint" >/dev/null; then
${PODS_ROOT}/SwiftLint/swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
これで基本的な設定が完了しました。
[注記]
@uhooi さんのコメントを参照ですが、
if which "${PODS_ROOT}/SwiftLint/swiftlint" >/dev/null; then
swiftlint autocorrect --format
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
と記載するとコミット毎に自動修正が入るようになります。
こちらの方が運用上楽かと思います。
ルートディレクトリに.swiftlint.yml
を追加して最初のルールを簡単に記載する
さてこれからソースコードに適用させるlintのルールを設定していきます。
このルールの把握に時間が取られました。
流石にここはQiitaの次の記事を参考にして設定していきました。
非常にお世話になりましたのでこの場をお借りして感謝のお礼を申し上げます。
そして、続きの説明に入りますが、プロジェクトファイルのルートディレクトリ(簡単に言えばPodfileなどが入ってい階層のこと)に.swiftlint.yml
ファイルを追加します。
ターミナルでルートディレクトに移動したらviコマンドでファイルを追加します。
vi .swiftlint.yml
これでvimが使えるようになるのでルールの詳細がわからない導入期は下記のコードをコピーペーストしましょう。
# 無効にするルール
disabled_rules:
# xcodeでviolation warningが表示されたり違反でXcodeがビルドできないルールを差し込んでいきます。
# デフォルトルール以外でopt-inから適用させるルールの設定
opt_in_rules:
# ここに採用したいルールを追加していく #
# SwiftLintの適用から外すディレクトリ
# (UnitTestやUITestもある場合は修正されますので入れます)
excluded:
# cocoapodsを使っている場合#
- Pods/
# Carthageを使っている場合#
- Carthage/
# 1行あたりの文字数制限を300に変更
line_length: 300
# etc
これをペースとして:wq
で保存します。
これでSwiftLintに適用させたいルールの設定が終わります。
Terminalでswiftlint autocorrect
を叩く
ここまでの設定が終わればあとはTerminalで次のコマンドを叩くだけです。
swiftlint autocorrect
これでちょっと汚いと思われていたコードの箇所が適用クラスに限り自動で修正されます。
自動修正自体はものの5秒程度で完了しますので本当にすぐです。
これでXcodeでソースコードを見ていきましょう。
そしてXcode上で⌘ + B
でビルドして見ましょう。
大体は感動の代わりに落胆になるかと思います。
少なくとも私は落胆しました。
Swiftの標準的な書き方を踏襲していたらそんな違反になることはないと思いましたが私がやって見た限りは
ビルドエラーになってしまいました。
はい。デフォルトルールに違反しているコードが多く存在していました。
例えば、メソッドの命名だったり定数・変数の命名で違反しているところが多かったです。
既存のコードでviolationや違反があってビルドが失敗する場合の対処方法
そこでデフォルトのSwiftLintのルールに違反していてビルドが成功しなかった場合の対処方法を紹介します。
定数・変数レベルでビルドが失敗していた場合には.swiftlint.yml
でルールを緩和していきます。
ただ、.swiftlint.yml
ファイルは通常は非表示ファイルなのでFinder上では見つけられません。
どうするかというと、
ターミナル上で次のコマンドを叩きます。
defaults write com.apple.finder AppleShowAllFiles TRUE
そして、次のコマンドでFinderを一度切ります。
killall Finder
再度、Finderを開くと非表示ファイルが見えるようになります。
これで.swiftlint.yml
をVScodeとかでひらけます。
そしてdisabled_rules
に次のようなルールを入れてそのルールを無効
にしていきます
disabled_rules:
# warningが走るため無効にする
# ビルドが失敗するルールを無効にする
- variable_name
- file_length
- function_body_length
- line_length
- type_body_length
- variable_name_max_length
- variable_name_min_length
- force_cast
- force_try
- shorthand_operator
- empty_count
- cyclomatic_complexity
- type_name
- implicit_getter
このあたりのルールを無効化したらSwiftLintが許してくれるようになりました(笑)。
結構、規約に無視したコードでも割とビルドに成功すると思います。
全体的なファイルをもう一度記載すると
# 無効にするルール
disabled_rules:
# warningが走るため無効にする
# ビルドが失敗するルールを無効にする
- variable_name
- file_length
- function_body_length
- line_length
- type_body_length
- variable_name_max_length
- variable_name_min_length
- force_cast
- force_try
- shorthand_operator
- empty_count
- cyclomatic_complexity
- type_name
- implicit_getter
# デフォルトルール以外でopt-inから適用させるルールの設定
opt_in_rules:
# ここに採用したいルールを追加していく #
# SwiftLintの適用から外すディレクトリ
# (UnitTestやUITestもある場合は修正されますので入れます)
excluded:
# cocoapodsを使っている場合#
- Pods/
# Carthageを使っている場合#
- Carthage/
# 1行あたりの文字数制限を300に変更
line_length: 300
# etc
こんな感じにして再度swiftlint autocorrect
を叩いてXcode上で⌘ + B
して見てください。
これよりひどい場合にはやっぱりビルドは失敗すると思いますが私の場合はこれでなんとかビルドが成功するようになりました。
あとはコミットのたびにswiftlint autocorrect
していけばSwiftLintを適用した快適なSwiftライフが送れるようになると思います。
では以上で記事を終わります。