一个用于强制执行 Swift 风格和约定的工具,其松散地基于现已存档的 GitHub Swift 风格指南。SwiftLint 强制执行 Swift 社区普遍接受的风格指南规则。这些规则在流行的风格指南(如 Kodeco 的 Swift 风格指南)中有很好的描述。
SwiftLint 接入 Clang 和 SourceKit,以使用源代码文件的 AST 表示形式,从而获得更准确的结果。
本项目遵守 贡献者盟约行为准则。参与本项目,即表示您需要遵守此准则。
要获得 SwiftLint 的高层次概述,我们鼓励您观看 JP Simard 于 2017 年 1 月 9 日录制的演示文稿(提供文字稿)
添加
.package(url: "https://github.com/SimplyDanny/SwiftLintPlugins", from: "<version>")
到您的 Package.swift
文件中,以自动使用最新版本的 SwiftLint,或将依赖项固定到特定版本
.package(url: "https://github.com/SimplyDanny/SwiftLintPlugins", exact: "<version>")
在其中,将 <version>
替换为所需的最低版本或确切版本。
注意
直接从 SwiftLint 仓库使用插件有一些缺点。为了避免这些缺点并减少带来的开销,强烈建议从专门的 SwiftLintPlugins 仓库 使用插件,即使来自 SwiftLint 仓库的插件也完全可用。如果首选来自 SwiftLint 的插件,只需在上面的包声明中使用 URL https://github.com/realm/SwiftLint
。
然而,SwiftLintPlugins 大大简化了插件的采用。它列出了使 SwiftLint 本身提供的插件非常麻烦的一些原因。由于插件代码和发布版本保持同步,因此两者之间的功能没有差异,但使用专门的插件仓库可以为您节省大量时间和麻烦。
本文档假设您依赖 SwiftLintPlugins。
使用以下链接将 SwiftLint 作为 Package Dependency 添加到 Xcode 项目
https://github.com/SimplyDanny/SwiftLintPlugins
brew install swiftlint
将以下内容添加到您的 Podfile
pod 'SwiftLint'
这将在您下次执行 pod install
时在 Pods/
中下载 SwiftLint 二进制文件和依赖项,并允许您在 Script Build Phases 中通过 ${PODS_ROOT}/SwiftLint/swiftlint
调用它。
通过 Cocoapods 安装还可以将 SwiftLint 固定到特定版本,而不是仅仅是最新版本(Homebrew 就是这种情况)。
请注意,这将把 SwiftLint 二进制文件、其依赖项的二进制文件以及 Swift 二进制库分发添加到 Pods/
目录,因此不鼓励将此目录签入到 Git 等 SCM 中。
mint install realm/SwiftLint
将此内容放入您的 MODULE.bazel
bazel_dep(name = "swiftlint", version = "0.52.4", repo_name = "SwiftLint")
或将此内容放入您的 WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "build_bazel_rules_apple",
sha256 = "390841dd5f8a85fc25776684f4793d56e21b098dfd7243cd145b9831e6ef8be6",
url = "https://github.com/bazelbuild/rules_apple/releases/download/2.4.1/rules_apple.2.4.1.tar.gz",
)
load(
"@build_bazel_rules_apple//apple:repositories.bzl",
"apple_rules_dependencies",
)
apple_rules_dependencies()
load(
"@build_bazel_rules_swift//swift:repositories.bzl",
"swift_rules_dependencies",
)
swift_rules_dependencies()
load(
"@build_bazel_rules_swift//swift:extras.bzl",
"swift_rules_extra_dependencies",
)
swift_rules_extra_dependencies()
http_archive(
name = "SwiftLint",
sha256 = "c6ea58b9c72082cdc1ada4a2d48273ecc355896ed72204cedcc586b6ccb8aca6",
url = "https://github.com/realm/SwiftLint/releases/download/0.52.4/bazel.tar.gz",
)
load("@SwiftLint//bazel:repos.bzl", "swiftlint_repos")
swiftlint_repos()
load("@SwiftLint//bazel:deps.bzl", "swiftlint_deps")
swiftlint_deps()
然后,您可以使用以下命令在当前目录中运行 SwiftLint
bazel run -c opt @SwiftLint//:swiftlint
从 最新的 GitHub 版本 下载 SwiftLint.pkg
并运行它。
确保已安装构建工具 Bazel 和最新的 Swift 工具链,并且所有工具在您的 PATH
中都可被发现。
要构建 SwiftLint,请克隆此仓库并运行 make install
。
重要提示
虽然在编译 Swift 源代码文件之前运行 SwiftLint 以在存在 lint 违规时提前退出构建似乎很直观,但重要的是要理解 SwiftLint 旨在分析可编译的有效源代码。非编译代码很容易导致意外和令人困惑的结果,尤其是在使用 --fix
/--autocorrect
命令行参数执行时。
SwiftLint 可以用作 Swift Package 项目 和 Xcode 项目 的构建工具插件。
构建工具插件通过查找包/项目目录中最顶层的配置文件来确定 SwiftLint 的工作目录。如果在其中未找到配置文件,则包/项目目录将用作工作目录。
当插件无法解析 SwiftLint 工作目录时,它会抛出错误。例如,这将在 Xcode 项目中发生,其中目标的 Swift 文件未位于项目目录中。
为了最大限度地提高与插件的兼容性,请避免需要使用 --config
选项的项目结构。
注意
需要通过 Swift Package Manager 安装。
构建工具插件在构建每个目标时运行。当项目有多个目标时,必须将插件单独添加到所需的目标。
为此,请按如下所示将插件添加到要进行 lint 检查的目标:
.target(
...
plugins: [.plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLintPlugins")]
),
注意
需要通过 Swift Package Manager 安装。
命令插件允许从命令行运行 SwiftLint,如下所示:
swift package plugin swiftlint
注意
需要通过 Xcode Package Dependency 安装。
构建工具插件作为每个目标的构建阶段运行。当项目有多个目标时,必须将插件单独添加到所需的目标。
为此,请将 SwiftLintBuildToolPlugin
添加到要进行 lint 检查的目标的 Build Phases
的 Run Build Tool Plug-ins
阶段。
提示
首次使用插件时,请务必在提示时信任并启用它。如果存在宏构建警告,请选择它以信任并启用宏。
对于无人值守的使用(例如在 CI 上),可以使用以下任一方法禁用包插件和宏验证
使用 xcodebuild
选项
-skipPackagePluginValidation
-skipMacroValidation
设置 Xcode 默认值
defaults write com.apple.dt.Xcode IDESkipPackagePluginFingerprintValidatation -bool YES
defaults write com.apple.dt.Xcode IDESkipMacroFingerprintValidation -bool YES
重要提示
无人值守使用选项绕过 Xcode 的验证对话框,并隐式信任所有插件和宏,这具有安全隐患。
构建工具插件不直接支持 SwiftLint 配置文件位于包/项目目录之外的项目结构。这是因为无法将参数传递给构建工具插件(例如,传递配置文件路径)。
如果您的项目结构无法直接使用构建工具插件,请考虑以下选项之一
parent_config: path/to/.swiftlint.yml
。注意
根据使用的安装方法,Run Script Build Phase 中的 shell 命令语法可能有所不同,或者可能需要额外的配置。有关更多信息,请参阅安装说明。
如果构建工具插件不适用于您的项目设置,或者当需要额外的自定义设置时,可以将 SwiftLint 添加为 Run Script Build Phase。当项目设置依赖于 --config
SwiftLint 选项时;或者将所有目标一起 lint 检查在单个 swiftlint
调用中时,这非常有用。文件包含和排除可以在 .swiftlint.yml
配置中配置。
为此,请在主要应用程序目标的 Build Phases
的 Run Script
阶段(在 Compile Sources
阶段之后)添加自定义脚本。使用以下脚本实现
if command -v swiftlint >/dev/null 2>&1
then
swiftlint
else
echo "warning: `swiftlint` command not found - See https://github.com/realm/SwiftLint#installation for installation instructions."
fi
如果您在 Swift 包中使用 SwiftLintPlugin,您可以按以下方式引用 swiftlint
可执行文件
SWIFT_PACKAGE_DIR="${BUILD_DIR%Build/*}SourcePackages/artifacts"
SWIFTLINT_CMD=$(ls "$SWIFT_PACKAGE_DIR"/swiftlintplugins/SwiftLintBinary/SwiftLintBinary.artifactbundle/swiftlint-*-macos/bin/swiftlint | head -n 1)
if test -f "$SWIFTLINT_CMD" 2>&1
then
"$SWIFTLINT_CMD"
else
echo "warning: `swiftlint` command not found - See https://github.com/realm/SwiftLint#installation for installation instructions."
fi
注意
SWIFTLINT_CMD
路径使用默认的 Xcode 配置,并在 Xcode 15/16 上进行了测试。如果使用其他配置(例如,自定义 Swift 包路径),请相应地调整值。
提示
取消选中“Based on dependency analysis
”以在所有增量构建上运行 swiftlint
,从而抑制未指定的输出警告。
Xcode 15 做出了一项重大更改,将 ENABLE_USER_SCRIPT_SANDBOXING
构建设置的默认值从 NO
设置为 YES
。因此,SwiftLint 遇到与缺少文件权限相关的错误,这通常表现为 error: Sandbox: swiftlint(19427) deny(1) file-read-data.
要解决此问题,必须手动将 ENABLE_USER_SCRIPT_SANDBOXING
设置为 NO
,用于配置 SwiftLint 的特定目标。
如果您通过 Homebrew 在 Apple Silicon 上安装了 SwiftLint,您可能会遇到此警告
warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint
这是因为 Apple Silicon 上的 Homebrew 默认将二进制文件安装到 /opt/homebrew/bin
文件夹中。要指示 Xcode 在哪里找到 SwiftLint,您可以将 /opt/homebrew/bin
添加到构建阶段的 PATH
环境变量中
if [[ "$(uname -m)" == arm64 ]]
then
export PATH="/opt/homebrew/bin:$PATH"
fi
if command -v swiftlint >/dev/null 2>&1
then
swiftlint
else
echo "warning: `swiftlint` command not found - See https://github.com/realm/SwiftLint#installation for installation instructions."
fi
或者您可以在 /usr/local/bin
中创建一个指向实际二进制文件的符号链接
ln -s /opt/homebrew/bin/swiftlint /usr/local/bin/swiftlint
如果您也希望修复违规,您的脚本可以运行 swiftlint --fix && swiftlint
而不是仅运行 swiftlint
。这将意味着所有可纠正的违规都将被修复,同时确保警告会在您的项目中显示剩余的违规。
如果您通过 CocoaPods 安装了 SwiftLint,则脚本应如下所示
"${PODS_ROOT}/SwiftLint/swiftlint"
要将 SwiftLint 与 Visual Studio Code 集成,请从 marketplace 安装 vscode-swiftlint
扩展。
您可以使用官方的 swiftlint
fastlane action 来运行 SwiftLint 作为 fastlane 流程的一部分。
swiftlint(
mode: :lint, # SwiftLint mode: :lint (default) or :autocorrect
executable: "Pods/SwiftLint/swiftlint", # The SwiftLint binary path (optional). Important if you've installed it via CocoaPods
path: "/path/to/lint", # Specify path to lint (optional)
output_file: "swiftlint.result.json", # The path of the output file (optional)
reporter: "json", # The custom reporter to use (optional)
config_file: ".swiftlint-ci.yml", # The path of the configuration file (optional)
files: [ # List of files to process (optional)
"AppDelegate.swift",
"path/to/project/Model.swift"
],
ignore_exit_status: true, # Allow fastlane to continue even if SwiftLint returns a non-zero exit status (Default: false)
quiet: true, # Don't print status logs like 'Linting ' & 'Done linting' (Default: false)
strict: true # Fail on warnings? (Default: false)
)
SwiftLint 也可用作使用 Ubuntu
的 Docker 镜像。因此,第一次您只需要使用以下命令拉取 docker 镜像
docker pull ghcr.io/realm/swiftlint:latest
然后,在接下来的时间里,您只需在 docker 中运行 swiftlint
,如下所示
docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:latest
这将在您当前所在的文件夹 (pwd
) 中执行 swiftlint
,并显示类似如下的输出
$ docker run -it -v `pwd`:`pwd` -w `pwd` ghcr.io/realm/swiftlint:latest
Linting Swift files in current working directory
Linting 'RuleDocumentation.swift' (1/490)
...
Linting 'YamlSwiftLintTests.swift' (490/490)
Done linting! Found 0 violations, 0 serious in 490 files.
您可以在此处找到有关 Docker 镜像 用法的更多文档。
$ swiftlint help
OVERVIEW: A tool to enforce Swift style and conventions.
USAGE: swiftlint <subcommand>
OPTIONS:
--version Show the version.
-h, --help Show help information.
SUBCOMMANDS:
analyze Run analysis rules
docs Open SwiftLint documentation website in the default web browser
generate-docs Generates markdown documentation for selected group of rules
lint (default) Print lint warnings and errors
baseline Operations on existing baselines
reporters Display the list of reporters and their identifiers
rules Display the list of rules and their identifiers
version Display the current version of SwiftLint
See 'swiftlint help <subcommand>' for detailed help.
在包含要 lint 检查的 Swift 文件的目录中运行 swiftlint
。目录将被递归搜索。
要在使用 lint
或 analyze
时指定文件列表(例如 Xcode 指定的已修改文件列表,由 ExtraBuildPhase
Xcode 插件指定,或基于 git ls-files -m
的工作树中的已修改文件),您可以通过传递选项 --use-script-input-files
并设置以下实例变量来完成此操作:SCRIPT_INPUT_FILE_COUNT
和 SCRIPT_INPUT_FILE_0
、SCRIPT_INPUT_FILE_1
、...、SCRIPT_INPUT_FILE_{SCRIPT_INPUT_FILE_COUNT - 1}
。 类似地,可以通过传递选项 --use-script-input-file-lists
并设置以下实例变量,从文件列表中读取文件:SCRIPT_INPUT_FILE_LIST_COUNT
和 SCRIPT_INPUT_FILE_LIST_0
、SCRIPT_INPUT_FILE_LIST_1
、...、SCRIPT_INPUT_FILE_LIST_{SCRIPT_INPUT_FILE_LIST_COUNT - 1}
。
这些是为 自定义 Xcode 脚本阶段 的输入文件设置的相同环境变量。
SwiftLint 接入 SourceKit,因此即使 Swift 不断发展,它也能继续工作!
这也使 SwiftLint 保持精简,因为它不需要附带完整的 Swift 编译器,它只是与您机器上已安装的官方编译器进行通信。
您应该始终使用与编译代码相同的工具链运行 SwiftLint。
如果您安装了多个工具链或 Xcode,您可能需要覆盖 SwiftLint 的默认 Swift 工具链。
以下是 SwiftLint 确定要使用的 Swift 工具链的顺序
$XCODE_DEFAULT_TOOLCHAIN_OVERRIDE
$TOOLCHAIN_DIR
或 $TOOLCHAINS
xcrun -find swift
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
~/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
~/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
sourcekitd.framework
预计在上面路径中传递的值的 usr/lib/
子目录中找到。
您还可以将 TOOLCHAINS
环境变量设置为标识 Swift 工具链版本的反向 DNS 表示法
TOOLCHAINS=com.apple.dt.toolchain.Swift_2_3 swiftlint --fix
在 Linux 上,SourceKit 预计位于 /usr/lib/libsourcekitdInProc.so
中,或由 LINUX_SOURCEKIT_LIB_PATH
环境变量指定。
SwiftLint 可以作为 pre-commit hook 运行。安装 安装 后,将此添加到存储库根目录中的 .pre-commit-config.yaml
中
repos:
- repo: https://github.com/realm/SwiftLint
rev: 0.57.1
hooks:
- id: swiftlint
调整 rev
为您选择的 SwiftLint 版本。 pre-commit autoupdate
可用于更新到当前版本。
可以使用 entry
配置 SwiftLint 以应用修复并因错误而失败
- repo: https://github.com/realm/SwiftLint
rev: 0.57.1
hooks:
- id: swiftlint
entry: swiftlint --fix --strict
SwiftLint 中包含 200 多个规则,Swift 社区(就是你!)不断贡献更多规则。Pull requests 受到鼓励。
您可以在 此处 找到更新的规则列表以及有关它们的更多信息。
您还可以查看 Source/SwiftLintBuiltInRules/Rules 目录以查看它们的实现。
opt_in_rules
默认禁用(即,您必须在配置文件中显式启用它们)。
关于何时将规则标记为选择加入的指南
empty_count
)force_unwrapping
)可以使用源代码文件中的注释禁用规则,格式如下
// swiftlint:disable <rule1> [<rule2> <rule3>...]
规则将被禁用,直到文件末尾或直到 linter 看到匹配的启用注释
// swiftlint:enable <rule1> [<rule2> <rule3>...]
例如
// swiftlint:disable colon
let noWarning :String = "" // No warning about colons immediately after variable names!
// swiftlint:enable colon
let hasWarning :String = "" // Warning generated about colons immediately after variable names
包含 all
关键字将禁用所有规则,直到 linter 看到匹配的启用注释
// swiftlint:disable all
// swiftlint:enable all
例如
// swiftlint:disable all
let noWarning :String = "" // No warning about colons immediately after variable names!
let i = "" // Also no warning about short identifier names
// swiftlint:enable all
let hasWarning :String = "" // Warning generated about colons immediately after variable names
let y = "" // Warning generated about short identifier names
也可以通过附加 :previous
、:this
或 :next
来修改 disable
或 enable
命令,以便仅将命令应用于上一行、当前行或下一行。
例如
// swiftlint:disable:next force_cast
let noWarning = NSNumber() as! Int
let hasWarning = NSNumber() as! Int
let noWarning2 = NSNumber() as! Int // swiftlint:disable:this force_cast
let noWarning3 = NSNumber() as! Int
// swiftlint:disable:previous force_cast
运行 swiftlint rules
以打印所有可用规则及其标识符的列表。
通过从您将运行 SwiftLint 的目录中添加 .swiftlint.yml
文件来配置 SwiftLint。可以配置以下参数
规则包含
disabled_rules
:禁用默认启用集中的规则。opt_in_rules
:启用不属于默认集的规则。特殊的 all
标识符将启用所有选择加入的 linter 规则,但 disabled_rules
中列出的规则除外。only_rules
:仅启用此列表中指定的规则。不能与 disabled_rules
或 opt_in_rules
一起指定。analyzer_rules
:这是一个完全独立的规则列表,仅由 analyze
命令运行。所有 analyzer 规则都是选择加入的,因此这是唯一可配置的规则列表,没有 disabled_rules
和 only_rules
的等效项。特殊的 all
标识符也可以在此处使用,以启用所有 analyzer 规则,但 disabled_rules
中列出的规则除外。# By default, SwiftLint uses a set of sensible default rules you can adjust:
disabled_rules: # rule identifiers turned on by default to exclude from running
- colon
- comma
- control_statement
opt_in_rules: # some rules are turned off by default, so you need to opt-in
- empty_count # find all the available rules by running: `swiftlint rules`
# Alternatively, specify all rules explicitly by uncommenting this option:
# only_rules: # delete `disabled_rules` & `opt_in_rules` if using this
# - empty_parameters
# - vertical_whitespace
analyzer_rules: # rules run by `swiftlint analyze`
- explicit_self
# Case-sensitive paths to include during linting. Directory paths supplied on the
# command line will be ignored.
included:
- Sources
excluded: # case-sensitive paths to ignore during linting. Takes precedence over `included`
- Carthage
- Pods
- Sources/ExcludedFolder
- Sources/ExcludedFile.swift
- Sources/*/ExcludedFile.swift # exclude files with a wildcard
# If true, SwiftLint will not fail if no lintable files are found.
allow_zero_lintable_files: false
# If true, SwiftLint will treat all warnings as errors.
strict: false
# If true, SwiftLint will treat all errors as warnings.
lenient: false
# The path to a baseline file, which will be used to filter out detected violations.
baseline: Baseline.json
# The path to save detected violations to as a new baseline.
write_baseline: Baseline.json
# If true, SwiftLint will check for updates after linting or analyzing.
check_for_updates: true
# 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
allowed_symbols: ["_"] # these are allowed in type names
identifier_name:
min_length: # only min_length
error: 4 # only error
excluded: # excluded via string array
- id
- URL
- GlobalAPIKey
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging, summary)
您还可以在配置文件中使用环境变量,方法是在字符串中使用 ${SOME_VARIABLE}
。
除了主要的 SwiftLint 项目附带的规则之外,SwiftLint 还可以运行两种类型的自定义规则,您可以在自己的项目中定义这些规则
这些规则的编写方式与 SwiftLint 附带的基于 Swift 的规则相同,因此它们速度快、准确、可以利用 SwiftSyntax、可以进行单元测试等等。
使用这些规则需要使用 Bazel 构建 SwiftLint,如 此视频 或其在 github.com/jpsim/swiftlint-bazel-example 中的关联代码中所述。
您可以使用以下语法在配置文件中定义自定义的基于正则表达式的规则
custom_rules:
pirates_beat_ninjas: # rule identifier
included:
- ".*\\.swift" # regex that defines paths to include during linting. optional.
excluded:
- ".*Test\\.swift" # regex that defines paths to exclude during linting. optional
name: "Pirates Beat Ninjas" # rule name. optional.
regex: "([nN]inja)" # matching pattern
capture_group: 0 # number of regex capture group to highlight the rule violation at. optional.
match_kinds: # SyntaxKinds to match. optional.
- comment
- identifier
message: "Pirates are better than ninjas." # violation message. optional.
severity: error # violation severity. optional.
no_hiding_in_strings:
regex: "([nN]inja)"
match_kinds: string
这是输出的样子
重要的是要注意,正则表达式模式与启用的标志 s
和 m
一起使用,即 .
匹配换行符,而 ^
/$
分别匹配行的开头和结尾。 例如,如果您不希望 .
匹配换行符,则可以在正则表达式前面加上 (?-s)
。
您可以通过提供一个或多个 match_kinds
来过滤匹配项,这将拒绝包含此列表中不存在的语法种类的匹配项。 以下是所有可能的语法种类
argument
attribute.builtin
attribute.id
buildconfig.id
buildconfig.keyword
comment
comment.mark
comment.url
doccomment
doccomment.field
identifier
keyword
number
objectliteral
parameter
placeholder
string
string_interpolation_anchor
typeidentifier
可以使用 SourceKitten 提取 Swift 代码片段中使用的所有语法种类。例如,sourcekitten syntax --text "struct S {}"
交付
source.lang.swift.syntaxtype.keyword
用于 struct
关键字,以及source.lang.swift.syntaxtype.identifier
用于其名称 S
它们与上面列表中的 keyword
和 identifier
匹配。
如果在 only_rules
中结合使用自定义规则,则必须在 only_rules
列表中包含文字字符串 custom_rules
only_rules:
- custom_rules
custom_rules:
no_hiding_in_strings:
regex: "([nN]inja)"
match_kinds: string
与 Swift 自定义规则不同,您可以使用官方 SwiftLint 构建版本(例如来自 Homebrew)来运行 regex 自定义规则。
SwiftLint 可以自动更正某些违规。磁盘上的文件将被更正后的版本覆盖。
请务必在运行 swiftlint --fix
之前备份这些文件,否则可能会丢失重要数据。
在更正时禁用标准 lint 检查,因为在应用更正时修改文件后,违规(或其偏移量)很可能不正确。
swiftlint analyze
命令可以使用完整的类型检查 AST 来 lint 检查 Swift 文件。包含干净的 swiftc
构建命令调用的编译器日志路径(增量构建将失败)必须通过 --compiler-log-path
标志传递给 analyze
。 例如 --compiler-log-path /path/to/xcodebuild.log
这可以通过以下方式获得
xcodebuild -workspace {WORKSPACE}.xcworkspace -scheme {SCHEME} > xcodebuild.log
swiftlint analyze --compiler-log-path xcodebuild.log
Analyzer 规则往往比 lint 规则慢得多。
SwiftLint 提供了多种包含多个配置文件的方法。多个配置文件合并为一个单一配置,然后像应用单个配置文件一样应用。
在很多用例中,使用多个配置文件可能很有用
例如,可以使用团队范围共享的 SwiftLint 配置,同时允许每个项目通过子配置文件进行覆盖。
团队范围配置
disabled_rules:
- force_cast
项目特定配置
opt_in_rules:
- force_cast
您可以在配置文件中指定 child_config
和/或 parent_config
引用。这些引用应该是相对于它们所在的配置文件的文件夹的本地路径。即使没有循环且没有歧义,这也适用于递归。
子配置被视为细化,因此具有更高的优先级,而父配置在发生冲突时被视为优先级较低的基础。
这是一个示例,假设您具有以下文件结构
ProjectRoot
|_ .swiftlint.yml
|_ .swiftlint_refinement.yml
|_ Base
|_ .swiftlint_base.yml
要同时包含细化文件和基础文件,您的 .swiftlint.yml
应如下所示
child_config: .swiftlint_refinement.yml
parent_config: Base/.swiftlint_base.yml
当合并父配置和子配置时,会仔细处理 included
和 excluded
配置,以考虑包含配置文件的目录位置的差异。
正如您可以提供本地 child_config
/parent_config
引用一样,您可以放置指向配置文件的 URL 而不是引用本地路径。为了让 SwiftLint 检测到这些远程引用,它们必须以 http://
或 https://
开头。
引用的远程配置文件甚至可以递归引用其他远程配置文件,但不允许包含本地引用。
使用远程引用,您的 .swiftlint.yml
可能如下所示
parent_config: https://myteamserver.com/our-base-swiftlint-config.yml
每次运行 SwiftLint 并且有 Internet 连接时,SwiftLint 都会尝试获取每个引用的远程配置的新版本。如果此请求超时,则使用缓存的版本(如果可用)。如果没有可用的缓存版本,SwiftLint 将失败 – 但不用担心,一旦 SwiftLint 至少成功运行一次,就应该有一个缓存版本。
如果需要,可以使用 remote_timeout
/remote_timeout_if_cached
说明符通过配置文件手动指定远程配置获取的超时时间。这些值默认为 2 秒或 1 秒。
当通过命令行运行 SwiftLint 时,您不仅可以提供一个配置文件,还可以传递一个层次结构,其中第一个配置被视为父配置,而最后一个配置被视为最高优先级的子配置。
一个简单的示例,仅包含两个配置文件,如下所示
swiftlint --config .swiftlint.yml --config .swiftlint_child.yml
除了主配置(根文件夹中的 .swiftlint.yml
文件)之外,您还可以将其他名为 .swiftlint.yml
的配置文件放入目录结构中,然后将其合并为子配置,但仅对与配置位于同一目录中或在更深目录中且没有其他配置文件的文件有效。换句话说:嵌套配置不以递归方式工作 – 每个文件最多可以应用一个嵌套配置,此外还可以应用主配置。
只有在 .swiftlint.yml
文件尚未用于构建主配置的情况下(例如,通过引用 child_config: Folder/.swiftlint.yml
),才将其视为嵌套配置。此外,嵌套配置的 parent_config
/child_config
规范将被忽略,因为这没有意义。
如果通过 --config
参数显式指定了一个(或多个)SwiftLint 文件,则该配置将被视为覆盖,无论目录中的其他位置是否存在其他 .swiftlint.yml
文件。因此,如果您想使用嵌套配置,则不能使用 --config
参数。
SwiftLint 完全由志愿者维护,他们在业余时间为它的成功做出贡献。因此,SwiftLint 在任何方面都不是商业产品。
请善待将 SwiftLint 作为爱好维护的人们,并接受他们的时间有限。通过为项目做出贡献、报告问题和帮助社区中的其他人来支持他们。
特别感谢 MacStadium 提供物理 Mac mini 机器来运行我们的性能测试。
我们还要感谢 Realm(现在的 MongoDB)对项目的初始贡献和建立。