一次被拒的 PR,教会我看 README

我一直以为「代码写得好就会有人用」。直到一个自动生成的 PR 被判了「不符合收录条件」,
而真正卡住我的,不是代码、不是截图、不是功能——是 README 用的是中文。

一、事情怎么开始的

AppImage/appimage.github.io 这个目录站有个自动发现流程:它会去 GitHub 上找带 AppImage 产物的项目,自动建 PR 收录。某天我的 HexoManager 被它找到了,自动生成了 PR #9648 ——「Add HexoManager」。

我以为这会是个走流程的事。结果它被判为「非英文界面」,PR 被改成了邀请形式。

第一轮排查,我去看它的判定脚本,以为是截图的锅:它会下载 AppImage、跑起来、截图、OCR 出界面文字,再算中文占比。我检查了 language.txt,那一关是过的。

第二轮才找到真正的原因:判定逻辑不止一条。除了截图 OCR,还有一条 code/readme-language.sh——它会去读仓库根目录的 README。

而这条脚本里有一个豁免条款:只要根目录存在英文版 README,就直接 exit 0 放行(它的正则认 README.en.md、README_EN.md、README.english.md 这几种写法)。

我只有一份中文 README。于是界面是英文的、截图也是英文的,但「上游文档是中文」,照样判你中文。

二、修复只花了一小时,教训花了一个下午

修复很简单:把 README 完整翻译一份,存成 README.en.md,再在 README.md 顶部加一行语言切换。本地按它的脚本逻辑复核了一遍:中文占比 HAN=4,远低于阈值 30,通过。

但我在这里卡了很久,因为我不服气:界面是英文的,为什么还判中文?

后来想通了,而且这个想法让我有点脸红——人家做的是「面向英文用户的收录目录」,它担心的问题根本不是「你的软件能不能显示英文」,而是「一个英文用户点进你的仓库,能不能看懂你在说什么」。README 是仓库的门面,门面上写满中文,后面的代码再漂亮也进不去。

我一直在优化「做出来的东西」,却忽略了「别人看到的第一屏」。

三、之后我改了哪些习惯

这件事之后,我陆续做了几件以前觉得「没必要」的事:

1. 每个仓库至少双语 README。 xfm 这种稍大的项目干脆拆成六份:README / README_CN / INSTALL / INSTALL_CN / PROGRAM / PROGRAM_CN。中文用户看中文,英文用户看英文,装不上的时候有专门的排障页。

2. 把文档站独立出去。 doc.lovou.pw 是专门给主题和工具写的文档站,不再把长篇说明塞在 README 里——README 只回答三个问题:这是什么、怎么跑起来、下一步去哪。

3. 给偏产品的东西做真国际化,而不是只翻界面。 HexoManager 的 i18n 做到了 1356 条 t() 词条、字典 1466 条、缺译文 0。做法是「中文原文即键」:源码保留中文并用 t() 包裹,英文译文集中在一个文件里,命中即翻译、未命中原样回退,不引第三方库。还写了两个脚本:一个增量合并词条(不覆盖手工修正),一个校验覆盖率(缺译文时退出码 1),后者直接当 CI 卡口用。

还有个不得已的过渡层:Rust 侧 250 多条中文错误信息,几十个命令用 Result<T, String> 返回,短期内不可能全改成错误码,于是前端加了一层「精确表 + 带参正则」映射。我在 changelog 里明确写了这是过渡方案,彻底解法是把错误改成错误码枚举——写清楚这件事,比假装它不存在重要。

4. 每个仓库配一篇文章。 不为推广,是为了逼自己回答「它到底解决什么问题」。写不出来的项目,通常也确实没什么人需要。

四、文档改变的不是「发布」,是「设计」

最意外的收获是:写文档的时候,我经常发现自己接口没想清楚。

比如给 xfm 写 INSTALL 时才发现,「全局安装失败」有四种原因(权限、PATH、Node 版本、镜像源),而我原来的错误提示只说了一句「安装失败」。写文档等于模拟一遍陌生人的路径,模拟到一半就会发现哪里断了。

同理,给 X-Notepad 的插件写权限说明时,我才意识到「权限清单」不只是一份文档,它还要被校验、被展示、被拒绝——文档直接变成了功能需求。

以前我把文档当收尾:代码写完,顺手写点说明。
现在我把文档当前置:说不清楚怎么用,就说明还没想清楚怎么做。

五、心态的变化

写代码的人容易有一个错觉:作品的价值在实现里。但开源这件事的规则不是这样——在别人读到你的代码之前,他先读到的是你的说明。

那次 PR 到现在也没让我多几颗星。但它让我停掉了「先堆功能、文档以后补」的习惯,也让我第一次认真对待「陌生人视角」这四个字。

现在每开一个新仓库,我第一件事是写 README:一句话说清它是什么,三行说清怎么跑,一段说清它不做什么。写不完这三段,就先别开这个仓库。