PayPal Build Codecov Swift 5.3 License Mastodon

目录

这是什么?

SwiftFormat 是一个代码库和命令行工具,用于在 macOS、Linux 或 Windows 上重新格式化 Swift 代码。

SwiftFormat 超出了您对代码格式化工具的预期。除了调整空格之外,它还可以插入或删除隐式 self,删除冗余括号,并纠正许多与标准 Swift 习惯用法的偏差。

为什么要这样做?

许多程序员都有自己喜欢的代码格式化风格,而另一些人似乎完全看不到项目现有的格式化约定(让他们的同事恼火)。

在项目协作中,达成一致的编码风格可能会有所帮助,但手动执行它既乏味又容易出错,而且如果某些参与者比其他人更认真对待它,可能会导致争论。

拥有一个自动执行通用风格的工具可以消除这些问题,并让您专注于代码的行为,而不是它的呈现方式。

如何安装它?

这取决于 - 您可以通过多种方式使用 SwiftFormat

  1. 作为手动运行的命令行工具,或作为其他工具链的一部分
  2. 作为源代码编辑器扩展,您可以通过 Xcode 中“编辑器 > SwiftFormat”菜单调用它
  3. 作为 Xcode 项目中的构建阶段,以便在每次按 Cmd-R 或 Cmd-B 时运行,或者
  4. 作为 Git pre-commit 钩子,以便在您检入之前对您已更改的任何文件运行它

命令行工具

注意: 如果您使用以下任何方法在 macOS 10.14.3 或更早版本上安装 SwiftFormat,并且在启动时遇到崩溃,您可能需要安装 Swift 5 命令行工具运行时支持。 有关详细信息,请参见已知问题

安装

您可以使用 Homebrew 在 macOS 或 Linux 上安装 swiftformat 命令行工具。 假设您已经安装了 Homebrew,只需输入

$ brew install swiftformat

安装后更新到最新版本

$ brew upgrade swiftformat

或者,您可以使用 Mint 在 macOS 或 Linux 上安装该工具,如下所示

$ mint install nicklockwood/SwiftFormat

或者,如果您愿意,您可以手动检出并在 macOS、Linux 或 Windows 上构建 SwiftFormat,如下所示

$ git clone https://github.com/nicklockwood/SwiftFormat
$ cd SwiftFormat
$ swift build -c release

如果您要将 SwiftFormat 安装到您的项目目录中,您可以使用 macOS 上的 CocoaPods 自动安装 swiftformat 二进制文件以及您的其他 pods - 有关详细信息,请参阅下面的 Xcode 构建阶段说明。

另一种选择是在您的 Package.swift 中包含二进制 artifactbundle

.binaryTarget(
    name: "swiftformat",
    url: "https://github.com/nicklockwood/SwiftFormat/releases/download/0.55.0/swiftformat-macos.artifactbundle.zip",
    checksum: "CHECKSUM"
),

如果您不想使用包管理器,您可以手动构建命令行应用程序

  1. 打开 SwiftFormat.xcodeproj 并构建 SwiftFormat (Application) 方案。

  2. swiftformat 二进制文件拖到 /usr/local/bin/ 中(这是一个隐藏文件夹,但您可以使用 Finder 的 前往 > 前往文件夹... 菜单打开它)。

  3. 在您喜欢的文本编辑器中打开 ~/.bash_profile(这是一个隐藏文件,但您可以在终端中输入 open ~/.bash_profile 来打开它)。

  4. 将以下行添加到文件中:alias swiftformat="/usr/local/bin/swiftformat --indent 4" (您可以省略 --indent 4,或将其替换为其他内容。运行 swiftformat --help 以查看可用选项)。

  5. 保存 .bash_profile 文件并运行命令 source ~/.bash_profile 以使更改生效。

用法

如果您按照上面的安装说明操作,现在只需输入

$ swiftformat .

(命令后跟一个空格和一个句点) 在终端中格式化当前目录中的任何 Swift 文件。 您可以输入要格式化的文件或目录的绝对或相对路径来代替 .

警告: swiftformat . 将覆盖它在当前目录及其任何子文件夹中找到的任何 Swift 文件。 如果您在您的主目录中运行它,它可能会重新格式化您硬盘驱动器上的每个 Swift 文件。

为了安全地使用它,请执行以下操作

  1. 选择要应用更改的文件或目录。

  2. 确保您已将所有更改安全地提交到 git 中的代码(或您使用的任何源代码控制系统)。

  3. (可选) 在终端中,输入 swiftformat --inferoptions "/path/to/your/code/"。 这将建议一组与您现有项目风格相匹配的格式化选项(但您可以随意忽略这些选项并使用默认设置,或者如果您愿意,可以使用您自己的设置)。

    该路径可以指向单个 Swift 文件或文件目录。 它可以是绝对的,也可以是相对于当前目录的。 路径周围的 "" 引号是可选的,但如果路径包含空格,则您需要使用引号,或者使用 \ 转义每个空格。 您可以包含多个用空格分隔的路径。

  4. 在终端中,输入 swiftformat "/path/to/your/code/"。 与上面关于路径的规则相同,并且允许使用多个空格分隔的路径。

    如果您使用 --inferoptions 在步骤 3 中生成了一组建议的选项,您应该将它们复制并粘贴到命令中,无论是在源文件的路径之前还是之后。

    如果您创建了配置文件,您可以使用 --config "/path/to/your/config-file/" 指定其路径。 或者,如果您将该文件命名为 .swiftformat 并将其放置在您正在格式化的项目内,它将被自动拾取。

  5. 按 Enter 开始格式化。 格式化完成后,使用您的源代码控制系统来检查更改,并验证是否没有引入不需要的更改。 如果有,请恢复更改,调整选项并重试。

  6. (可选) 提交更改。

遵循这些说明应该确保您避免灾难性数据丢失,但在它擦除您的硬盘驱动器的不太可能的情况下,请注意,我不承担任何责任

使用标准输入/输出

如果您愿意,您可以使用 unix 管道将 SwiftFormat 作为命令链的一部分包含在内。 例如,这是格式化文件的另一种方法

$ cat /path/to/file.swift | swiftformat --output /path/to/file.swift

省略 --output /path/to/file.swift 会将格式化的文件打印到标准输出 (stdout)。 您也可以显式传递“stdout”作为输出路径

$ cat /path/to/file.swift | swiftformat --output stdout

或者您可以使用 > 指定输出路径,如下所示

$ cat /path/to/file.swift | swiftformat > /path/to/file.swift

如果您不提供输入文件,SwiftFormat 将自动从标准输入 (stdin) 获取其输入,但如果未立即收到输入,则会超时并显示帮助屏幕。 为了使其明确,请传递“stdin”作为输入路径

$ cat /path/to/file.swift | swiftformat stdin

使用 stdin 时,SwiftFormat 无权访问输入的文件路径,因此依赖于文件位置的功能(例如将创建日期插入到标头注释中,或检测文件路径中的 .swiftformat 配置文件)将不起作用。 要解决此问题,您可以使用 --stdinpath 参数提供文件路径

$ cat /path/to/file.swift | swiftformat stdin --stdinpath /path/to/file.swift

Xcode 源代码编辑器扩展

安装

与命令行工具一样,您可以通过 Homebrew 安装 SwiftFormat for Xcode 扩展应用程序。 假设您已经安装了 Homebrew,请输入

$ brew install --cask swiftformat-for-xcode

这将在您的“应用程序”文件夹中安装 SwiftFormat for Xcode。 双击该应用程序以启动它,然后按照屏幕上的说明进行操作。

注意: 该应用程序应该已正确签名,但是如果您在尝试打开它时收到 Gatekeeper 警告,您可以通过右键单击(或按住 Control 键单击)该应用程序并选择 打开 来绕过此警告。

要更新到安装后的最新版本,请使用

$ brew upgrade --cask swiftformat-for-xcode

或者,如果您不想使用 Homebrew,您可以在 GitHub 版本页面上找到最新版本的 SwiftFormat for Xcode 应用程序。 下载并解压缩 zip 存档,然后将 SwiftFormat for Xcode.app 拖到您的 应用程序 文件夹中。

用法

启动应用程序并重新启动 Xcode 后,您将在 Xcode 的“编辑器”菜单下找到“SwiftFormat”选项。 如果 SwiftFormat 菜单没有出现,此线程 可能会有所帮助。

您可以使用 SwiftFormat for Xcode 主机应用程序配置格式化规则选项。 目前没有按项目覆盖这些规则的方法,但是,您可以使用“文件”菜单导入和导出不同的配置。 每次切换项目时,您都需要再次执行此操作。

配置文件的格式在下面的配置部分中进行了描述。

注意: SwiftFormat for Xcode 无法自动检测对导入的配置文件的更改。 如果您更新了项目的 .swiftformat 文件,您需要手动将该文件重新导入到 SwiftFormat for Xcode,以便 Xcode 源代码编辑器扩展使用新的配置。

Xcode 构建阶段

注意: 添加此脚本会覆盖您正在处理的源文件,这会产生清除撤消历史记录的恼人副作用。 您可能希望将脚本添加到您的测试目标,而不是您的主要目标,以便仅在您运行单元测试时才调用该脚本,而不是每次构建应用程序时都调用。

或者,您可能希望在正常构建中将 SwiftFormat 以lint模式运行,然后手动运行格式化过程,或将其作为不那么频繁的构建目标(例如测试)的一部分运行。

使用 Swift Package Manager

要将 SwiftFormat 设置为 Xcode 构建阶段,请执行以下操作

1) 创建一个 BuildTools 文件夹和 Package.swift

  1. 在与您的 xcodeproj 文件相同的文件夹中创建一个名为 BuildTools 的文件夹
  2. 在此文件夹中,创建一个名为 Package.swift 的文件,其内容如下
// swift-tools-version:5.1
import PackageDescription

let package = Package(
    name: "BuildTools",
    platforms: [.macOS(.v10_11)],
    dependencies: [
        .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.55.0"),
    ],
    targets: [.target(name: "BuildTools", path: "")]
)
  1. 如果您运行的是 Xcode 11.4 或更高版本,请在 BuildTools 文件夹中创建一个名为 Empty.swift 的文件,其中没有任何内容。 这是为了满足 Swift Package Manager 中的一项更改。

2) 将构建阶段添加到您的应用程序目标

  1. 在文件列表中单击您的项目,在 TARGETS 下选择您的目标,单击 Build Phases 选项卡

  2. 通过单击左上角的小加号图标来添加一个新的 New Run Script Phase

  3. 取消选中 Based on dependency analysis 复选框

  4. 将新的 Run Script 阶段拖动到 Compile Sources 阶段之上,展开它并粘贴以下脚本

    cd BuildTools
    SDKROOT=(xcrun --sdk macosx --show-sdk-path)
    #swift package update #Uncomment this line temporarily to update the version used to the latest matching your BuildTools/Package.swift file
    swift run -c release swiftformat "$SRCROOT"

如果需要更复杂的脚本并且 cd BuildTools 中断了,您也可以使用 swift run -c release --package-path BuildTools swiftformat "$SRCROOT"

注意: 您可能希望将 BuildTools/Package.swift 检入您的源代码控制中,以便由您的 run-script 阶段使用的版本保存在版本控制中。 建议将以下内容添加到您的 .gitignore 文件中:BuildTools/.buildBuildTools/.swiftpm

注意 (2): 如果您使用的是 Xcode 15 或更高版本,请确保将 ENABLE_USER_SCRIPT_SANDBOXING(也称为“User Script Sandboxing”)选项设置为 NO,否则 SwiftFormat 将无法正确运行。

使用 CocoaPods

1) 将 SwiftFormat CLI 添加到您的 Podfile

  1. 通过 CocoaPodsswiftformat 二进制文件添加到您的项目目录,方法是将以下行添加到您的 Podfile 中,然后运行 pod install

    pod 'SwiftFormat/CLI', '~> 0.55'

注意: 这只会安装预构建的命令行应用程序,而不是 SwiftFormat 框架的源代码。

注意 (2): 以这种方式安装时,GateKeeper 可能会阻止 swiftformat 运行,除非您第一次在 Finder 中右键单击并选择“打开”来手动打开它。

2) 将构建阶段添加到您的应用程序目标

  1. 在文件列表中单击您的项目,在 TARGETS 下选择您的目标,单击 Build Phases 选项卡

  2. 通过单击左上角的小加号图标来添加一个新的 New Run Script Phase

  3. 取消选中 Based on dependency analysis 复选框

  4. 将新的 Run Script 阶段拖动到 Compile Sources 阶段之上,展开它并粘贴以下脚本

    "${PODS_ROOT}/SwiftFormat/CommandLineTool/swiftformat" "$SRCROOT"

替代方案:本地安装的 SwiftFormat

或者,您可以使用本地安装的 swiftformat 命令行工具,方法是将以下内容放入您的“运行脚本构建阶段”中

if which swiftformat >/dev/null; then
  swiftformat .
else
  echo "warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat"
fi

但是,不建议用于共享项目,因为使用不同版本的 SwiftFormat 的不同团队成员可能会导致提交历史中出现噪音,因为代码格式不一致。

如果您在 Apple Silicon 上通过 Homebrew 安装了 SwiftFormat,您可能会遇到此警告

警告:SwiftFormat 未安装,请从 https://github.com/nicklockwood/SwiftFormat 下载

这是因为 Apple Silicon 上的 Homebrew 默认将二进制文件安装到 /opt/homebrew/bin 文件夹中。 要指示 Xcode 在哪里找到 SwiftFormat,您可以将 /opt/homebrew/bin 添加到构建阶段的 PATH 环境变量中

if [[ "$(uname -m)" == arm64 ]]; then
    export PATH="/opt/homebrew/bin:$PATH"
fi

if which swiftformat > /dev/null; then
  swiftformat .
else
  echo "warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat"
fi

或者,您可以在 /usr/local/bin 中创建一个指向实际二进制文件的符号链接

ln -s /opt/homebrew/bin/swiftformat /usr/local/bin/swiftformat

Swift Package Manager 插件

您可以将 SwiftFormat 用作 SwiftPM 命令插件。

注意: 需要 Swift 5.6 或更高版本。 将该软件包添加到您的 Package.swift 文件中的依赖项中。

dependencies: [
    // ...
    .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.55.0"),
]

该插件将在您的软件包根文件夹中找到现有的 .swiftformat 文件,并自动遵守它。

从命令行触发插件

swift package plugin --allow-writing-to-package-directory swiftformat

您可以使用 --target 选项将格式化限制为特定目标。

您还可以指定 SwiftFormat 参数,例如 --swiftversion

例子

swift package plugin --allow-writing-to-package-directory swiftformat --target MyLibrary --swiftversion 5.6 --verbose

从 Xcode 触发插件

在 Xcode 14 中,您可以为 Swift 软件包或 Xcode 项目触发命令插件执行。

对于 Xcode 项目,将处理项目的主目录,并且将忽略 --target 选项。

您还可以指定 SwiftFormat 参数,例如 --swiftversion

Run plugin in Xcode 14

通过 AppleScript

要在最前面的 Xcode 文档(项目或工作区)上运行 SwiftFormat,您可以使用以下 AppleScript

tell application "Xcode"
    set frontWindow to the first window
    set myPath to path of document of frontWindow
    do shell script "cd " & myPath & ";cd ..; /usr/local/bin/swiftformat ."
end tell

您可以从中触发此操作的一些应用程序包括 BetterTouchToolAlfredKeyboard Maestro。 另一个选项是通过 Automator 为 Xcode 定义一个 QuickAction,然后在系统偏好设置中为其分配一个键盘快捷键。

VSCode 插件

如果您更喜欢使用 Microsoft 的 VSCode 编辑器来编写 Swift,则 Valentin Knabel 创建了一个适用于 SwiftFormat 的 VSCode 插件

Sublime Text 插件

如果您更喜欢使用 Sublime Text 编辑器,请尝试由 Aerobounce 提供的 Sublime-Swift-Format 插件

Nova 插件

如果您更喜欢使用 Nova 编辑器,请尝试由 Pádraig Ó Cinnéide 提供的 SwiftFormat 扩展

Git pre-commit 钩子

  1. 请按照说明安装 SwiftFormat 命令行工具。

  2. 安装 git-format-staged

  3. 在您的项目文件夹中编辑或创建 .git/hooks/pre-commit 文件。.git 文件夹是隐藏的,但如果您将 Git 用于您的项目,则应该已经存在,因此使用终端或 Finder 的 前往 > 前往文件夹... 菜单打开它。

  4. 在 pre-commit 文件中添加以下行。 {} 将自动替换为正在格式化的 Swift 文件的路径

    #!/bin/bash
    git-format-staged --formatter "swiftformat stdin --stdinpath '{}'" "*.swift"

    (请注意,此示例使用您本地安装的 SwiftFormat 版本,而不是项目存储库中的单独副本。 如果您愿意,可以将 swiftformat 替换为指向项目内部副本的路径。)

  5. 通过在终端中键入 chmod +x .git/hooks/pre-commit 来启用该钩子。

现在,每当您运行 git commit 时,pre-commit 钩子都将运行。 运行 git commit --no-verify 将跳过 pre-commit 钩子。

注意: 如果您通过 GUI 客户端(例如 Tower)使用 Git,则可能需要其他步骤

注意 (2): 与 Xcode 构建阶段方法不同,git pre-commit 钩子不会签入到源代码控制中,并且无法保证项目的所有用户都使用相同版本的 SwiftFormat。 对于协作项目,您可能需要考虑使用提交钩子,它将在您的持续集成服务器上运行。

GitHub Actions

  1. 所有 macOS GitHub 托管的 runners 上都预安装了 SwiftFormat。 如果您是自行托管,则需要确保 SwiftFormat 已安装在您的 runner 上。
  2. 使用 SwiftFormat 创建一个 GitHub Actions 工作流程,并传递 --reporter github-actions-log 命令行选项。 以下示例操作使用 SwiftFormat 检查 pull request,并使用 GitHub Actions 日志报告警告。
# Lint.yml
name: Lint
on: pull_request

jobs:
  Lint:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - name: SwiftFormat
        run: swiftformat --lint . --reporter github-actions-log

在 CI 中使用 Danger

要设置 SwiftFormat 以便您的持续集成系统使用 Danger,请执行以下操作

  1. 按照 说明 设置 Danger。

  2. danger-swiftformat 插件添加到您的 Gemfile

  3. 将以下内容添加到您的 Dangerfile

    swiftformat.binary_path = "/path/to/swiftformat" # optional
    swiftformat.additional_args = "--indent tab --self insert" # optional
    swiftformat.check_format(fail_on_error: true)

    注意: 建议将 swiftformat 二进制文件添加到您的项目目录中,以确保每次都使用相同的版本(请参阅上面的 Xcode 构建阶段 说明)。

Bazel 构建

如果您使用 Bazel 来构建您的 Swift 项目,并且想要确保只有格式正确的代码才能合并到您的主分支,请尝试 rules_swiftformat。 该存储库包含 Bazel 规则和宏,这些规则和宏使用 SwiftFormat 格式化 Swift 源代码文件、测试格式化文件是否存在于工作区目录中,并将格式化文件复制到工作区目录中。

Docker

SwiftFormat 将发布版本到 GitHub Packages Docker 注册表中。 要拉取镜像,请调用

$ docker pull ghcr.io/nicklockwood/swiftformat:latest

默认情况下,容器运行 swiftformat . 因此,您需要通过参数提供路径

docker run --rm -v /local/source/path:/work ghcr.io/nicklockwood/swiftformat:latest /work

或者通过更改工作目录

docker run --rm -v /local/source/path:/work -w /work ghcr.io/nicklockwood/swiftformat:latest

要检查已安装的 SwiftFormat 版本

docker run --rm ghcr.io/nicklockwood/swiftformat:latest --version

Linting 示例

docker run --rm -v /local/source/path:/work ghcr.io/nicklockwood/swiftformat:latest /work --lint

配置

SwiftFormat 的配置分为 规则选项。 规则是 SwiftFormat 库中用于更改代码的函数。 选项是控制规则行为的设置。

选项

SwiftFormat 中可用的选项可以使用 --options 命令行参数显示。 每个选项的默认值都在帮助文本中指出。

规则通过将 --[option_name] [value] 添加到您的命令行参数,或者通过创建 .swiftformat 配置文件 并将其放置在您的项目目录中来配置。

给定的选项可能会影响多个规则。 使用 --ruleinfo [rule_name] 命令获取有关哪些选项影响给定规则的详细信息,或者参阅 Rules.md 文件。

您可以通过在 Swift 文件内的注释中使用 swiftformat:options 指令来配置特定文件或代码范围的选项。 要临时设置源文件中的一个或多个选项,请使用

// swiftformat:options --indent 2 --allman true

要仅将选项覆盖应用于特定行,请使用 :next 修饰符

// swiftformat:options:next --semicolons inline
doTheThing(); print("Did the thing")

规则

SwiftFormat 包括 50 多个规则,并且一直在添加新规则。 可以在 Rules.md 中找到最新的列表,以及有关如何使用它们的文档。

可以使用 --rules 参数在命令行应用程序中显示可用规则的列表。 规则可以启用或禁用。 大多数默认情况下是启用的。 使用 --rules 显示时,禁用的规则标有“(disabled)”。

您可以使用 --ruleinfo [rule_name] 命令来获取有关特定规则的信息。 传递以逗号分隔的规则名称列表以一次获取多个规则的信息,或者使用不带参数的 --ruleinfo 获取有关所有规则的信息。

您可以使用 --disable 后跟一个或多个以逗号分隔的规则名称列表来单独禁用规则,或者使用 --enable 后跟规则名称来启用选择加入规则

--disable redundantSelf,trailingClosures
--enable isEmpty

如果您愿意,可以使用多个 --enable/--disable 参数,而不是使用逗号

--disable indent
--disable linebreaks
--disable redundantSelf

或者,您可以使用行继续字符 \ 将单个参数换行到多行

--disable          \
    indent,        \
    linebreaks,    \
    redundantSelf

为避免在更新 SwiftFormat 时自动选择加入新规则,您可以使用以下命令禁用所有规则

--disable all

然后单独启用您想要的规则。 或者,使用 --rules 参数启用您指定的规则

--rules indent,linebreaks

如上所述,您可以包含多个 --rules 参数,或使用行继续字符 \ 将规则换行到单独的行

--rules redundantSelf
--rules         \
    indent,     \
    linebreaks

要准确查看哪些规则应用于给定文件,您可以使用 --verbose 命令行选项来强制 SwiftFormat 在应用格式化时打印更详细的日志。 注意: 以 verbose 模式运行比默认模式慢。

您可以通过在 Swift 文件内的注释中使用 swiftformat: 指令来禁用特定文件或代码范围的规则。 要临时禁用源文件中的一个或多个规则,请使用

// swiftformat:disable <rule1> [<rule2> [rule<3> ...]]

要再次启用规则,请使用

// swiftformat:enable <rule1> [<rule2> [rule<3> ...]]

要禁用所有规则,请使用

// swiftformat:disable all

要再次全部启用它们,请使用

// swiftformat:enable all

要临时阻止仅将一个或多个规则应用于下一行,请使用

// swiftformat:disable:next <rule1> [<rule2> [rule<3> ...]]
let foo = bar // rule(s) will be disabled for this line
let bar = baz // rule(s) will be re-enabled for this line

在使用 next 指令后,无需手动重新启用规则。

注意: swiftformat:enable 指令仅用于抵消同一文件中之前的 swiftformat:disable 指令。 无法使用 swiftformat:enable 来启用在格式化开始时尚未启用的规则。

Swift 版本

大多数 SwiftFormat 规则是版本无关的,但有些规则仅适用于较新的 Swift 版本。 如果未指定 Swift 版本,这些规则将自动禁用,因此要确保完整的功能可用,您应指定项目使用的 Swift 版本。

您可以通过以下两种方式之一指定 Swift 编译器版本

您可以使用 --swiftversion 命令行参数指定项目的 Swift 编译器版本。 您还可以将 --swiftversion 选项添加到您的 .swiftformat 文件中。

另一种选择是在您的项目目录中添加一个 .swift-version 文件。 这是一个文本文件,应包含您的项目支持的最低 Swift 版本,并且也受到其他一些工具的支持。 --swiftversion 参数优先于任何 .swift-version 文件。

.swift-version 文件和 .swiftformat 文件中的 --swiftversion 选项都以分层方式应用; 如果您的项目中有使用不同 Swift 版本的子模块,您可以为这些目录添加单独的 Swift 版本配置。

Swift 语言模式

SwiftFormat 还允许您指定项目使用的 Swift *语言模式*。 这与 Swift 编译器版本不同。 例如,您可以使用 Swift 6.0 编译器以及 Swift 5 语言模式或 Swift 6 语言模式。 某些 SwiftFormat 规则在不同的 Swift 语言模式下会有不同的行为。

您可以使用 --languagemode 命令行参数指定项目的 Swift 语言模式。 您还可以将 --languagemode 选项添加到您的 .swiftformat 文件中。

如果未指定,SwiftFormat 将使用指定的 Swift 编译器版本的默认语言模式。 Swift 5.x 和 Swift 6.x 中的默认语言模式是 Swift 5 语言模式。 如果您的项目使用 Swift 6 语言模式,您应该指定 --languagemode 6

配置文件

虽然可以通过使用上面详细介绍的命令行选项规则直接配置 SwiftFormat,但有时创建配置文件会更方便,该文件可以添加到您的项目中并与其他开发者共享。

SwiftFormat 配置文件由一个或多个命令行选项组成,这些选项被分成单独的行,例如

--allman true
--indent tab
--disable elseOnSameLine,semicolons

在格式化时,SwiftFormat 会自动检查每个子目录中是否存在 .swiftformat 文件,并将它在那里找到的任何选项应用于该目录中的文件。

这允许您仅针对特定文件目录覆盖某些规则或格式化选项。 您还可以使用 --exclude 指定相对于该目录的排除文件,这可能比在顶层指定它们更方便

--exclude Pods,Generated

--exclude 选项接受一个逗号分隔的文件或目录路径列表,以从格式化中排除。 排除的路径是相对于包含 --exclude 命令的配置文件的。 排除的路径可以包含通配符,使用 Unix "Glob" 语法指定,如下面文档中所述。

名为 ".swiftformat" 的配置文件将被自动处理,但是,您可以使用 --config "path/to/config/file" 命令行参数选择要用于格式化的其他配置文件。 使用 --config 选择的配置文件不需要命名为 ".swiftformat",并且可以位于项目目录之外。

配置文件格式旨在手动编辑。 您可以包含空行以提高可读性,并且还可以使用哈希前缀 (#) 添加注释,例如。

# format options
--allman true
--indent tab # tabs FTW!

# file options
--exclude Pods

# rules
--disable elseOnSameLine,semicolons

如果您不想手动编辑配置文件,您可以使用SwiftFormat for Xcode应用程序编辑配置并导出配置文件。 您还可以使用 swiftformat 命令行工具的 --inferoptions 命令从您现有的项目中生成一个配置文件,如下所示

$ cd /path/to/project
$ swiftformat --inferoptions . --output .swiftformat

Globs

当使用 --exclude 选项从格式化中排除文件时,您可能希望使用通配符路径(也称为 "Globs")来匹配所有符合特定命名约定的文件,而无需手动列出它们。

SwiftFormat 的 glob 语法基于 Ruby 的实现,它与 Unix 标准略有不同。 支持以下模式

示例

Linting

SwiftFormat 主要被设计为一个格式化程序,而不是一个 linter,也就是说,它旨在修复你的代码,而不是告诉你代码有什么问题。 然而,有时验证代码是否已在不希望实际更改它的上下文中格式化会很有用。

一个典型的例子是作为 CI(持续集成)过程的一部分,您可能希望有一个自动脚本来检查提交的代码是否存在样式违规。 虽然您可以使用单独的工具,例如 SwiftLint 来执行此操作,但能够根据您用于应用它的完全相同的规则来验证格式是有意义的。

为了将 SwiftFormat 作为 linter 运行,您可以使用 --lint 命令行选项

$ swiftformat --lint path/to/project

这运行与格式模式相同的规则,并且所有相同的配置选项都适用,但是,不会修改任何文件。 相反,SwiftFormat 将在内存中格式化每个文件,然后将结果与输入进行比较,并报告需要更改的行。

--lint 选项类似于 --dryrun,但 --lint 会为每行需要更改的内容返回警告,并且如果检测到任何更改,将返回一个非零错误代码(参见下面的错误代码),如果你希望它在你的 CI 服务器上使构建步骤失败,这将非常有用。

如果您希望 --lint 不会使您的构建失败,您可以使用 --lenient 选项强制 SwiftFormat 在 --lint 模式下即使检测到格式问题也返回成功。

$ swiftformat --lint --lenient path/to/project

默认情况下,--lint 仅报告需要格式化的行,但您可以使用额外的 --verbose 标志来显示有关已检查的文件的其他信息,即使不需要进行任何更改也是如此。

如果您不想看到每个格式化更改的警告,您可以使用 --quiet 标志来禁止除错误之外的所有输出。

有时您可能希望自动格式化某些规则,但只 lint 其他规则。 为此,请在您的配置文件中使用 --lintonly 选项来指定仅应在 --lint 模式下应用的规则

--rules braces,indent
--lintonly trailingClosures,unusedArguments

错误代码

swiftformat 命令行工具将始终以以下代码之一退出

缓存

SwiftFormat 使用缓存文件来避免重新格式化未更改的文件。 对于大型项目,这可以显著减少处理时间。

默认情况下,缓存存储在 macOS 上的 ~/Library/Caches/com.charcoaldesign.swiftformat 中,或 Linux 上的 /var/tmp/com.charcoaldesign.swiftformat 中。 使用命令行选项 --cache ignore 忽略缓存的版本并重新将格式应用于所有文件。 或者,您可以使用 --cache clear 删除缓存(或者您可以手动删除缓存文件)。

缓存在所有项目之间共享。 该文件相当小,因为它只存储每个文件的路径和大小,而不是内容。 如果您确实开始因为缓存增长太大而遇到速度变慢的情况,您可能需要考虑为每个项目使用单独的缓存文件。

您可以通过将路径作为 --cache 选项值传递来指定自定义缓存文件位置。 例如,您可能希望将缓存文件存储在您的项目目录中。 如果您想在项目的不同用户之间共享它,可以签入缓存文件,因为存储在缓存中的路径是相对于格式化文件的位置的。

文件头

SwiftFormat 可以被配置为用模板剥离或替换每个文件中的标头注释。“标头注释”被定义为从文件中的第一个非空白行开始的注释块,后面至少跟一个空白行。 这可能由单个注释正文组成,或者由连续行上的多个注释组成

// This is a header comment
// This is a regular comment
func foo(bar: Int) -> Void { ... }

标头模板是一个字符串,您可以使用 --header 命令行选项提供。 传递值 ignore(默认值)将保持标头注释不变。 传递 strip 或一个空字符串 "" 将删除它们。 如果您希望提供自定义标头模板,格式如下

对于单行模板:--header "Copyright (c) 2017 Foobar Industries"

对于多行注释,请用 \n 标记换行符:--header "First line\nSecond line"

如果您愿意,您可以在模板中包含 Swift 注释标记:--header "/*--- Header comment ---*/"

如果您不包括注释标记,模板中的每一行都将以 // 和一个空格作为前缀。

通常的做法是在注释标头版权声明中包含文件名、创建日期和/或当前年份。为此,您可以使用以下占位符

例如,一个标头模板

--header "{file}\nCopyright (c) {year} Foobar Industries\nCreated by John Smith on {created}."

将被格式化为

// SomeFile.swift
// Copyright (c) 2019 Foobar Industries
// Created by John Smith on 01/02/2016.

注意: {year} 值和 {created} 日期格式由运行脚本的机器的当前区域设置和时区决定。 {author.name}{author.email} 需要项目由 git 进行版本控制。

常见问题解答

问:这与 SwiftLint 有什么不同?

A. SwiftLint 的主要设计目的是查找并报告代码中的坏味道和风格违规。SwiftFormat 的设计目的是修复它们。虽然 SwiftLint 可以自动修正一些问题,并且 SwiftFormat 也对代码检查提供一些支持,但它们的主要功能是不同的。

Q. SwiftFormat 和 SwiftLint 可以一起使用吗?

A. 当然可以!这两种工具推荐的风格规则非常相似,SwiftFormat 甚至可以修复一些 SwiftLint 警告但目前无法自动修正的风格违规。

Q. SwiftFormat 支持哪些平台?

A. SwiftFormat 可以在 macOS 10.13 (High Sierra) 及更高版本上运行,也可以在 Ubuntu Linux 和 Windows 上运行。

Q. 支持哪些 Swift 版本?

A. SwiftFormat 框架和命令行工具可以使用 Swift 5.3 及更高版本编译,并且可以格式化用 Swift 4.x 或 5 编写的程序。不再积极支持 Swift 3.x。如果您仍然使用 Swift 3.x 或更早的版本,并且发现 SwiftFormat 破坏了您的代码,最好的解决方案可能是恢复到较早的 SwiftFormat 版本,或者仅启用一小部分规则。使用 --swiftversion 参数可以启用特定于更高 Swift 版本的其他规则。

Q. SwiftFormat 进行了我不想要的更改。如何找出要禁用的规则?

A. 如果您使用 --verbose 选项运行 SwiftFormat,它会告诉您哪些规则应用于每个文件。然后,您可以使用 --disable 参数选择性地禁用某些规则(请参见下文)。

Q. 我的团队成员安装了不同的 SwiftFormat 版本。我们如何确保一致的格式化?

A. 您可以在项目的 .swiftformat` 文件中指定 --minversion 参数,如果开发者尝试使用旧版本的 SwiftFormat,则构建将失败。

Q. 如何修改格式化规则?

A. 许多配置选项都暴露在命令行界面或 .swiftformat 配置文件中。您可以手动设置这些选项,也可以使用 --inferoptions 参数从现有项目中自动生成配置。

如果您不喜欢某个规则,并且无法通过命令行选项将其配置为您喜欢的样式,则可以使用 --disable 参数禁用一个或多个规则,后跟规则名称,用逗号分隔。您可以使用 --rules 参数显示所有支持的规则的列表,它们的行为已在本节上面的 README 中记录。

如果您使用的是 Xcode 源代码编辑器扩展,则可以使用 SwiftFormat for Xcode 宿主应用程序配置规则和选项。不幸的是,由于 Extensions API 的限制,无法在每个项目的基础上配置这些选项。

如果您想要的选项未公开,并且禁用该规则无法解决问题,则这些规则在文件 Rules.swift 中实现,因此您可以修改它们并构建命令行工具的新版本。如果您认为您的更改可能具有普遍用途,请提交 pull request。

Q. 我不想在升级 SwiftFormat 时对添加的新规则感到惊讶。如何防止这种情况?

A. 您可以使用 --rules 参数指定要运行的规则的独占列表。如果添加了新规则,如果您在 SwiftFormat 配置中指定了 --rules 列表,则不会启用它们。

Q. 为什么我无法在 SwiftFormat for Xcode 选项中设置缩进宽度或在制表符/空格之间进行选择?

缩进宽度和制表符/空格可以在 Xcode 中按项目配置。您可以在右侧边栏的文件检查器中的“文本设置”下找到该选项。

Q. 应用 SwiftFormat 后,我的代码无法编译。这是一个 bug 吗?

A. 理想情况下,SwiftFormat 绝不应该破坏您的代码。检查已知问题,如果它尚未列在那里,或者建议的解决方法无法解决您的问题,请在 GitHub 上打开一个 issue

Q. 我可以使用 SwiftFormat 检查我的代码而不更改它吗?

A. 是的,有关详细信息,请参见上面的代码检查部分。

Q. 我可以在另一个应用程序中使用 SwiftFormat.framework 吗?

A. 是的,可以将 SwiftFormat 框架包含在应用程序或测试目标中,并用于许多种类的 Swift 源代码解析和处理,除了格式化之外。SwiftFormat 框架作为 CocoaPod 提供,以便于集成。

已知问题

小费罐

SwiftFormat 不是一个商业资助的产品,它是社区的免费奉献。如果您觉得它有用,请考虑捐赠。

Donate via PayPal

鸣谢

(贡献者完整列表)