☰
DDNS 仓库维护工具(tools/)开发指南:Python 3 维护代码的工程规范、测试约定与确定性校验
2026/10/14 6:09:09 网站建设 项目流程
  • 网络
  • CLI

【免费下载链接】DDNS

🌐自动更新域名解析到本机IP,支持dnspod,阿里DNS,CloudFlare,华为云,DNSCOM...

项目地址:https://gitcode.com/gh_mirrors/dd/DDNS
点击查看免费下载

本指南以 DDNS 仓库内 tools/AGENTS.md 为核心,系统讲解维护工具目录的职责边界、Python 3 编码规范、测试编写约定与完整验证命令链,并结合 tools/check.py、tools/tests/test_check.py 及.github/workflows/下的 CI 工作流给出源码级佐证。读完本篇,你将掌握:如何在 Python 3 环境下为 DDNS 编写仓库维护脚本、如何为这类工具编写离线且确定性的单元测试,以及如何把 lint、格式与契约校验接入发布与日常 CI 流程。

一、tools/ 的定位:维护代码而非运行时

1.1 与运行时代码的边界

DDNS 主项目(ddns/包)是一个要求同时兼容 Python 2.7 与 Python 3 的动态 DNS 客户端,其运行时代码受到 .github/instructions/python.instructions.md 的约束——不允许使用 f-string、注解、async/await 等 Python 3 专属语法,运行时依赖仅限标准库。

而tools/目录则完全不同:它存放仓库维护代码,不随 DDNS 运行时一起发布,也不需要保持 Python 2.7 兼容。这就意味着维护脚本可以放心使用现代 Python 语法与特性。仓库根目录 AGENTS.md 在 Directory Structure 一节中把tools/明确标注为 “Python 3.12+ repository maintenance tools”,与运行时代码形成了清晰的分层:

  • ddns/、run.py、tests/:Python 2.7 / 3.x 双兼容,标准库优先;
  • tools/与.github/scripts/下的 Python 脚本:Python 3.12+,可以使用现代语法。

1.2 工具目录的实际构成

从当前仓库看,tools/目前包含三个文件:

  • tools/AGENTS.md:本篇指南对应的维护工具开发规范;
  • tools/check.py:确定性项目契约检查工具,负责按“开发车道(lane)”挑选并执行对应的测试与 lint 命令,同时校验 provider 元数据、可移植 Agent 契约等仓库一致性;
  • tools/tests/test_check.py:针对check.py的聚焦单元测试。

此外,.github/scripts/update_agents_structure.py 会在运行时把tools/目录加入sys.path并导入check模块(见其main()函数),这也印证了tools/作为仓库级工具库被其他维护脚本复用的定位。

二、Python 编码规范:Python 3.12+、标准库优先

原文档对工具代码的 Python 要求可以概括为四条核心原则:

  1. 目标 Python 3.12 或更新版本。当前仓库的 CI 在 .github/workflows/update-agents.yml 中使用python-version: '3.12'运行工具契约测试,与文档要求完全一致。
  2. 优先使用标准库。只有在该依赖能显著降低复杂度、且已由项目统一管理时,才引入额外的工具依赖。tools/check.py全程仅使用argparse、ast、json、re、shutil、subprocess、dataclasses、pathlib等标准库模块,正是这一原则的直接体现。
  3. 使用类型注解、pathlib、subprocess.run与现代 Python 语法。check.py大量使用from __future__ import annotations、dataclass(frozen=True)、tuple[str, ...]等类型注解语法,与 Python 2 兼容代码(只能使用# type:类型注释)形成鲜明对比。
  4. 路径从仓库根解析,跨 Windows / Linux / macOS 可用。check.py通过REPO_ROOT = Path(__file__).resolve().parents[1]计算仓库根,并用normalize_path()把\统一为/处理跨平台路径;.github/scripts/update_agents_structure.py也通过os.path.dirname三层向上推导REPO_ROOT。测试用例test_dot_directories_are_preserved_for_agent_lane验证了./.github/...这类带点前缀的路径会被正确规范化。

2.1 一个不可逾越的红线:绝不改动用户数据

原文档明确要求维护工具永不修改用户配置、凭据、DNS 记录、发布产物或仓库设置。这条红线背后的原因是:维护工具运行在仓库维护者与 CI 环境中,但绝不能越界触碰终端用户的运行数据。因此check.py的全部职责被设计为“检查与报告”(输出错误清单、返回非零退出码),而不是“修复或写入”;.github/scripts/update_agents_structure.py 在--check模式下也只负责检测AGENTS.md目录结构与实际文件的漂移并返回失败码,不执行任何仓库写操作。

三、工具测试约定:离线、确定、失败显式

原文档对tools/测试的要求非常明确,结合test_check.py可以逐条印证:

3.1 测试位置与命名

  • 测试必须放在tools/tests/下,并使用test_*.py命名,以便unittest discover自动发现。当前仓库的 tools/tests/test_check.py 正是唯一的测试文件。

3.2 使用临时目录与注入的命令执行器

  • 涉及文件系统或 subprocess 行为的测试,应当使用临时目录和注入的命令执行器,避免污染真实仓库、保证可重复运行。test_check.py中的ChangedPathsTests在tempfile.TemporaryDirectory()内初始化一个迷你 git 仓库(git init、git commit、git mv),以此验证changed_paths()能同时收集 merge-base 差异、已暂存、未暂存与未跟踪文件;ContractTests则通过_write()在临时目录中构造一整套最小化但结构完整的“DDNS 仓库”,再对provider_parity_errors()等契约函数做断言。

3.3 保持离线与确定性

  • 测试不允许依赖网络或真实凭据。test_check.py中没有任何网络请求;对subprocess.run、shutil.which等副作用的调用均通过unittest.mock.patch注入,例如test_run_command_uses_resolved_executable用patch("check.shutil.which", return_value="C:/tools/npm.cmd")验证命令执行器会解析可执行文件路径。

3.4 缺失时显式失败

  • 当所需的工具或期望的仓库表面缺失时,测试必须显式失败,而不是静默跳过。check.py定义了CheckError异常,_load_json()在必需文件缺失时抛出CheckError,_run_command()在shutil.which()找不到可执行文件时同样抛出CheckError;test_missing_temporary_surface_raises_check_error与test_changed_paths_fails_without_base分别验证了这两种显式失败路径。

3.5 测试导入模式

test_check.py通过sys.path.insert(0, str(Path(__file__).resolve().parents[1]))把tools/加入路径后import check,并利用importlib加载.github/scripts/update_agents_structure.py做结构漂移测试——这体现了工具测试与运行时测试(tests/init.py 路径初始化)完全不同的导入约定。

四、Validation:完整的验证命令链

原文档给出了工具代码的标准验证命令,这也是提交前必须通过的关卡:

python3 -m unittest discover tools/tests -p "test_*.py" -v ruff check tools ruff format --check tools

4.1 三条命令各自的职责

命令职责在仓库中的落地
python3 -m unittest discover tools/tests -p "test_*.py" -v以 unittest 发现并运行tools/tests/下全部工具测试,-v输出详细结果.github/workflows/update-agents.yml 的 “Run tooling contract tests” 步骤、tools/check.py中Agent/Workflow车道的 “Tooling contract tests” 命令
ruff check tools对tools/做 lint 检查(E/W/F/C 规则集,见 pyproject.toml 的[tool.ruff.lint])check.py中Agent/Workflow车道的 “Ruff tooling lint” 命令
ruff format --check tools校验tools/代码格式是否符合 ruff 格式化规则check.py的_python_format_arguments()会把tools/下被 git 跟踪或未忽略的.py文件全部纳入格式检查

值得注意的是,pyproject.toml 的 ruff 配置把目标版本设为py37并刻意排除UP(pyupgrade)规则以保护 Python 2 兼容代码,但这只影响运行时代码;tools/因不参与运行时发布,天然不受该约束限制,这正是原文档单独为其制定 Python 3.12+ 规范的原因。

4.2 验证命令在 CI 中的编排

  • 每日 / PR 自动检查:.github/workflows/update-agents.yml 在 PR 事件触发时依次运行工具契约测试、update_agents_structure.py --check(结构契约)与python3 tools/check.py --providers(provider 契约);非 PR 事件(每日 cron0 0 * * *与手动触发)则负责把结构漂移与契约错误汇总写入 issue body 并自动创建 issue,标题为 “docs(agents): AGENTS.md directory structure needs update”。
  • 全量确定性检查:python3 tools/check.py --all会在仓库根执行一整套不重复的命令集合(_all_commands()),包括 ruff lint、全量单元测试、离线 E2E、工具契约测试以及文档依赖安装与构建;python3 tools/check.py --changed则先根据变更文件路径做车道归类,再只运行相关车道的命令,尽量减少 CI 开销。

五、check.py 深度剖析:车道选择与契约校验

tools/check.py是本目录中唯一的核心实现,其设计对理解整个仓库的维护模型至关重要。

5.1 车道(Lane)分类模型

check.py定义了 9 个规范车道(CANONICAL_LANES):Core、Config、Provider、Web、Scheduler、MCP、Docs、Build/Release、Agent/Workflow。lanes_for_path()负责把任一变更路径映射到可能受影响的多个车道,例如:

  • docs/providers/cloudflare.md→("Provider", "Docs");
  • schema/v4.1.json→("Config", "Provider", "Docs");
  • .github/workflows/build.yml→("Build/Release", "Agent/Workflow");
  • tools/check.py或任何/AGENTS.md→("Agent/Workflow",)等。

这一模型与根目录 AGENTS.md 的 “Agent Quick Start” 车道划分一一对应。对于无法归类的未知路径,select_lanes()采取保守策略——直接选中全部车道(test_unknown_path_selects_full_conservative_set验证了这一行为),保证任何新文件都不会绕过检查。

5.2 两类核心契约检查

  • Provider parity(provider_parity_errors):以 ddns/config/field-model.json 中的 provider 元数据(id与docs)为基准,逐一与以下表面比对:
    • 运行时注册表 ddns/provider/init.py 中get_provider_class的映射(通过 AST 静态解析,不导入 Python 2 兼容代码);
    • CLI 的--dns选项 choices(ddns/config/cli.py);
    • schema/v4.1.json 中dns与providers[].provider两个 enum;
    • 双语文档文件 docs/providers/ 与 docs/en/providers/、VitePress 导航 docs/.vitepress/config.mts、双语文档索引表以及 docs/llms.txt 中的 provider 数量与链接清单。
    • 任何一处漂移(如docs/llms.txt中 provider 数量与 field-model 不一致、导航缺失、文档被注释隐藏)都会产生明确的错误信息。
  • Portable agent contracts(portable_contract_errors):校验根目录与各层级的AGENTS.md必需文件(AGENTS.md、tools/AGENTS.md、ddns/provider/AGENTS.md、docs/AGENTS.md)是否存在;校验.agents/skills/*/SKILL.md的 front matter(name、description、命名规范、不得预授权工具);校验.github/agents/*.agent.md薄配置文件必须引用可移植 Skill。

5.3 Merge gate 策略

check.py还内置了合并门禁逻辑(merge_gate_failures):MERGE_GATE_REQUIRED中的lint、python、e2e、pypi、nuitka、linux-binary、prepare-docker、docker等任务必须全部 success;preview-pypi、preview-docker则允许在 PR 场景下跳过(skipped),但 push 场景必须 success。这些任务名与 .github/workflows/build.yml 中的实际 job 一一对应,test_merge_gate_rejects_required_skip_and_cancellation等测试保证了该策略的确定性。

六、测试驱动的最佳实践与调试建议

6.1 迭代节奏

原文档强调“先在最小范围内跑测试,再逐步扩大”。对于tools/的开发,推荐节奏是:

# 单文件快速迭代 python3 -m unittest tools.tests.test_check -v # 工具目录全量 python3 -m unittest discover tools/tests -p "test_*.py" -v # 结合 lint 与格式 ruff check tools ruff format --check tools

对受影响的语法做快速验证时,也可使用:

python3 -m py_compile tools/check.py python3 tools/check.py --all # 全量确定性检查 python3 tools/check.py --changed # 仅按变更车道检查

6.2 常见问题排查

  • 测试导入失败:确认test_check.py是否像现有实现一样把tools/插入sys.path后再import check;确认.github/scripts下的脚本可用importlib加载。
  • 契约检查误报:provider_parity_errors会把被 HTML 注释(<!-- -->)包裹的索引行视为缺失(见_strip_html_comments),因此不要用注释方式“暂时隐藏” provider 条目。
  • 格式检查范围:ruff format --check只作用于被 git 跟踪或未被忽略的tools/、tests/、ddns/与.github/scripts/下的.py文件,docs/下的示例.py不在范围内(test_format_check_only_targets_python_files验证)。

七、维护工具的发布与隔离原则

tools/不随运行时发布,但在发布流水线中依然扮演重要角色:

  • .github/workflows/publish.yml 在构建 PyPI 包与原生二进制前,会通过 .github/patch.py 写入发布版本号、替换 README 相对文档链接、对 Docker 构建移除 scheduler 相关代码并剥离 Python 2 兼容分支;这些操作全部发生在发布构建环境内,属于仓库发布维护的一部分,与“绝不修改用户配置/凭据/发布产物”的约束并不冲突——后者针对的是对用户侧数据的越界操作。
  • 根目录 AGENTS.md 的 “Agent Development Model” 进一步规定:Agent 工具链与发布相关改动应遵循tools/AGENTS.md与.agents/skills/下的可移植 Skill;copilot-instructions.md也明确“不要为了让tools/兼容 Python 2 而改写它,除非任务明确要求”。

八、小结

tools/AGENTS.md用极简的篇幅定义了 DDNS 仓库维护工具的三条主线:Python 3.12+ 现代语法与标准库优先的编码规范、离线确定且显式失败的测试约定、以及一条可一键执行的验证命令链。而 tools/check.py 与 tools/tests/test_check.py 则把这份规范落成了可运行、可测试、可接入 CI 的具体实现——车道分类、provider 一致性契约、可移植 Agent 契约与 merge gate 策略共同构成了 DDNS 仓库“代码、测试、schema、双语文档、元数据必须同步演进”的工程约束。如果你正准备为 DDNS 贡献新的维护脚本或 CI 检查项,请先阅读 tools/AGENTS.md 与 tools/check.py,再在 tools/tests/ 中补充test_*.py测试,最后用上文三条验证命令完成本地验证。

  • 网络
  • CLI

【免费下载链接】DDNS

🌐自动更新域名解析到本机IP,支持dnspod,阿里DNS,CloudFlare,华为云,DNSCOM...

项目地址:https://gitcode.com/gh_mirrors/dd/DDNS
点击查看免费下载
上一篇:CANN/asc-devkit GlobalTensor GetSize函数
下一篇:XuanYuan-6B部署优化:提升推理速度的10个技巧

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询