ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Gotenberg 仓库贡献指南:从模块架构、代码规范到集成测试的完整开发守则

Gotenberg 仓库贡献指南:从模块架构、代码规范到集成测试的完整开发守则 后端开发工具【免费下载链接】gotenbergA developer-friendly API for converting many document formats into PDF files, and more!项目地址https://gitcode.com/gh_mirrors/go/gotenberg点击查看免费下载本文以 Gotenberg 仓库的 AGENTS.md 为核心骨架系统讲解这个文档转 PDF API 项目的两条最高准则向后兼容与防御性编程、模块化架构、Makefile 工作流、代码与文档规范、测试体系以及 Pull Request 提交流程。读完本文你将能按照项目官方标准为 Gotenberg 新增模块、编写路由与 Gherkin 场景、安全地修改 CLI 标志与 API 表单字段并通过单元测试与集成测试完成一次合格的贡献。两条压倒一切的准则Gotenberg 是一个基于 Docker 的文档转 PDF API任何开发工作开始之前必须首先接受两条铁律向后兼容Backward compatibility任何 CLI 标志、环境变量、API 表单字段form field、HTTP 端点以及会改变既有行为的默认值未经讨论一律不得重命名或移除。防御性编程Defensive programming默认输入是畸形malformed的必须显式处理每一个错误任何情况下不允许 panic。这两条准则贯穿于 AGENTS.md 的全部章节从标志弃用策略、错误处理方式到 PR 检查清单都可以看到它们的影子。工具链与开发环境贡献 Gotenberg 需要以下工具链版本要求以仓库实际内容为准组件说明Go 模块github.com/gotenberg/gotenberg/v8见 go.mod当前 Go 版本为 1.27.1Go具体版本见 go.mod 中的go指令Docker构建镜像与运行集成测试必需Node.js版本见.node-version文件用于 Prettier 非 Go 文件格式化golangci-lint要求 v2 及以上版本负责 Go 代码的格式化与静态检查开工之前先讨论再动手AGENTS.md 明确要求非平凡改动必须先开 issue 或 draft PR在其中说明需要改什么提议的解决方案要修改的文件、接口变更、表单字段变化受影响的集成测试标签tag。同时遵循一个 PR 只做一件事原则功能feature、缺陷修复bug fix、重构refactoring必须拆分到不同的 PR 中。新增功能或路由时要先写 Gherkin 场景feature 文件再写 Go 代码如果路由发生变化还需要同步更新 Bruno 集合.bruno/ 目录。项目布局理解模块化仓库结构AGENTS.md 给出了仓库的顶层布局各目录职责如下cmd/gotenberg/ - 入口点装配/启动。不含业务逻辑。 pkg/gotenberg/ - 核心模块系统、接口、工具、mock。 pkg/modules/ - 功能模块api、chromium、libreoffice、pdfengines 等。 pkg/standard/ - 通过 import 将所有标准模块装配在一起。 test/integration/ - Gherkin feature 文件 Go 测试基础设施。 build/ - Dockerfile、字体、Chromium 配置。 .bruno/ - Bruno API 集合镜像每一个路由。关键接口位于 pkg/gotenberg/包括Module、Provisioner、Validator、Debuggable。每个模块都实现Descriptor()并通过init()自注册。入口点只做装配cmd/gotenberg/main.go 全文件只有两件事调用gotenbergcmd.Run()并匿名导入pkg/standard包。这正是入口点无业务逻辑的体现。而装配动作发生在 pkg/standard/imports.go它通过一系列_ ...匿名导入依次加载 api、chromium、exiftool、libreoffice、libreoffice/api、libreoffice/pdfengine、pdfcpu、pdfengines、pdftk、prometheus、qpdf、webhook 等全部标准模块。Makefile一切构建与验证任务的中枢AGENTS.md 规定所有构建和验证任务都必须通过 Makefile 执行除非是在调试某个特定包否则不要直接运行go命令。完整命令表如下命令用途使用时机make build构建 Gotenberg Docker 镜像集成测试或手工测试之前make run通过docker compose运行 Gotenberg 容器手工测试标志通过 Makefile 变量和 compose.yaml 配置make telemetry启动 OpenTelemetry collector 和 OpenObserve本地测试遥测时make down停止所有 compose 容器手工测试之后make godoc在localhost:6060提供 GoDoc 服务验证文档时make fmt格式化 Go 代码提交之前make lint检查 Go 代码零错误容忍提交之前make prettify格式化非 Go 文件Markdown、YAML、JSON提交之前make lint-prettier检查非 Go 文件提交之前make test-unit运行单元测试提交之前make test-integration运行全部集成测试40 分钟超时提交之前按标签选择性运行集成测试全套集成测试有 40 分钟超时因此只运行与你改动相关的标签即可不要跑全量make test-integration TAGShealth make test-integration TAGSchromium-convert-html make test-integration TAGSmerge,split从 Makefile 的源码可以看到test-integration目标通过go test -timeout 40m -tagsintegration驱动并支持NO_CONCURRENCYtrue禁用并行场景与PLATFORMlinux/arm64指定平台等变量。可用标签的完整清单chromium、libreoffice、pdfengines、merge、split、stamp、webhook、prometheus-metrics 等数十个都注释在 Makefile 的TAGS变量上方。另外Makefile 顶部还集中定义了大量环境变量默认值如API_PORT3000、CHROMIUM_MAX_CONCURRENCY6、PDFENGINES_MERGE_ENGINESqpdf,pdfcpu,pdftk、OTEL_TRACES_EXPORTERnone、WEBHOOK_MAX_RETRY4等手工测试时可直接覆盖这些变量来调整容器行为。代码约定模块系统受 CaddyServer 启发的自注册架构Gotenberg 采用类似 CaddyServer 的自注册模块架构。每个模块位于pkg/modules/name/下至少要实现gotenberg.Module接口即Descriptor()方法并通过init()自注册模块间的装配wiring发生在pkg/standard/。以 pkg/gotenberg/modules.go 的源码为准核心接口定义如下Module所有模块的根基Descriptor() ModuleDescriptorModuleDescriptor描述模块本身包含必填的IDsnake_case 唯一名称、可选的FlagSet模块的标志定义以及必填的New func() Module工厂函数Provisioner需要依据标志、环境变量、上下文等进行初始化的模块实现Provision(*Context) errorValidator需要在校验阶段执行检查的模块实现Validate() errorApp可启动/停止的模块实现Start()、StartupMessage()、Stop(ctx)SystemLogger想在启动时输出额外消息的模块Debuggable想提供额外调试数据的模块实现Debug() map[string]any。注册通过gotenberg.MustRegisterModule()完成其内部会校验 ID 非空、New非 nil并对重复注册直接 panic这是注册机制层面的保护与生产代码路径不许 panic不冲突。pkg/modules/api/api.go 中func init() { gotenberg.MustRegisterModule(new(Api)) }就是标准写法。决定功能归属时先判断能否放进已有模块只有确实属于独立关注点时才新建模块。cmd/gotenberg/包严格只做装配与启动禁止业务逻辑。向后兼容弃用而非删除CLI 标志、环境变量、API 表单字段、HTTP 端点以及任何改变既有行为的默认值未经讨论不得变更。正确的做法是用fs.MarkDeprecated()标记旧名称新旧名称同时注册。如果改动确实违反向后兼容必须在 PR 描述中标注为 breaking change。pkg/modules/api/api.go 提供了真实范例api-trace-header被标记为 deprecated提示改用api-correlation-id-headerapi-disable-health-check-logging被标记为 deprecated提示改用api-disable-health-check-route-telemetry。而在Provision()中则用flags.MustDeprecatedString(api-trace-header, api-correlation-id-header)实现新旧标志的兼容读取。错误处理每个错误都要用fmt.Errorf(description: %w, err)包裹上下文绝不静默吞掉错误用errors.Is匹配错误禁止用strings.Contains生产代码路径禁止 panic防御性地校验输入。以 api 模块为例pkg/modules/api/api.go 的Validate()会逐个校验端口范围、绑定 IP 合法性、TLS 证书与密钥是否成对出现、root path 是否以/开头和结尾、Basic Auth 与 OIDC 互斥等全部通过errors.Join聚合返回。错误消息对客户端与运维人员可操作面向客户端和运维人员的错误消息必须说明什么失败了、为什么不明显时、以及如何修复存在修复方案时只有进入日志的内部包装错误链fmt.Errorf链可以保持纯粹的技术性。客户端HTTP 响应体指明出错的表单字段及其合法取值绝不返回裸的http.StatusText()运维启动、Provision、Validate指明需要设置的环境变量或标志以及被检查的路径或值安全与过滤类错误对客户端保持笼统不泄露 allow/deny 列表或私有 IP 策略但要在日志中给运维记录具体原因不使用while others may have failed这类含糊表述不在面向人的补救建议中暴露原始os.Stat或 exec 输出。日志基于 slog 且必须携带上下文使用gotenberg.Logger(mod)在Provision()期间获取模块的 slog logger。所有日志调用都必须上下文感知logger.DebugContext(ctx, msg)、logger.InfoContext(ctx, msg)、logger.ErrorContext(ctx, msg)。当 OpenTelemetry 生效时这会自动把 trace/span ID 传播进结构化日志中。遥测外部工具调用必须建 Span对外部工具的调用Chromium、LibreOffice、PDF 引擎、webhook、下载必须创建trace.SpanKindClient类型的 OTEL span并设置semconv.ServerAddress(toolname)。追踪与指标分别使用gotenberg.Tracer()和gotenberg.Meter()。这与仓库的 otel-collector-config.yaml 以及make telemetry提供的本地排障链路相呼应。导入顺序由gci强制标准库 → 第三方库 →github.com/gotenberg/gotenberg/v8三组之间以空行分隔。这一点在 pkg/modules/api/api.go 的 import 块中可以直接观察到。文档约定语气短小、陈述性的句子说明它做什么即可以动作开头Validates font embedding而不是 This function validates font embedding使用主动语态Gotenberg checks the profile而不是 The profile is checked by Gotenberg不使用破折号em dash用句号、冒号或逗号替代不用 we 这种含混说法Dont... 而不是 We do not recommend...。Godoc每个导出的类型和函数都必须有以其标识符名称开头的 Godoc 注释例如// OutboundDecision is the result of validating an outbound URL via // [DecideOutbound]. ... type OutboundDecision struct { ... }每个包都应有doc.go内含// Package foo ...注释用[Name]方括号引用标识符便于 pkg.go.dev 自动链接。仓库中pkg/gotenberg/internal/log/doc.go、pkg/gotenberg/internal/otel/doc.go等即是此约定的落地。代码注释解释为什么而不是是什么禁止编号步骤注释// 1. Do X与带数字的分节线// --- 8. Foo ---纯分隔线可接受禁止复述代码的无意义注释如// Check if err is nil相关时引用规范条款如// Per ISO 32000-2, Table 116...技术债用// TODO: [context]标记。测试体系单元测试表驱动测试table-driven tests写在*_test.go中。优先使用 pkg/gotenberg/mocks.go 提供的综合 mock 实现而不是自行编写新的 mock。集成测试Gherkin Godog testcontainers集成测试使用 GherkinBDD语法通过 Godog 驱动用testcontainers-go编排 Docker 容器feature 文件位于test/integration/features/一个端点或一项能力一个文件step 定义位于test/integration/scenario/容器管理、HTTP 辅助、PDF 校验入口是test/integration/main_test.gobuild tagintegration测试数据位于test/integration/testdata/。详细约定见 test/integration/README.md每个场景都会通过 testcontainers 起一个全新的 Gotenberg 容器另外用一个gotenberg/integration-tools容器提供 PDF 校验工具verapdf、pdfinfo、pdftotext。运行集成测试前必须先make build产出镜像。编写新测试的步骤来自 test/integration/README.md新建或更新.feature文件 → 打上合适的标签如chromium chromium-convert-html→ 新标签要同时加入 Makefile 的TAGS注释块和 README 的标签表 → 新 step 定义加进scenario/scenario.go并在InitializeScenario中注册 → 测试数据放入testdata/。写新测试前务必先读scenario.go和containers.go。Pull Request 规范提交信息Conventional Commits提交信息遵循 Conventional Commits 格式type(scope): description。常用 typefeat、fix、refactor、test、docs、chore、ci、build。scope 与改动所属模块或区域一致如chromium、pdfengines、api。只暂存具体文件绝不使用git add -A或git add .。提交前检查清单打开 PR 之前逐一确认无向后兼容性回归见向后兼容一节满足代码约定错误包装、日志、遥测、导入顺序、无 panic、cmd/中无业务逻辑满足文档约定每个导出标识符都有 Godoc、新包有doc.go、语气正确make fmt make lint make prettify make lint-prettier零警告通过make test-unit通过相关的make test-integration TAGS...通过路由有增改时Bruno 集合已同步更新。延伸阅读test/integration/README.mdGherkin step 参考、可用标签、如何编写新测试.bruno/README.md.bru文件格式、约定、路由更新检查清单pkg/modules/pdfengines/README.md如何新增 PDF 引擎功能Makefile 变量与标志。赞分享后端开发工具【免费下载链接】gotenbergA developer-friendly API for converting many document formats into PDF files, and more!项目地址https://gitcode.com/gh_mirrors/go/gotenberg点击查看免费下载相关推荐大麦网抢票脚本教程自动化抢票从安装到运行的完整指南大麦网抢票脚本教程自动化抢票从安装到运行的完整指南 Automatic_ticket_purchase 是一个大麦网抢票脚本基于 Python 的自动化购票网页爬虫工作流自动化为 Fresh 框架贡献代码仓库结构、本地开发环境与测试规范完整指南为 Fresh 框架贡献代码仓库结构、本地开发环境与测试规范完整指南 Fresh 是一个基于 Deno 的现代 Web 框架以简单到你已经会用了为设计哲后端前端Coil 仓库开发与贡献指南模块组织、构建测试与代码规范全解析Coil 仓库开发与贡献指南模块组织、构建测试与代码规范全解析 本文以 CoilImage loading for Android and Compose移动开发图像处理缓存抽象创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表