Server-Side Swift Vaporでrealm/SwiftLintを導入する
Last Updated on 2024年5月19日 by lemonade
概要
今までapple/swift-formatを使用してformatterだけ入れていたのですが、強いLinterも最近欲しくなってきたので探したところ、realm/SwiftLintが良さそうとなりました。
この記事では、realm/SwiftLintをSwift Package Managerのプロジェクトでのインストール方法を紹介します。
手順
SPMのdependenciesにSwiftLintを入れる
// swift-tools-version:5.10
import PackageDescription
let package = Package(
name: "event-sourcing-api-design",
platforms: [
.macOS(.v13)
],
dependencies: [
// 💧 A server-side Swift web framework.
.package(url: "https://github.com/vapor/vapor.git", from: "4.99.3"),
// 🗄 An ORM for SQL and NoSQL databases.
.package(url: "https://github.com/vapor/fluent.git", from: "4.9.0"),
// 🐘 Fluent driver for Postgres.
.package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.8.0"),
// 🔵 Non-blocking, event-driven networking for Swift. Used for custom executors
.package(url: "https://github.com/apple/swift-nio.git", from: "2.65.0"),
// 追加
.package(url: "https://github.com/realm/SwiftLint.git", from: "0.55.1"),
],
targets: [
...
]
)
var swiftSettings: [SwiftSetting] { [
.enableUpcomingFeature("DisableOutwardActorInference"),
.enableExperimentalFeature("StrictConcurrency"),
] }
各targetのpluginsに設定する
// swift-tools-version:5.10
import PackageDescription
let package = Package(
name: "event-sourcing-api-design",
platforms: [...],
dependencies: [...],
targets: [
.executableTarget(
name: "App",
dependencies: [
.product(name: "Fluent", package: "fluent"),
.product(name: "FluentPostgresDriver", package: "fluent-postgres-driver"),
.product(name: "Vapor", package: "vapor"),
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "NIOPosix", package: "swift-nio"),
],
swiftSettings: swiftSettings,
plugins: [.plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLint")] // 追加
),
.testTarget(
name: "AppTests",
dependencies: [
.target(name: "App"),
.product(name: "XCTVapor", package: "vapor"),
],
swiftSettings: swiftSettings,
plugins: [.plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLint")] // 追加
)
]
)
var swiftSettings: [SwiftSetting] { [
.enableUpcomingFeature("DisableOutwardActorInference"),
.enableExperimentalFeature("StrictConcurrency"),
] }
.swiftlint.ymlを追加する
今回はとりあえずデフォルトでオフになっているルールだけ一つ一つ確認して取捨選択してみました。これを.swiftlint.yml
というファイル名でプロジェクトルートに追加します。
opt_in_rules:
- anyobject_protocol
- array_init
- closure_spacing
- collection_alignment
- comma_inheritance
- contains_over_filter_count
- contains_over_filter_is_empty
- contains_over_first_not_nil
- contains_over_range_nil_comparison
- direct_return
- discouraged_assert
- discouraged_optional_boolean
- discouraged_optional_collection
- empty_collection_literal
- empty_count
- empty_string
- enum_case_associated_values_count
- expiring_todo
- explicit_init
- extension_access_modifier
- fallthrough
- fatal_error_message
- file_name_no_space
- first_where
- flatmap_over_map_reduce
- joined_default_parameter
- last_where
- multiline_arguments
- multiline_arguments_brackets
- period_spacing
- prefer_self_in_static_references
- prefer_self_type_over_type_of_self
- redundant_nil_coalescing
- redundant_self_in_closure
- redundant_type_annotation
- return_value_from_void_function
- sorted_imports
- static_operator
- toggle_bool
- unneeded_parentheses_in_closure_argument
- vertical_parameter_alignment_on_call
analyzer_rules:
- unused_declaration
- capture_variable
- unused_import
included:
- Sources
strict: true
line_length: 120
reporter: "xcode"
Xcodeで開いて実行する
この状態でXcodeで開いて実行するとLinterが実行され、Xcode上にエラーが表示されます。
SwiftLint Analyzeを使用する
unused_import
やunused_declaration
を検知するには実行だけでなくCLI上でanalyzeを行う必要があります。
Homebrewでswiftlintをインストールする
SwiftLintのCLIをHomebrewでインストールします。
brew install swiftlint
analyze用のMakefileを作成する
以下のMakefileをプロジェクトルートディレクトリに配置してください 。
.PHONE: analyze
analyze:
rm -rf ./DerivedData
xcodebuild -workspace ./.swiftpm/xcode/package.xcworkspace -derivedDataPath ./DerivedData -scheme swift-testing-example -destination "platform=macOS,arch=arm64" > xcodebuild.log
swiftlint analyze --compiler-log-path xcodebuild.log
rm -f xcodebuild.log
.PHONE: fix
fix:
swiftlint lint --fix --format
Xcodeでプロジェクトを1度開くと./.swiftpm/Xcode/package.xcworkspace
が生成されます。<scheme名>
を実行するスキーム名に変更してください。
DerivedDataを消してい流のは解析にはbuild時のログファイルを用いるのですがインクリメンタルビルドのログでは解析が行えないため、DerivedDataを消してからbuildする必要があるからです。
make analyze
で実行してください。
最後に
Discordのswift-developers-japan
のbeginner-help
チャンネルで私の質問に回答いただいたshimastripe
さんのおかげで解析をすることができました。日曜日にわざわざ丁寧にご回答いただきありがとうございました。