概述

Fuchsia 开发者可以使用各种工具来执行 lint 请求和格式化代码。这个 对每种语言的相应工具进行了简要介绍,并说明了另外 应添加 lint 检查以及它们应遵循的准确性标准。

请注意,这不会尝试解释每个 linter 和 。不过,执行 lint 请求和格式化的目的是鼓励和强制执行建议 围绕风格和最佳做法,每种相关语言都有自己的指南来解释 决策和启用的配置。

工具集成

Fuchsia 团队提供了两种设置代码格式和 lint 代码的方法:开发者端 fx 中的子命令 工具,以及针对上传更改集成的 Tricium 分析。此外,部分格式和 lint 可以直接包含在 build 中,但在准确性方面有严格的限制。

开发者工具(IDE 和 fx)

主要的开发者工具套件是 fx 命令及其子命令。它提供两个 此处相关的子命令:fx format-code 和 fx lint。每种产品都基于 并将输出内容输出到终端的 stdout/stderr。运行 fx lint 会假定 开发者已经运行 fx build;否则许多 linter 就会生成 缺少 build 创建的文件。

可以通过以下三种方式之一指定文件列表:

  • 自从倒数第二次 Git 提交以来更改的文件列表,包括已提交、已修改、 和缓存的文件(这是默认行为)
  • 以逗号分隔列表的形式传递到 --files 标志的文件列表
  • GN 目标中传递给 --target 标志的文件列表

格式就在原地完成。执行 lint 请求在默认情况下只发出警告,但用户可以将 --fix 标志传递给 fx lint 以自动修复那些工具已提供修复的错误。

大多数编辑器还会集成格式化程序和 linter,以便开发者自动 format-on-save 或 format-on-keybinding。在大多数情况下,设置(如果有)包括指向 IDE 在相关配置文件和 Fuchsia 分布式工具二进制文件中。

集成工具 (Tricium)

Tricium 是一项与 Gerrit 代码审核系统集成的服务,可显示 以不阻止提交的方式显示警告。当用户上传每个补丁集时, 提交对 Fuchsia 代码库的访问权限并运行两套工具分析。

格式化程序分析会进行最少的检出(无 third_party,无预构建),并提取列表 从补丁提交中更改的文件数量。它会根据 每个文件。如果生成的格式文件与上传的补丁中的文件内容不同, Tricium 对补丁发布了一条评论,解释了如何在该文件上运行相应的格式化程序。

linter 分析会执行全面检出,并执行最少量的构建(以生成必要的代码 配置文件和标头)。它从补丁提交中提取已更改文件的列表, 然后根据文件扩展名运行相关的 linter。机器可读输出是从 如果生成了警告,系统会解析输出,并将其收集到注释中 表单。然后,Tricium 会对相应的行进行注释,并显示 linter 警告。

Tricium 在可能的情况下仅对提交中已更改的行运行工具,但并非全部 linter 支持此行为。对于支持 lint 请求,这是为了让现有但不相关的 lint 错误并不会分散对更改本身的注意力,并且只会显示直接相关的 lint。

分析结果通常基于启发法。因此,他们不时地 假正例。Fuchsia 旨在为此类分析服务提供高标准服务,支持 错误率超过 10%。

通常,应将新的 linter 添加到现有的 Tricium 配方中。从结账/构建时间开始 到目前为止,这些 build 的成本最高(分析本身最多需要几秒钟, 最糟糕的是几分钟,而签出和/构建可能需要更长时间),但从 同时考虑时间和基础架构资源,以轻松扩展现有构建器。通过 应根据所需信息量选择要扩展的配方,例如如果 运行分析时不需要预构建/third_party 代码,应采用最少的结账方法 。

build 集成

提供零假正例率的 linter 检查的另一种方法是将其包含在 build。 除非确定并非如此,否则不建议针对此类问题添加额外的检查 假正例触发。

这些检查直接在 build 中实现(通常作为运行相关 脚本),因此如果它们捕获错误,会导致整个构建失败。它们还扩展了 因此只应在能为广告客户提供有价值的正确信息时才使用 开发者。

标准

格式化程序

格式化程序应遵循相关的风格指南,但格式化程序的输出是否是 风格指南的可信来源由语言及其风格仲裁者决定。当 formatter 在上游社区中发生了变化(例如,当 Rust 社区更改了 rustfmt 时), 更新后的格式化程序将随工具链一起推进到 Fuchsia 中。这种情况很少发生, 可能会导致 Tricium 和本地工具之间出现格式冲突,直到开发者更新为 使用新的工具链。

一般来说,Fuchsia 对格式设置工具的支持取决于开发者使用 命令。唯一的自动化操作来自 Tricium,它会在文件与 formatter 的输出,但不会阻止 CL 的提交。

Linters

linter 通常应向开发者提供实用且实用的注释。由于它们通常都是 它们可能会产生假正例,但是任何超过 10% 假正例的 linter 速率。添加 linter 检查的流程是提交 bug,请求新的 并概述其值和预期假正例率。移除 linter 检查可以 通过提交 bug 或提交包含所请求的配置更改的补丁来完成。

只有保证不会产生误报的 linter 才应在 build 中实现 本身。这些措施应由本地 build 和 CQ 强制执行,以免出现意外 当开发者尝试提交代码时触发。

语言工具

每种受支持的语言都提供格式化程序和可选的 linter。本部分介绍了 这些工具集成到 Fuchsia 工作流中。虽然格式化程序往往 简单明了,但 linter 的集成方式有点复杂。在大多数情况下 开发者无需了解 fx 和 Tricium 的内部机制。

假定所有命令都从 Fuchsia 检出的根目录运行。

C/C++

C/C++ 代码使用 clang-formatclang-tidy。这些模块通过 Clang 中的预构建版本进行分发 工具链。两者都使用根级配置文件(.clang-format.clang-tidy, )。开发者不应在较低级别创建额外的配置文件,因为 这会导致规则树出现分歧。

clang-format 按如下方式在源文件上运行:

prebuilt/third_party/clang/$HOST_PLATFORM/bin/clang-format \
-i \
-style=file \
-fallback-style=Google \
-sort-includes \
$FILES

在运行 clang-tidy 之前,您必须:

  • 构建一组生成的标头。 clang-tidy 工具会对 Fuchsia 中的源代码以及大多数 C 和 C++ 代码进行部分编译 包含作为 build 的一部分生成的头文件。

编译数据库和生成的头文件存在后,您就可以运行 run-clang-tidy.py 脚本来启动 clang-tidy 工具。脚本负责处理并行化和去重 错误的数量。当多个源文件包含相同的标头时,这是必要的。当您 使用此脚本,您还必须将 clang-tidyclang-apply-replacements 二进制文件从 分布式 Fuchsia 工具链,以确保使用正确的命令。

export CLANG_TOOLCHAIN_PREFIX=prebuilt/third_party/clang/$HOST_PLATFORM
$CLANG_TOOLCHAIN_PREFIX/share/clang/run-clang-tidy.py \
  -clang-tidy-binary $CLANG_TOOLCHAIN_PREFIX/bin/clang-tidy \
  -clang-apply-replacements-binary $CLANG_TOOLCHAIN_PREFIX/bin/clang-apply-replacements \
  $FILES

可以添加一个可选的 -fix 标志,以自动应用修复。您可在 开发端工具

Rust

Rust 代码使用 rustfmtclippy。它们以预构建版本的形式从 Rust 工具链分发。通过 格式化程序具有根级配置文件 (rustfmt.toml)。

rustfmt 在源文件上运行,如下所示:

prebuilt/third_party/rust/${HOST_PLATFORM}/bin/rustfmt \
--config-path=rustfmt.toml \
--unstable-features \
--skip-children \
$FILES

默认情况下,fx build 会在所有 Rust 目标上运行 clippyclippy 个警告 在预提交过程中被视为构建错误。

如果您只想运行 linter,也可以在 GN 目标上本地调用它 替换为我们的 fx 帮助程序脚本:

fx clippy TARGET
fx clippy --files FILE1 FILE2 # Filters lints for a list of specific files
fx lint # Same as --files but implicitly runs on locally changed files

启用 Clippy lint

要查看您的目标的 lint,您需要通过以下某种方式启用它们:

  • 通过添加配置 configs += [ "//build/config/rust/lints:clippy_warn_all" ],在特定目标上启用一组默认的 Clippy lint。
  • 在本地使用 gn 参数 fx set core.x64 --args clippy_warn_all=true 为每个目标启用剪辑 lint 作为警告。这对于在为 crate 启用 lint 之前确定哪些 lint 比较常见,或者在整个项目中收集 lint 频率等统计信息非常有用。

点击此处列出了所有可用的 Clippy lint 及其名称。

针对特定代码停用 Clippy lint

#[allow(clippy::LINT_NAME)] 添加到您希望忽略任何 Rust 代码中 特定 lint。请注意,属性不能应用于所有表达式 因此可能需要将该属性应用到包含的语法元素。

Go

Go 代码使用 gofmtgo vet。它们作为 Go 工具链构建的一部分进行构建, 在 Go 主机工具链预构建中分发。

gofmt 在源文件上运行,如下所示:

prebuilt/third_party/go/$HOST_PLATFORM/bin/gofmt -s -w $FILES

TODO(https://fxbug.dev/42101826):在确定实施细节后,审查文档。

FIDL

FIDL 代码使用 fidl-formatfidl-lint 工具。它们作为主工具从树内构建而成。 在运行之前,必须构建 zircon/tools 目标以使二进制文件存在。

fidl-format 在源文件上运行,如下所示:

$ZIRCON_BUILD_DIR/tools/fidl-format -i $FILES

fidl-lint 在源文件上运行,如下所示:

$ZIRCON_BUILD_DIR/tools/fidl-lint $FILES

GN

GN 文件使用 gn format 子命令。我们没有 linter,这将作为 GN 预构建版本。

它在源文件上运行,如下所示:

prebuilt/third_party/gn/$HOST_PLATFORM/gn format <files>