reviewdog:把任意 linter 的输出变成 diff 上的评论
自动代码审查工具与任何代码分析工具集成,无论编程语言如何。
秒懂
- 它是什么?
- reviewdog 是一个用 Go 写的命令行工具,它读取 linter 的 stdout,解析出文件、行号和消息,然后只把落在 diff 范围内的发现发到 GitHub、GitLab 或 Bitbucket 的评论里。核心机制是 errorformat 解析和 diff 过滤,适合想统一代码审查入口的团队。
- 适合谁用?
- reviewdog 适合那些已经在用多种 linter、并且希望审查意见只出现在实际改动行上的团队。它把解析和过滤逻辑集中在一个工具里,CI 脚本里只需一条管道命令。
- 能商用吗?
- 可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 2 天前。
- 用什么语言写的?
- 主要是 Go(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月14日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决的是审查噪音问题
代码审查里最烦人的不是 linter 报错,而是报错位置和本次改动无关。reviewdog 的核心思路很直接:它不替代任何 linter,而是站在 linter 和代码托管平台之间。它从 stdin 读取 linter 的输出,解析出文件、行号、列号和消息,然后拿这些数据和当前 diff 做比对。只有落在 diff 范围内的发现才会被发出去。这意味着老代码里堆积的警告不会刷屏,审查者看到的就是本次提交引入的问题。这个工具适合那些已经有一套 linter 组合、但不想为每个 linter 单独写 CI 上传逻辑的团队。
errorformat:从 Vim 借来的解析语法
reviewdog 不限定你用什么语言或工具,因为它不内置解析规则。它用的是 errorformat,这是从 Vim 的 quickfix 功能移植过来的格式描述语言。比如最常见的输出格式是“文件名:行号:列号: 消息”,对应的 errorformat 就是 %f:%l:%c: %m。你通过 -efm 参数把它传给 reviewdog。这个设计的好处是,任何能输出文本的工具都能接入,坏处是你得为不常见的输出格式写 errorformat。文档里提到 errorformat 能处理更复杂的输出,但具体多复杂,需要去 reviewdog/errorformat 仓库查。如果你不想写 errorformat,还可以用 RDFormat,这是 reviewdog 自己的诊断格式,或者直接用 checkstyle 和 SARIF 格式。SARIF 是很多现代分析器支持的标准化输出,能省掉不少解析工作。
diff 过滤和 filter mode 的取舍
reviewdog 的过滤逻辑是它的价值所在,但文档里有个细节值得注意:filter mode。默认情况下,它只报告新增的行,也就是 diff 里加号开头的部分。这能避免重复报旧问题,但如果你的团队希望看到改动行上所有现存问题,比如重构时想顺带清理,就得调整模式。文档没有详细列出所有 filter mode 的取值,只说有几种模式可选。这意味着默认行为可能不是你要的,需要自己试。另外,diff 的来源可以是 git diff 的输出,也可以是 CI 提供的事件数据。在本地环境,你可以用 -diff="git diff FETCH_HEAD" 这样的方式,只审查未推送的改动。
reporter 矩阵:从本地到 GitHub Checks
reviewdog 的输出目标通过 -reporter 参数指定。默认是 local,也就是把过滤后的结果直接打印到终端,适合本地跑。要发到 GitHub,有几个选项:github-pr-check 对应 PR Checks,github-check 对应 Checks,github-pr-review 是 PR review 评论,还有 github-annotations 和 github-pr-annotations。区别在于评论的呈现形式,比如 pr-review 会以代码评论的形式出现在 diff 里,而 check 会显示在 Checks 标签页。GitLab 有 gitlab-mr-discussion 和 gitlab-mr-commit,Bitbucket 有 bitbucket-code-report。这意味着一个工具能覆盖三个主流平台,但每个平台的配置方式不同,需要设置对应的 token 和环境变量。文档里列出了支持的 CI 服务,包括 GitHub Actions、Travis、Circle、GitLab CI 和 Bitbucket Pipelines,还有 Jenkins 配合 pull request builder 插件的方式。
安装和最小可用配置
安装方式很多,最简单的是一行 curl 脚本,默认装到 ./bin/。也可以指定版本和目录,比如 curl -sfL .../install.sh | sh -s -- -b $(go env GOPATH)/bin v0.21.0。macOS 用户可以用 brew install reviewdog/tap/reviewdog,Windows 有 Scoop,或者用 go install github.com/reviewdog/reviewdog/cmd/reviewdog@latest。最小用法是:golint ./... | reviewdog -efm="%f:%l:%c: %m" -diff="git diff FETCH_HEAD"。这条命令把 golint 的输出解析后,只打印 diff 内的发现。要发到 GitHub,需要设置 REPOVDOG_GITHUB_API_TOKEN 或类似的环境变量,具体名称文档没写全,但官方 action reviewdog/action-setup 可以帮你装好工具。
退出码和 CI 集成的坑
reviewdog 的退出码有约定,文档里专门有一节。默认情况下,如果 diff 内有发现,它会返回非零码,具体是 2。这会影响 CI 的通过与否。如果你的 CI 流程里把 reviewdog 当作检查步骤,那么有发现就会导致构建失败,这通常是期望的。但如果你只想发评论而不阻断,可能需要调整参数。文档没有明确说怎么关闭阻断,但你可以从退出码的设计推断,默认行为是阻断的。另一个坑是 diff 来源:在 GitHub Actions 里,reviewdog 能自动获取 PR 的 diff,但在 Jenkins 这类通用 CI 上,你需要自己提供 diff 内容,比如用 git diff 命令生成。文档里提到了 Common (Jenkins, local, etc...) 一节,说明这是常见场景,但配置复杂度会上升。
config 文件与代码建议功能
除了命令行参数,reviewdog 支持配置文件,文档里有专门一节叫 reviewdog config file。配置文件可以集中管理 errorformat 和 reporter 设置,避免每条 CI 命令都写一长串参数。文档还提到了 Code Suggestions 功能,这应该是 reviewdog 能提供代码修改建议,而不仅仅是报错消息。但 README 里没有详细说明建议的格式和触发条件,需要看设计文档或源码。从仓库布局看,这是一个相对成熟的项目,有 CHANGELOG.md 和 nightly release,说明维护活跃。最近一次发布是 v0.21.0,2025 年 9 月,距离上一个版本有九个月,节奏不算快但稳定。
替代方案和适用边界
最直接的替代是 GitHub Actions 里的官方 linter action,比如 actions/setup-node 配合 eslint 的 action,它们通常已经集成了评论功能。区别在于,那些 action 是为特定 linter 设计的,而 reviewdog 是通用的。如果你只用一种语言,官方 action 可能更简单,因为不需要写 errorformat。另一个替代是直接写 CI 脚本,用 grep 过滤 diff,但那样每个项目都要重复造轮子。reviewdog 的劣势在于,它需要你理解 errorformat 的语法,虽然常见格式有预定义的 errorformat 列表,但文档里提到“Available pre-defined 'errorformat'”,说明有一些现成的,具体有哪些需要去查。如果你的 linter 输出非常规,比如多行消息或者跨文件引用,解析起来会比较痛苦。还有一点,reviewdog 本身不做代码分析,它只是搬运工,所以它不会帮你发现新问题,只负责把已有问题放到正确的位置。
编辑结论
reviewdog 适合那些已经在用多种 linter、并且希望审查意见只出现在实际改动行上的团队。它把解析和过滤逻辑集中在一个工具里,CI 脚本里只需一条管道命令。如果你只用单一语言且 linter 已经原生支持 GitHub Actions,比如 ESLint 或 RuboCop,那么官方 action 可能更省事。如果你需要把结果发到 GitLab 或 Bitbucket,reviewdog 是少数能统一处理的方案。在采用前,先确认你的 linter 输出能否映射到 errorformat 或 RDFormat,尤其是那些输出多行堆栈或非标准路径的。还要检查 filter mode 的默认行为,它默认只报告新增行,如果你希望看到所有改动行的意见,需要显式设置。最后,注意 exit code 2 表示有 diff 内的发现,CI 流程要据此决定是否阻断。
社区笔记