OneDrive Client for Linux 贡献指南:从编码规范、D 语言风格到 PR 提交流程的完整实战手册

📅 发布时间:2026/9/23 6:04:47
OneDrive Client for Linux 贡献指南:从编码规范、D 语言风格到 PR 提交流程的完整实战手册
OneDrive Client for Linux 贡献指南从编码规范、D 语言风格到 PR 提交流程的完整实战手册【免费下载链接】onedriveOneDrive Client for Linux项目地址: https://gitcode.com/gh_mirrors/onedri/onedrive本篇指南围绕docs/contributing.md展开系统讲解 OneDrive Client for LinuxD 语言编写的代码贡献规范涵盖代码排版tab 缩进、1TBS 花括号风格、命名约定、注释与文档要求、addLogEntry日志输出标准、基于 LDC 编译器的最低版本兼容性测试以及提交 Pull Request 时必须附带的测试证据与可选的 GitHub Actions 冒烟测试配置。读者读完可掌握一套可直接落地的 D 语言项目协作与提交流程并能在src/与.github/workflows/中找到每一处规范的源码佐证。引言这份贡献指南为什么重要OneDrive Client for Linux 是一个用 D 语言编写、规模不小的开源同步客户端其src/目录下分布着 src/onedrive.d、src/sync.d、src/monitor.d、src/log.d 等十余个核心模块。多模块、多贡献者的协作场景下一份清晰、统一的编码规范是保证代码库干净、组织良好、对新老贡献者同样友好的前提——这正是docs/contributing.md存在的原因。该文档为所有贡献者划定了从缩进到日志级别、从编译器版本到 PR 证据格式的全套纪律下面的每一节都将先给出规范本身再结合仓库源码说明为什么以及在哪里能验证。代码布局Code Layout贡献者开发时建议使用Microsoft Visual Studio Code或Notepad作为编辑器。下面按缩进、行长、花括号三个维度展开。缩进统一使用 Tab一 Tab 等于 4 个空格代码库大部分代码使用 Tab 进行缩进且每个 Tab 按4 个空格的宽度对待。贡献者需要严格保持这一约定不要混用空格与 Tab否则 diff 会变得难以阅读。从仓库源码可以印证这一约定包括 src/log.d 的LogBuffer类、src/config.d 的参数解析等模块在内缩进层次全部由 Tab 驱动。行长适度即可不必拘泥于 80 字符文档明确要求不要把行长限制在 80 字符之类的短长度。理由很实际当代码在编辑器中显示时只要屏幕分辨率达到1920x1080 及以上较长的行也能完整展示不需要横向滚动。因此贡献者不必为了凑 80 字符而把函数签名强行折断。反面示例是下面这种把参数拆得零碎、缩进又混乱的写法应避免... void functionName( string somevar, bool someOtherVar, cost(char) anotherVarnull ){ ....正确做法是保持合理长度让参数列表自然可读。花括号使用 1TBSOne True Brace Style代码采用1TBSOne True Brace Style它是KRKernighan Ritchie风格的一种变体。1TBS 的核心纪律是即使if、else、for或函数体内只有一条语句也必须用花括号包裹以此提升可读性并避免后续新增语句时忘记补括号的隐患。标准形态如下// What this if statement is doing if (condition) { // The condition was true ..... } else { // The condition was false ..... } // Loop 10 times to do something for (int i 0; i 10; i) { // Loop body } // This function is to do this void functionExample() { // Function body }左花括号不独占一行而是紧跟在条件/循环/函数声明的同一行末尾右花括号独立成行。这与 D 语言社区常见的风格一致也和 src/log.d 中addLogEntry等函数的实际写法吻合。命名约定Naming Conventions项目对三类标识符的命名有明确区分贡献者应照此执行标识符类别命名风格示例变量与函数camelCaseverboseLogging、logThisMessage、computeItemPath类、接口、结构体PascalCaseLogBuffer、Notification、OneDriveApi常量全大写 下划线分隔SMOKE_PERSONAL_REFRESH_TOKEN在源码中可以看到这些约定的实际落地src/log.d中的全局变量verboseLogging、debugLogging是小驼峰类LogBuffer是大驼峰.github/workflows/smoke-test.yaml中引用的 GitHub secret 名SMOKE_PERSONAL_REFRESH_TOKEN则是常量式全大写。文档与注释标准语言与拼写统一使用英式英语为了让文档、注释、代码在语言风格上保持一致所有书面文本必须使用英式英语拼写而非美式英语。这一要求适用于代码库的一切角落包括变量名、注释和文档。例如用specialise不用specialize用colour不用color用organise不用organize这一点在审视 diff、review PR 时需要格外留意——拼写风格不一致本身就是一个可被要求修改的审查意见。代码注释全层级注释 解释为什么文档要求在所有层级为代码添加注释行注释统一使用//。注释的重点是讲清楚为什么需要这条语句或预期会发生什么让后来的读者能清晰理解代码意图而不仅仅是复述代码在做什么。特别地如果修复的是一个 bug必须在注释中附上对应的 GitHub issue 链接。文档给出的真实示例该 issue 案例与--single-directory同步场景的边界情况有关... // Before discarding change - does this ID still exist on OneDrive - as in IS this // potentially a --single-directory sync and the user moved the file out of the sync-dir to another OneDrive folder // This is a corner edge case - https://github.com/skilion/onedrive/issues/341 // What is the original local path for this ID in the database? Does it match syncFolderChildPath if (itemdb.idInLocalDatabase(driveId, item[id].str)){ // item is in the database string originalLocalPath computeItemPath(driveId, item[id].str); ...仓库中的实际注释同样遵循这一风格——例如 src/log.d 中对转移 buffer 所有权以规避高水位内存滞留的注释就详细解释了这行代码的存在原因。所有代码都应清晰注释。应用日志输出使用 addLogEntry 与既定级别如果贡献者要改动任何应用日志输出必须先通过直接沟通或邮件与维护者讨论避免不同模块各自发明日志风格。作为参考下面列出项目可用的日志输出函数与级别示例节选自docs/contributing.md// most used addLogEntry(Basic info message, [info]); .... or just use addLogEntry(Basic info message); addLogEntry(Basic verbose message, [verbose]); addLogEntry(Basic debug message, [debug]); // GUI notify only addLogEntry(Basic notify ONLY message and displayed in GUI if notifications are enabled, [notify]); // info and notify addLogEntry(Basic info and notify message and displayed in GUI if notifications are enabled, [info, notify]); // log file only addLogEntry(Information sent to the log file only, and only if logging to a file is enabled, [logFileOnly]); // Console only (session based upload|download) addLogEntry(Basic Console only with new line message, [consoleOnly]); // Console only with no new line addLogEntry(Basic Console only with no new line message, [consoleOnlyNoNewLine]);从源码看 addLogEntry 的实现原理addLogEntry并非简单地向终端print而是一个带缓冲、带级别过滤、可选写文件、可选 GUI 通知的完整日志子系统其实现位于 src/log.d。核心要点函数签名void addLogEntry(string message , string[] levels [info])默认级别为info调用logThisMessage入队见 src/log.d。LogBuffer内部维护一个string[3][]缓冲区时间戳、级别、消息由独立flushThread消费生产-消费之间通过Mutex与Condition协调避免多线程日志交错。级别过滤逻辑普通模式下只有info、verbose且需开启--verbose、logFileOnly、consoleOnly、consoleOnlyNoNewLine会进入缓冲区而debug模式--verbose --verbose即-vv则无条件记录所有消息并加DEBUG:前缀。notify级别在编译期启用--enable-notifications对应version(Notifications)编译分支且 D-Bus 可用时才会调用 src/log.d 的notify()发送 GUI 通知运行在 debug 模式时不会发送通知。输出分流规则见 src/log.dlogFileOnly只写文件不写控制台consoleOnly/consoleOnlyNoNewLine只写控制台后者不追加换行常用于--resync提示或下载进度点号其余级别在开启文件日志时同时写控制台与日志文件。此外日志子系统还提供了几个配套入口addProcessingDotEntry()受 1 秒节流保护避免刷爆缓冲区见 src/log.d、enableLogFileOutput()设置日志文件路径并开启写文件见 src/log.d。日志文件的落盘目录由配置项log_dir控制默认值在 src/config.d 中初始化且当enable_logging开启时log_dir不允许为空见 src/config.d配置中若包含~会自动展开为用户主目录。文档同步更新义务如果代码改动影响了任何已文档化的功能提交 PR 时必须同步更新对应的用户文档章节和/或 man page即 docs/usage.md、docs/advanced-usage.md、docs/application-config-options.md 或 onedrive.1.in 等。代码改了但文档没改会被视为不完整的提交。开发测试兼容旧平台的 LDC 最低版本尽管已有更新的 D 语言编译器可用但确保客户端能在较老平台上构建是硬性要求。问题源于 Debian 与 Ubuntu 的 LTS 版本——例如Ubuntu 20.04的ldc软件包仅为v1.20.1因此LDC v1.20.1 是全部编译工作必须测试通过的最低版本。选择 LDC v1.20.1 作为下限的另一个原因是OpenSuSE Build Service 上打包给绝大多数 Debian/Ubuntu 用户安装的 onedrive 软件包正是用该版本编译的。这意味着如果贡献者的代码在新编译器上通过但在 v1.20.1 上失败下游用户就会拿到无法构建的软件包。文档假设贡献者已经知道如何为自己的平台下载并安装正确的 LDC 编译器D 语言官方有多种安装途径此处不再展开。提交 PR必须附带测试证据提交 PR 时必须在 PR 描述中按以下格式提供修复了什么的测试证据无该 PR 时Without PRApplication output that is doing whatever | or illustration of issue | illustration of bug有该 PR 时With PRApplication output that is doing whatever | or illustration of issue being fixed | illustration of bug being fixed同时必须附上使用最低 LDC 版本v1.20.1编译通过的验证结果。为了帮助贡献者完成这项最低版本验证文档提供了如下可直接使用的脚本#!/bin/bash PRYour_PR_Number rm -rf ./onedrive-pr${PR} git clone https://github.com/abraunegg/onedrive.git onedrive-pr${PR} cd onedrive-pr${PR} git fetch origin pull/${PR}/head:pr${PR} git checkout pr${PR} # MIN LDC Version to compile # MIN Version for ARM / Compiling with LDC source ~/dlang/ldc-1.20.1/activate # Compile code with specific LDC version ./configure --enable-debug --enable-notifications; make clean; make; deactivate ./onedrive --version脚本流程说明以 PR 号拉取对应分支并检出source ~/dlang/ldc-1.20.1/activate激活最低版本 LDC 环境dlang安装目录结构来自 D 语言官方安装脚本./configure --enable-debug --enable-notifications开启调试符号与 GUI 通知支持后编译退出激活环境并运行./onedrive --version确认产物可用。可选的 GitHub Actions 冒烟测试Smoke Test项目仓库还提供了一个可选的冒烟测试工作流定义于 .github/workflows/smoke-test.yaml用于验证简单的 monitor 模式行为包括使用一次性 OneDrive Personal 测试账号进行干净退出clean shutdown。该工作流会分别在 Ubuntu 22.04/24.04 与 Fedora 42/43 上构建客户端、启动--monitor --verbose进程等待日志中出现 Sync with Microsoft OneDrive is complete 进入稳态后发送SIGINT并检查是否出现段错误、pthread_mutex_destroy failed等致命退出模式见 .github/workflows/smoke-test.yaml失败时还会自动用 gdb 脚本重跑并采集诊断日志。该工作流需要以下 GitHub 环境配置环境Environment名称smoke-testSecret 名称SMOKE_PERSONAL_REFRESH_TOKEN出于安全原因GitHub 不会向来自 fork 的 PR 提供仓库 Secret。因此外部贡献者若想在自己 fork 中运行该冒烟测试必须在自己的 fork 中配置这个 Secret。刷新令牌refresh token属于凭据必须只从一次性disposable测试账号生成绝不能使用真实个人账号。在自己 fork 中配置的步骤创建一个一次性 OneDrive Personal 测试账号手动完成客户端认证复制生成的refresh_token文件内容在 GitHub 中创建一个名为smoke-test的 Environment添加名为SMOKE_PERSONAL_REFRESH_TOKEN的 Environment secret在自己的 fork 中重新运行 smoke-test 工作流。如果该 Secret 不可用fork 提交的 PR 会跳过 smoke-test 工作流——这一点在工作流中也有显式处理见 .github/workflows/smoke-test.yamlfork PR 缺少 Secret 时输出 Skipping monitor smoke test 并安全退出而非报错。参考资源贡献者在提交前可进一步对照以下资料深化对 D 语言风格与英式拼写的理解D 语言官方风格指南D Language Official Style Guide英式英语拼写规范Collins Dictionary项目内可交叉验证的仓库文件包括docs/usage.md日志级别与客户端活动的用户文档、src/log.d日志子系统实现、src/config.dlog_dir、monitor_log_frequency等配置项解析、.github/workflows/smoke-test.yaml冒烟测试工作流以及 tests/ 与 ci/e2e 下的大量端到端测试用例可作为理解项目行为与验证改动的参照。小结对 OneDrive Client for Linux 的贡献者而言docs/contributing.md是一份一次审阅处处生效的契约——遵循 Tab 缩进与 1TBS 花括号、遵守三种命名风格、坚持英式拼写与//注释、通过addLogEntry的既定级别输出日志、用 LDC v1.20.1 验证最低版本兼容、并在 PR 中附上有/无对照的测试证据即构成了一个规范、可审查、可复现的完整贡献闭环。【免费下载链接】onedriveOneDrive Client for Linux项目地址: https://gitcode.com/gh_mirrors/onedri/onedrive创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考