1. Coding Conventions
Coding Conventionsとはプログラミングの一般的な原則です。Coding Conventionをちゃんと守とソースコードが読みやすく、理解しやすくになって、ソースコード管理とプロジェクトのメンテナンスは簡単になります
プログラミング言語の種類ごとに、Coding Conventionsがあります。 そして、それらの原則は固定されていません。開発チーム内で決めて、チームメンバーがその通りすれば良いと思います。
Swift について、このURLを参照しましょう: https://github.com/raywenderlich/swift-style-guide
2. SwiftLint
2.1 概念
- SwiftLintはSwiftの規約を通して、コードをチェックするツールです(コードレビュー)
- 各言語について、違うLintがあります
- デフォルトの rule を使うこともできるし、プロジェクトのルールで、カスタムすることもできます
- Github: https://github.com/realm/SwiftLint
2.2 インストール
インストールの方がたくさんありますが、今回はCocoaPodと使用して説明していきたいと思います。
- podファイルを開く、追加:
pod 'SwiftLint'
インストール します。
- Xcodeにて script を追加し, swiftlintを実行する
- Build Phase > New Run Script Phase
- 以下の script をコピーして, 使います:
"${PODS_ROOT}/SwiftLint/swiftlint"
プロジェクトをビルドすると、 Swiftlintのwarning と errorのお知らせが見えます
2.3 SwiftLintの動作を確認しましょう!
SwiftLintの動作を確認するには以下のようなコードを追加てみます。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// test comment
var namesOfIntegers: [Int: String] = [Int: String]()
return true
}
- 結果
- 空行に2個の警告がある。
Array初期化の仕方が間違える
- 空行に2個の警告がある。
3. SwiftLintとCI 統合します
- SwiftLintをCIと一緒に使える用に(この記事では Travis CI)
- yaml fileを一つ作成 、ルートディレクトリに置く。CIは自動的にスキャンして実行します
- .swiftlint.ymlの後に名前を設定する
- 参照ファイルの内容:
disabled_rules: # rule identifiers to exclude from running
- colon
- comma
- control_statement
opt_in_rules: # some rules are only opt-in
- empty_count
# Find all the available rules by running:
# swiftlint rules
excluded: # paths to ignore during linting. Takes precedence over `included`.
- Carthage
- Pods
- vendor
analyzer_rules: # Rules run by `swiftlint analyze` (experimental)
- explicit_self
# configurable rules can be customized from this configuration file
# binary rules can set their severity level
force_cast: warning # implicitly
force_try:
severity: warning # explicitly
# rules that have both warning and error levels, can set just the warning level
# implicitly
line_length: 110
# they can set both implicitly with an array
type_body_length:
- 300 # warning
- 400 # error
# or they can set both explicitly
file_length:
warning: 500
error: 1200
# naming rules can set warnings/errors for min_length and max_length
# additionally they can set excluded names
type_name:
min_length: 4 # only warning
max_length: # warning and error
warning: 40
error: 50
excluded: iPhone # excluded via string
identifier_name:
min_length: # only min_length
error: 3 # only error
excluded: # excluded via string array
- id
- URL
- GlobalAPIKey
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit, html, emoji, sonarqube, markdown)
- このファイルにあるキーワードとコマンドの意味は難しくないので,自分で調べてくださいね。
- 注意:
- rules 、 custom_rules : デフォルト設定とカスタムの設定。プロジェクトによって、デフォルトのルール と プロジェクトのルールが違うかもしれません。
例えば:
custom_rules:
id_suffix_naming:
name: "Wrong name"
regex: "(ID)"
match_kinds:
- comment
- identifier
message: "Use 'Id' instead 'ID'"
severity: error
uiwebview_disabled:
included: ".*.swift"
name: "UIWebView Usage Disabled"
regex: 'UIWebView'
message: "Do not use UIWebView. Use WKWebView Instead. https://developer.apple.com/reference/uikit/uiwebview"
severity: error
- SwiftLint通した場合は、ビルドに続ける、失敗する場合は 以下のレポートが出ます:
Testing failed:
Identifier Name Violation: Variable name should be between 4 and 40 characters long: 'key' (identifier_name)
Testing cancelled because the build failed.
** TEST FAILED **
ビルドを正しくて実行すると、何にを表示されてないので、次のステップ続きます。
4. GitHubにLinterBotでレポートとコメントする
GitHubにSwiftLint の結果とコメントを投稿するためにLinterBotを使います
4.1 概念
- Linterbot
- Linterbotはボットです。 SwiftLint のoutput を受け取って、GitHubのpull request にコメントしてくれます。
- ボットがコメントを投稿できるために、開発者アカウントのaccess_token が必要です。
- 参照するリンク: https://github.com/guidomb/linterbot
4.2 設定
- GemFileに下記のように追加
gem 'linterbot'
- インストール
gem install linterbot
4.3 ローカルで使用
swiftlint lint --reporter json | linterbot REPOSITORY PULL_REQUEST_NUMBER
4.4 Travis CIで使用
- bash scriptを作成
- scripts フォルダーを作成(ルートディレクトリに) > ファイルを作成 (拡張子がない) 。以下のように編集して:
#!/bin/bash
if [ "$TRAVIS_PULL_REQUEST" != "false" ]
then
./Pods/SwiftLint/swiftlint --reporter json > swiftlint-report.json || false
linterbot $TRAVIS_REPO_SLUG $TRAVIS_PULL_REQUEST < swiftlint-report.json
fi
- こちらのリンクを注意してください./Pods/SwiftLint/swiftlint は pod がswiftlint を置く場所なので、 正しくて指定すると実行できます。 きちんとコピーペーストしない場合は大変時間がかかります。
- linterと言う名前のファイルで保存します
- Permission deniedに関するエラーを避けるために、以下に権限を編集します ( CIで実行するとき)
0.01s$ ./bin/linter
/Users/travis/.travis/functions: line 104: ./bin/linter: Permission denied
The command “./bin/linter” exited with 126.
- アクセス許可を再設定する
chmod +x ./scripts/linter
- .travis.ymlを編集する
- linterbot の設定するコマンドを追加する
before_install:
- bundle install
- gem install linterbot
- bundle exec pod install --repo-update
- linterの実施コマンドを追加します
script:
- ./scripts/linter
- .travis.yml のファイルは下記のようになります。
language: objective-c
osx_image: xcode10.1
cache:
- bundler
- cocoapods
xcode_workspace: TheLastProject.xcworkspace
xcode_scheme: TheLastProject_Development
xcode_destination: platform=iOS Simulator,OS=12.1,name=iPhone X
before_install:
- bundle install
- gem install linterbot
- bundle exec pod install --repo-update
install:
- set -o pipefail
- sudo systemsetup -settimezone Asia/Ho_Chi_Minh
- bundle install --path=vendor/bundle --jobs 4 --retry 3
before_script:
- chmod a+x ./scripts/linter
script:
- ./scripts/linter
4.5 アクセスキー
- post/comment に投稿するために、GitHubの権限が必要です。
- 参照 access_key : https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line
- セキュリティ規約を守る為に、アクセスキーが Travis CIに保存されます。settingにて一つのGITHUB_ACCESS_TOKENを作成する。
- デフォルト設定なら LinterBotが 自動的にGITHUB_ACCESS_TOKENの環境変数を探します。その他の設定をしたい場合は自分でコンフィグレーションを作成する。
- .linterbot.ymlを作成
- 編集
github_access_token: 'YOUR_GITHUB_ACCESS_TOKEN'
linter_report_file: 'PATH/TO/SWIFTLINT/JSON/OUTPUT/FILE'
project_base_path: 'BASE/PROJECT/PATH'
詳細: https://github.com/guidomb/linterbot#configuration-file
5. 結果
コミットして、プルリクエストを送った後にCIが実行されてチェック行われます。pull request に以下の結果になる場合は、passしましたので、おめでとうございます!
- CIを通す
- linterbot を通して、SwiftLintのコメントを表示しま
- エラーがない場合は以上のように表示します。
6. まとめ:
- プロジェクトの conventions を保障する。
- 自動コードレビューでコードレビューの時間を減らす。
- コードレビュー結果をGitHubに自動的にコメントする