news 2026/9/10 17:55:04

SerenityOS 贡献指南:从 Issue 规范、C++ 编码风格到 commit hook 的完整协作实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SerenityOS 贡献指南:从 Issue 规范、C++ 编码风格到 commit hook 的完整协作实践

SerenityOS 贡献指南:从 Issue 规范、C++ 编码风格到 commit hook 的完整协作实践

【免费下载链接】serenityThe Serenity Operating System 🐞项目地址: https://gitcode.com/GitHub_Trending/se/serenity

SerenityOS 是一个从零自研的操作系统项目,其 CONTRIBUTING.md 定义了整个社区的协作契约:包括 Issue 提交流程、人类语言政策、C++26 编码风格、提交信息格式、Pull Request 评审预期,以及仓库内置的 pre-commit / commit-msg 钩子。本文以该文档为主线,结合仓库内的 .pre-commit-config.yaml、Meta/lint-commit.sh、Meta/lint-ci.sh、Meta/check-style.py 与 Documentation/CodingStyle.md 等真实实现,给出可直接落地执行的全流程贡献实操指南。

贡献前的方向确认

SerenityOS 对贡献者的第一要求是:确保你的改动符合项目发展方向。如果你不确定,应先在仓库中开启一个 Issue 讨论,而不是直接提交大段代码。

  • 对于最初的一两个 Pull Request,文档明确建议从小改动开始,先熟悉项目与开发流程;
  • 禁止以新增一个应用程序、库或其他大型组件作为首次 PR
  • 项目欢迎所有人参与,文档的原话是"我们玩得很开心,但这是认真的那种开心"——意味着协作氛围轻松、但对工程质量要求严肃。

从仓库结构可以看到项目的宏大版图:内核(Kernel/)、基础库(AK/)、浏览器(Ladybird/)以及数千个用户态程序(Userland/)。这也解释了为什么文档要求新贡献者从小处入手——改动必须能被维护者在合理时间内审阅清楚。

沟通渠道

项目的开发者沟通主阵地是 Discord 服务器(https://serenityos.org/discord)。文档后续多次强调 Discord 在代码评审中的实际作用:

  • 未在社区"打广告"的 PR 可能被好奇的维护者随机合并,但主动在 Discord 上宣传会顺畅得多
  • 由于 GitHub 通知量过大,很多维护者关闭了 GitHub 通知、依赖 Discord 获知评审请求,因此在 Discord 上(例如#code-review频道)询问评审远比在 GitHub 上等待有效;
  • 构建类问题(见下节)应前往 Discord 的#build-problems频道求助。

Issue 政策:目标读者是开发者自己

文档开宗明义:与许多追求最大用户群的项目不同,SerenityOS 的目标受众是其自身的开发者。因此,项目对非贡献者的功能请求兴趣有限——请不要把这里当作普通软件的产品反馈渠道。

提交 Bug 时请遵守以下规则:

  1. 一个 Issue 只描述一个 Bug。把多个问题塞进同一 Issue 会使讨论和关闭都变得不必要的复杂;
  2. 不要提交构建问题或其他支持请求。如果 CI 构建成功而本地失败,问题大概率在你自己环境,应在本地解决,或去 Discord 的#build-problems频道询问;
  3. 不要在 Issue 里刷无意义评论(玩笑或无关吐槽)。成百上千人会被评论通知打扰,请保持相关性;
  4. 裸机(bare metal)问题必须附带完整调试日志:包括串口控制台的完整 debug log、你为解决该问题已尝试过的步骤、机器的硬件型号与相关细节,帮助维护者诊断。

人类语言政策:像对待编程语言一样对待自然语言

项目将人类语言与编程语言同等重视。以下规范适用于所有面向用户的字符串、代码、注释和提交信息

  • 官方语言为美式英语
  • 日期使用ISO 8601格式;
  • 度量单位使用公制单位
  • 拼写、语法和标点必须正确;
  • 语气要求权威且技术化(authoritative and technical)。

文档鼓励大家使用拼写检查器等工具来辅助。在仓库中,这一政策同样被机器强制执行——例如 Meta/lint-commit.sh 会检查提交信息中的大小写与标点,而 Meta/check-style.py 会强制 C++ 头文件的版权头格式。

测试政策:能测则测

修复 Bug 或添加新功能时,请尽可能附带测试。这是硬性要求而非建议。

仓库中测试的体量可以佐证这一政策的执行力度:Tests/AK/ 下有 100+ 个针对基础库的测试文件(如TestVector.cppTestString.cppTestHashMap.cpp),而 Tests/ 目录整体覆盖了从 LibGfx 图像解码到 LibJS、Kernel 等几乎所有子系统。CI 中的 Meta/check-ak-test-files.sh 还会专门检查 AK 的测试文件是否齐备。

代码提交规范:Do 与 Don't

应做事项(Do)

1. 编写地道的 SerenityOS C++26,并在所有代码中使用AK容器。

项目不使用 STL 作为主力容器库,而是使用自研的 AK(Auxiliary Kernel 工具库)——例如VectorStringHashMapOwnPtrRefPtr等。提交代码前请确保对 AK/ 的常用容器有基本了解。

2. 遵循项目编码风格,并使用clang-format(20 或更新版本)。

完整的风格规范见 Documentation/CodingStyle.md,底层格式规则由仓库根目录的 .clang-format 定义。要点速览:

维度规范正例 / 反例
类/结构体/命名空间CamelCase(首字母大写)class FileDescriptor/class filedescriptor
变量/函数snake_casesize_t buffer_size/size_t bufferSize
常量SCREAMING_CASEMAX_ENTRIES
成员前缀非静态成员m_、静态成员s_、全局变量g_int m_length { 0 };
getter/settersetter 用set_前缀,getter 用裸词,out 参数 getter 用get_set_count(int)/int count() const
头文件守卫一律#pragma once
const 位置"east const"(const 写在类型右侧)Salt const& m_salt;
虚函数声明必须带virtual,重写必须带overridefinalvirtual String description() override
强制转换禁止 C 风格 cast,用static_cast等对应 C++ cast
花括号单行体可省略花括号,否则整套 if/else 都要加

若你的发行版没有 clang-format 20,Documentation/AdvancedBuildInstructions.md 给出了三个方案:基于 apt 的发行版使用 LLVM 官方 apt 仓库安装最新 clang-format;或通过 Toolchain/BuildClang.sh 编译 SerenityOS 定制的 LLVM,使用编译产物Toolchain/Local/clang/bin/clang-format(pre-commit 钩子会自动识别该二进制)。

3. 命名要富有表现力:变量、函数和类名要尽可能直观地表达其用途。

4. 将改动拆分为独立的原子提交:每个提交对应一个功能或修复,且提交后构建、测试和系统都能正常运行。

5. 确保提交基于 master 分支 rebase 过。

6. 提交信息每行不超过 72 个字符,并按指定格式书写

  • 第一行为主题行,格式为Category: Brief description of what's being changed
  • Category 应为库、应用、服务或工具的名称,例如LibAudioHackStudioBaseKernelConfigServercat
  • 除非改动横跨目录内大量代码,否则不要使用UserlandUtilities这类宽泛类别;
  • 不要用具体组件名(如 C++ 类名)作类别,应写进摘要里,例如用LibGUI: Brief description of what's being changed in FooWidget而非FooWidget: ...
  • 多个类别可用+组合,如LibJS+LibWeb+Browser: ...
  • 主题行使用祈使语气Foo: Change the way dates work,而非Foo: Changed the way dates work);
  • 提交信息要用规范英语书写,注意措辞与标点;
  • 评审后的修改请用 amend 合并进原提交(而非新提交),并在推送修复后把每条评审意见标记为 resolved。

仓库最近的提交历史就是活教材,例如Ports/ncurses: Remove the --enable-term-driver build option——类别 + 祈使语气 + 无句号结尾,完全符合上述格式。

7. 对文件做实质性修改时,可以(鼓励但非必须)添加个人版权行。

8. 检查代码、注释与提交信息的拼写。

9. 附带的图片资源先用optipng -strip all优化:去掉无用元数据,文件体积可能从数 KB 降到几百字节。

禁止事项(Don't)

  • 提交与项目许可证(2-clause BSD)不兼容的代码
  • 触碰 PR 声明范围之外的任何东西;
  • 在多个提交中反复迭代设计;
  • 用 "refactor"、"fix" 之类模糊词汇回避解释改动内容;
  • 提交信息主题行以句号结尾;
  • 包含注释掉的代码;
  • 用 C 编写代码——应充分利用 C++ 的能力,不要把自己限制在标准 C 库内;
  • 在尚未熟悉系统前尝试大规模架构改动;
  • 无量化收益地搬动代码(文档称之为 "feng shui programming");
  • 在系统面向用户的部分加入玩笑或"有趣"内容。

提交钩子:让规范自动化

仓库根目录的 .pre-commit-config.yaml 定义了三个基于 pre-commit 框架的钩子:

钩子入口触发阶段作用
meta-lint-cibash Meta/lint-ci.sh --no-portspre-commit运行全部 lint 脚本,确保改动能通过 CI 检查
meta-lint-portsMeta/lint-ports.pypre-commit仅在^Ports/文件变更时运行,扫描 Ports 目录
meta-lint-commitMeta/lint-commit.shcommit-msg校验提交信息格式

启用方式:先按 pre-commit 官方文档安装框架,然后执行:

# 安装 pre-commit 钩子:提交前运行 Meta/lint-ci.sh 与 Meta/lint-ports.py,确保代码能通过 lint pre-commit install # 安装 commit-msg 钩子:提交时校验提交信息能否通过 commit lint pre-commit install --hook-type commit-msg

注意钩子配置中的一个工程细节:meta-lint-ci通过args: [ --no-ports ]跳过了 Ports 检查,而meta-lint-ports只对Ports/目录的文件触发(files: ^Ports/pass_filenames: false)。正如 Meta/lint-ci.sh 注释所解释的:lint-ports.py会全量扫描所有 Ports,若在 pre-commit 阶段每次都跑会非常耗时,因此拆成了按需触发的独立钩子。

lint-ci.sh 实际执行哪些检查

从 Meta/lint-ci.sh 源码看,pre-commit 的meta-lint-ci钩子会串行运行 16 个检查脚本,任何一个失败都会计入FAILURES并最终以非零退出码结束:

  • Meta/check-ak-test-files.sh:AK 测试文件完整性
  • Meta/check-debug-flags.sh:debug 标志检查
  • Meta/check-emoji.py、Meta/check-idl-files.py、Meta/check-jbig2-json.sh、Meta/check-markdown.sh、Meta/check-newlines-at-eof.py、Meta/check-png-sizes.sh
  • Meta/check-style.py:版权头、#pragma once、include 合法性(详见下文)
  • Meta/lint-executable-resources.sh、Meta/lint-gml-format.sh、Meta/lint-gn.sh、Meta/lint-keymaps.py、Meta/lint-prettier.sh、Meta/lint-python.sh、Meta/lint-shell-scripts.sh

此外还会尝试用构建产物./Build/lagom/bin/IPCMagicLinter校验*.ipc文件(未构建时跳过),最后通过 Meta/lint-clang-format.sh 对全部.cpp/.h/.mm文件就地运行 clang-format 并比对 git diff。lint-clang-format.sh会按优先级查找clang-format-20brew --prefix llvm@20下的二进制、Toolchain/Local/clang/bin/clang-format,并要求显式传入--overwrite-inplace参数——这是为了让开发者清楚意识到该脚本会直接改写本地文件。

check-style.py 的机器化风格检查

Meta/check-style.py 是风格政策的直接执行者,它用正则强制以下规则:

  • BSD-2-Clause 版权头:每个.cpp/.h文件顶部必须是/* ... SPDX-License-Identifier: BSD-2-Clause */格式(有少量排除名单,如 AK/Checked.h);
  • #pragma once:所有头文件必须包含且格式正确的#pragma once(前后有空白行);
  • 禁止#include <LibC/...>:LibC 是系统库,不应以目录形式被包含;
  • 禁止#include <complex>/#include <ccomplex>:Serenity C++ 代码必须使用 AK 的复数实现;
  • 本地 include 必须可解析#include "..."指向的文件必须真实存在。

这些检查与 Documentation/CodingStyle.md 中的命名、前缀、const 位置、虚函数声明等规范一起,构成了"编码风格可被 CI 强制"的完整闭环。

lint-commit.sh 如何校验提交信息

Meta/lint-commit.sh 是 commit-msg 钩子的实现,它对提交信息做了非常具体的机器校验,逐条对应文档中的要求:

  • 拒绝 Windows 风格 CRLF 换行;
  • 拒绝 merge commit(提示改用 rebase);
  • 主题行必须匹配Category:格式(正则^(\S+: )),否则报"缺少类别";若怀疑是前一个提交的 fixup,应直接 squash 掉;
  • 主题行超过 72 字符即报错(Revert "开头的提交豁免);
  • 主题行中类别后的首词必须以大写字母或数字开头;
  • 主题行以句号结尾即报错;
  • 第二行必须为空行(标题与正文之间的空行不可省略);
  • 正文每行不得超过 72 字符(URL 行豁免);
  • 正文中不允许出现Signed-off-by:标记。

Pull Request 评审 FAQ

文档以 FAQ 形式回答了新贡献者最关心的评审问题:

Q:PR 通过了 CI,多久能收到评审反馈?未宣传的 PR 可能被好奇的维护者随机合并,但更稳妥的方式是在 Discord 上积极互动、主动宣传。

Q:PR 一直没人理,该等多久再联系维护者?如果是紧急内容可以立即 ping;非紧急则在 Discord 的#code-review频道宣传你的 PR 并请求评审。

Q:项目维护者是谁?当前维护者名单(GitHub 用户名):@ADKaster@alimpfard@AtkinsSJ@BertalanD@GMTA@Lubrsi@LucasChollet@nico@spholz@timschumi@trflynn89。维护权是仅限邀请制,且与任何特定指标无关。

Q:对长期无人维护的分支/PR 有策略吗?有。仓库运行一个 "stalebot":PR 连续 21 天无人触碰会被标记为 "stale",再经过 7 天仍无动静则自动关闭。

Q:不同子系统(Kernel、Browser、GUI 等)有专门对接人吗?理论上最合适的人选是"写过与你改动相邻代码最多的人";实践中在 Discord 的开发频道提问通常更简单有效,因为能让更多人参与讨论。

Q:请求评审该用 Discord 还是 GitHub?明确建议用 Discord。由于 GitHub 通知量太大,很多维护者关闭了通知、依赖 Discord 获知评审请求。

被遗弃的 Pull Request 如何处理

偶尔有质量不错但作者失联的 PR。若 PR 本身没有问题、只是作者不回应对接,项目可能会以小幅修改代码与提交信息的方式手动合入。因此文档特别鼓励贡献者开启 PR 上的"Allow edits from maintainers"选项,方便维护者直接修正。

关于意识形态类改动

Serenity 的愿景是在合理范围内让尽可能多的群体协作,欢迎使项目对更多人可及的贡献。但项目定位为纯粹的技术实践,不寻求引发任何社会政治层面的改变:项目明确避免卷入"外部"文化战争,并可能拒绝它认为敏感(如狗哨式隐语、宗教信仰——这显然离题——或现实政治人物)的改动。

文档也承认项目有时会判断失误,但鼓励以善意的对话而非愤怒来处理分歧。

小结:一次合规贡献的完整动线

把以上所有规范串联起来,一次符合 SerenityOS 流程的贡献大致是:

  1. 开 Issue 确认方向(或直接修一个明确的小 Bug);
  2. 用 SerenityOS 风格(C++26 + AK 容器)编写代码,clang-format20 自动格式化;
  3. 尽可能为改动补充测试(参考 Tests/AK/ 的模式);
  4. Category: Imperative summary格式书写提交信息(72 字符、祈使语气、无句号),通过 .pre-commit-config.yaml 配置的 pre-commit 与 commit-msg 钩子自检;
  5. 推送基于 master rebase 的原子提交,在 Discord 的#code-review频道宣传 PR;
  6. 根据评审意见 amend 提交、标记评论为 resolved,保持沟通畅通。

这套由文档 + 钩子脚本 + CI 共同构成的流程,让"编码风格"与"提交规范"从纸面约定变成了可机器校验的硬约束——这正是 SerenityOS 能在庞大的代码库规模下维持高度一致性的关键工程实践。

【免费下载链接】serenityThe Serenity Operating System 🐞项目地址: https://gitcode.com/GitHub_Trending/se/serenity

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 17:52:37

React Native鸿蒙迁移:bundle白屏根因与排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 17:51:19

多隐层神经网络的数理本质:每一层在算什么

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 17:50:20

Python爬虫构建Markdown语法速查字典实战

1. 为什么需要Markdown语法速查字典&#xff1f; 作为一个每天和文档打交道的开发者&#xff0c;我深刻体会到Markdown语法速查的重要性。虽然Markdown本身语法简单&#xff0c;但不同平台&#xff08;如GitHub、Typora、VS Code&#xff09;对Markdown的扩展支持各不相同。比如…

作者头像 李华
网站建设 2026/9/10 17:49:04

C语言实现Kahn算法:拓扑排序原理与实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 17:47:59

Spark直读Hive ORC实现交通实时研判

简介&#xff1a;本资源是一套面向高校大数据方向毕业设计与课程设计的实战项目——基于Spark与Hive构建的交通智能研判系统&#xff0c;聚焦城市交通流量实时分析与历史态势挖掘&#xff0c;助力学生掌握分布式计算与数据仓库协同开发的核心能力。压缩包共58个文件&#xff0c…

作者头像 李华