Homebrew 文档维护实战:docs/AGENTS.md 写作规范与校验工作流解析
【免费下载链接】brew🍺 The Package Manager for Everywhere项目地址: https://gitcode.com/GitHub_Trending/br/brew
docs/AGENTS.md是 Homebrew/brew 仓库为文档贡献者(无论人还是 AI Agent)编写的操作说明,它把 docs 站点维护的工具链选择、Markdown 写作风格和四层校验命令固定成一套可执行规范。本文围绕该文档展开,结合 .github/workflows/docs.yml、docs/Rakefile、docs/Gemfile 与 Vale 风格库等仓库实况,说明如何在本地复现与 Homebrew 官方一致的文档校验流水线。读完你将掌握一套从写作到 lint、到断链检查、再到 CI 发布的完整方法,可以直接套用到任何 Jekyll 驱动的大型文档站点维护中。
一、文档定位:一份写给人与 AI Agent 的维护说明书
docs/AGENTS.md带 Jekyll 前置元数据last_review_date: "2026-06-10",标题为 "Agent Instructions for Homebrew/brew docs",开篇即限定适用范围:"These instructions apply when working indocs/"。
也就是说,它是一份作用于目录边界的约定文档:凡是在docs/目录下增删改文档,都应遵守其规则。之所以需要这样一份说明,是因为 Homebrew 的文档站点并非手写 HTML,而是基于 Jekyll 静态站点工具链(见 docs/_config.yml),从几十篇 Markdown 生成 docs.brew.sh 等另有渠道)。
一个容易被忽略的细节是:docs/_config.yml 的exclude列表中明确排除了AGENTS.md,同时被排除的还有Gemfile*、Rakefile、vale-styles等工程性文件。这印证了 AGENTS.md 的定位:它面向编辑者而不是读者,不会被 Jekyll 构建成公开页面,而是与仓库根目录的 AGENTS.md、CLAUDE.md 一脉相承,作为人类协作者与 AI 编程助手共同的"进场须知"。
从内容结构看,这份文档由四部分组成,下文逐一展开:
| 部分 | 解决的问题 |
|---|---|
| Tooling | 用什么命令跑 docs 工具链、为什么不用./bin/brew |
| Markdown style | 文档写作的排版、拼写与链接规范 |
| Verification | 改完文档后本地要跑哪些校验 |
| Notes | 站点构建、Rake 任务与 manpage 再生成的补充约定 |
二、工具链:用brew bundle exec管理 docs 的 Ruby 环境
AGENTS.md 的 Tooling 部分给出了三条关键约定,直接决定了 docs 目录下所有命令的形态:
- 从
docs/目录使用系统级 Homebrew 的brew bundle exec ...工作流,而不是./bin/brew。原因在于 docs 站点是一个独立的 Ruby/Jekyll 项目(依赖定义在 docs/Gemfile),并不需要 brew 本体自举运行;用brew bundle拉起的 Bundler 环境最贴近官方 CI(.github/workflows/docs.yml 同样用bundle exec rake ...形式执行任务)。 - 所有校验命令都设置
HOMEBREW_NO_AUTO_UPDATE=1,避免 brew 在跑校验时先触发自身自动更新,从而与 CI 环境保持一致、加快反馈速度。这一点在 .github/workflows/docs.yml 的环境变量中同样成对出现(另有HOMEBREW_DEVELOPER、HOMEBREW_NO_ENV_HINTS等)。 - 用
brew bundle exec bundle install安装或刷新文档 Ruby 环境。docs/下存在 Brewfile 与 Gemfile,前者描述 brew 侧需要的东西,后者声明 Jekyll 及其插件。
以 Ruby 侧为例,docs/Gemfile 精确刻画了工具链的组成,这也是我们理解后续每条校验命令的前提:
- 构建侧:
jekyll及插件组,其中jekyll-relative-links负责把文档里的.md相对链接在渲染时解析为最终页面 URL(这正是"写链接只写文件名"能成立的底层机制),jekyll-seo-tag、jekyll-sitemap、jekyll-titles-from-headings等负责 SEO 元数据。 - 文档侧:
yard与yard-sorbet,对应 Rakefile 里从 Ruby 源码生成 YARD API 文档的任务。 - 测试侧:
html-proofer(断链与 HTML 合法性检查)、mdl(Markdownlint)、rake。
典型的首次环境准备命令为:
# 在 docs/ 目录下执行 HOMEBREW_NO_AUTO_UPDATE=1 brew bundle exec bundle install需要说明的是,docs/下并没有现成的可执行文件,bin/jekyll这类调用依赖 Bundler 对本地 binstub 或 gem 内可执行文件的解析,brew bundle exec的职责就是保证解析发生在 Bundler 锁定的版本上。若你只是快速预览文档效果,CI 中使用的等价路径是bundle exec rake build(见 docs/Rakefile)。
三、写作规范:文档风格的可机械化约束
AGENTS.md 的 Markdown style 部分总结了 Homebrew 文档的排版底线,每一句几乎都能在仓库的工具配置或样式指南里找到落点。下面是逐条解读与仓库佐证。
3.1 语义换行与表格对齐
- 每句话独占一行(semantic line breaks),而不是按固定列宽回行。这样 diff 只影响改动的句子,review 时更干净。这条规范在 docs/Prose-Style-Guidelines.md 的 "One sentence per source line in Markdown, without wrapping prose to a fixed width" 中被再次确认。
- Markdown 表格要用空格补齐列宽,让源文件里
|竖线肉眼可对齐。虽然渲染结果一样,但对协作审阅极其友好。
3.2 拼写:英式拼写与 licence / license 的语义分工
- 全文使用英式拼写与标点。
- 名词用
licence,动词用license;但当指代确切接口名时保留原样license——例如 Formula DSL 中的license方法、命令行选项。仓库里 docs/Licence-Guidelines.md 一整篇都在讨论如何在现实语境下区分二者,AGENTS.md 只是把结论收敛成一条可执行规则。
3.3 标点与列表
- 避免 em-dash(破折号),改用分号、冒号与逗号。
- 不使用 Oxford comma(牛津逗号)。
- 嵌套无序列表缩进 2 个空格。
这两条均有工具背书。Vale 样式库 docs/vale-styles/Homebrew/OxfordComma.yml 会在正文中捕捉牛津逗号;而 docs/index.mdl_style.rb 的rule "MD007", indent: 2正是为"无序列表缩进"量身定制的 Markdownlint 配置。注意同文件中exclude_rule "MD013"关闭了行宽检查,正是为了让"每句一行"的规范不被行宽规则误伤。
3.4 链接与 URL
- 禁止裸 URL,一律使用 Markdown 链接。
- 站内链接必须指向
.md文件本身,例如[Bottles](https://link.gitcode.com/i/20272004a445d48f7effe4666f2581a3),而不是docs.brew.sh的成品 URL。这背后的技术原因是jekyll-relative-links插件会在构建时把这些相对 Markdown 路径自动解析成站点内页面;把链接写成.md还让仓库内浏览(如 GitHub 代码视图)也能直接跳转。
按仓库根路径换算,AGENTS.md 中示例Bottles.md实际指向 docs/Bottles.md。文档站点中这类相对链接在源文件里全部是"文件名 +.md"的形式。
四、校验工作流:四类检查本地全量复现
AGENTS.md 强调,修改文档后应运行 .github/workflows/docs.yml 与 docs/Rakefile 中相关的检查。以下命令均以docs 目录为工作目录执行(除明确注明"仓库根"的之外)。
4.1 环境与构建
HOMEBREW_NO_AUTO_UPDATE=1 brew bundle exec bundle install HOMEBREW_NO_AUTO_UPDATE=1 brew bundle exec bin/jekyll build第一条确保依赖齐全;第二条本地构建站点,是后续 lint/test 的先决条件。docs/Rakefile 中rake build就是对bundle exec jekyll build的封装,CI 正是通过bundle exec rake build(.github/workflows/docs.yml)执行的。
4.2rake lint:Markdownlint 与元数据完整性
HOMEBREW_NO_AUTO_UPDATE=1 brew bundle exec bundle exec rake lintrake lint(docs/Rakefile)实际做了两件事:
- 对
git ls-files '*.md'追踪的文档跑mdl,但排除Manpage.md与站点首页index.md(首页单独使用 docs/index.mdl_style.rb 这份更宽松的规则,它豁免了行宽、标题层级、裸 URL 等规则,并把 MD007 缩进固定为 2)。 - 检查每个
.md文件是否都带last_review_date前置元数据——这就是为什么 docs/AGENTS.md 自身顶部也有last_review_date: "2026-06-10"。
4.3rake test:HTMLProofer 断链与结构检查
HOMEBREW_NO_AUTO_UPDATE=1 brew bundle exec bundle exec rake testrake test(docs/Rakefile)会先构建站点,再用html-proofer检查_site/产物,重点包括:4 线程并行、自定义 User-Agent(兼容 403/429 反爬)、校验 favicon 与 OpenGraph 标签、强制 HTTPS、并针对 GitHub 等外部 URL 配置一天缓存。因此它既能发现仓库内.md链接失效,也能发现外部链接返回 404/403/429。在 CI 中该步骤只在 pull request 上执行并失败重跑一次(.github/workflows/docs.yml),因为每次全量外部检查成本较高。
4.4 Vale 文案检查与 RuboCop 代码块风格
AGENTS.md 明确要求在仓库根目录额外执行两条内容变更类检查:
rg --files docs -0 -g '*.md' -g '!vendor/**' -g '!_site/**' -g '!rubydoc/**' | xargs -0 vale HOMEBREW_NO_AUTO_UPDATE=1 brew style docs第一条先把docs/下所有 Markdown(排除构建产物与 vendor)以 NUL 分隔喂给 Vale。Vale 的规则由 .vale.ini 指定:样式路径为./docs/vale-styles,同时适用于*.md与*.rb,启用Homebrew样式集合。这一集合即 docs/vale-styles/Homebrew 下的多个 YAML 规则文件,例如:
- Terms.yml:把
Pull Request纠正为pull request、Rubocop纠正为RuboCop、非上下文的MacOS纠正为macOS、ruby纠正为Ruby。 - OxfordComma.yml:拦截牛津逗号。
- 另有 Headings.yml(标题大小写)、Spacing.yml(空格)等,构成了一套可自动执行的风格约束层,是"人写规范 + 机器兜底"的典型实践。
第二条brew style docs用 RuboCop 检查文档中嵌入的 Ruby 代码块是否符合仓库的代码风格,对应 CI 中的 "Check code blocks conform to our Ruby style guide" 步骤(.github/workflows/docs.yml)。
4.5 manpage 与补全的联动再生成
AGENTS.md 的 Notes 部分最后提醒:当文档改动依赖 manpage 或补全脚本的更新时,需要先运行:
brew generate-man-completions --no-exit-code在官方 CI 中,这一步位于 "Cleanup Homebrew/brew docs" 步骤(.github/workflows/docs.yml),即对 Homebrew/brew 本体仓库在跑 Vale 之前先重新生成manpages/brew.1与 shell 补全,--no-exit-code保证生成结果差异不阻断主流程。实现入口可参考 Library/Homebrew/cmd/generate-man-completions.rb。
五、本地校验与 CI 的映射关系
把 AGENTS.md 给出的本地命令与 .github/workflows/docs.yml 的 docs job 对照,能清晰看到这套工作流的设计哲学:让本地开发者/Agent 跑与 CI 完全一致的命令,把"提交后才被 CI 打回"的概率降到最低。
| 本地校验(docs/ 下) | CI 对应步骤 | 检查目标 |
|---|---|---|
brew bundle exec bundle install | "Setup Ruby"(bundler-cache) | Ruby 依赖就绪 |
brew bundle exec rake lint | "Check Markdown syntax" | Markdownlint +last_review_date |
brew style docs | "Check code blocks…" | 文档中 Ruby 代码块风格 |
rake build(jekyll build) | "Build the site" | 站点可构建 |
rake test | "Check for broken links"(仅 PR) | HTMLProofer 断链检查 |
rg ... \| xargs -0 vale | "Install Vale" +vale docs/ | 英式拼写、术语、逗号等文案 |
brew generate-man-completions | "Cleanup Homebrew/brew docs" | manpage 与补全同步 |
此外,针对 Homebrew/brew 本体,CI 在全部检查通过后还会执行rake yard从Library/Homebrew的 Ruby 源码重新生成 YARD API 文档(docs/Rakefile,.github/workflows/docs.yml),并最终把_site/作为 GitHub Pages 产物上传部署。部署失败时还会自动开/关 GitHub issue(.github/workflows/docs.yml),形成"构建-检查-部署-告警"的完整闭环。
六、可复用的实践清单
把 docs/AGENTS.md 的方法论抽象出来,任何维护 Jekyll 类文档仓库的团队都可以照搬这套分工:
- 写一份只面向编辑者的 AGENTS 说明,并确保它被 Jekyll
exclude,不进入公开站点;把工具链约定、风格底线、校验入口写死在上面。 - 工具链统一走 Bundler:把风格检查器(
mdl、vale)、构建器(jekyll)、质量器(html-proofer)全部锁进 Gemfile,配合HOMEBREW_NO_AUTO_UPDATE=1类环境开关消除环境漂移。 - 把风格规范翻译成可执行规则:语义换行让 diff 干净,表格对齐便于审阅,而牛津逗号、术语大小写交给 Vale,缩进交给 Markdownlint,代码块交给 RuboCop——规范落在配置里才不会被遗忘。
- 本地命令与 CI 命令一一对应:
rake lint、rake test、rake build分层封装,CI 只做编排(安装 Vale、缓存 proofer、上传产物),逻辑全在本地可复现的 Rake 任务与配置文件里。 - 特殊文件特殊处理:
Manpage.md、index.md使用独立 lint 规则(见 docs/index.mdl_style.rb),既保留首页的灵活性,又不牺牲其余文档的严格度。
结语
docs/AGENTS.md篇幅虽短,却精准浓缩了 Homebrew 文档工程化的全部要点:面向docs/目录的明确边界、以brew bundle为锚的依赖管理、可被 Vale/Markdownlint/RuboCop 自动执行的行文规范,以及一套与.github/workflows/docs.yml完全对齐的本地校验命令。对文档贡献者而言,它是"照做即通过 CI"的捷径;对正在搭建大型文档项目的团队而言,它更是一份关于如何让文档质量检查从人工评审走向工程化流水线的成熟范本。
【免费下载链接】brew🍺 The Package Manager for Everywhere项目地址: https://gitcode.com/GitHub_Trending/br/brew
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考