Sapling 测试体系全指南:从 .t 测试到 Rust/Python 测试的编写规范
开发工具CLI后端【免费下载链接】saplingA Scalable, User-Friendly Source Control System.项目地址https://gitcode.com/gh_mirrors/sa/sapling点击查看免费下载本篇技术指南围绕 Sapling开源的可扩展、易用的源码控制系统的测试编写实践展开系统讲解.t测试这一 Sapling 特有的端到端命令行测试格式包括其基本语法命令执行、多行 heredoc、Python 代码块、退出码断言、推荐的最佳实践newclientrepo建仓、drawdag 造提交、按子用例隔离仓库、高级特性测试环境变量、条件逻辑、动态输出匹配、双测试引擎并覆盖 Rust 与 Python 两种语言的单元测试、doctest 与集成测试规范。读者读完后可以独立编写、运行与维护 Sapling 仓库中的各类测试并理解其底层执行原理。引言Sapling 为什么需要多套测试体系在 Sapling 仓库中针对不同语言和不同测试目的存在截然不同的测试写法。官方文档 writing_tests.md 开篇即给出了清晰的分层原则Rust 代码单元测试unit tests与 doctests 是通常的首选Python 代码由于sapling/的 Python API 并不稳定且模块之间耦合过重例如 Python 的 bookmark 存储对象bmstore无法脱离 repo 对象单独创建因此 Python 单元测试只适合逻辑相对独立的场景端到端命令行体验Sapling 独有的.t测试是最佳载体专门用于验证最终用户在命令行下的真实使用体验。这一分层思路直接决定了仓库中 tests/ 目录的形态这里既有数千个test-*.t文件也有test-*.py单元测试和大量辅助脚本tinit.sh、hghave.py、default_hgrc.py、run-tests.py等。.t测试入门.t测试存放在仓库的tests/目录下即 eden/scm/tests/通过测试运行器run-tests.py执行python tests/run-tests.py test-xxx.t在仓库中运行器实现在 tests/run-tests.py其命令行用法为%(prog)s [options] [tests]参见源码第 406 行的getparser()支持的参数包括测试选择--blacklist、--changed、-k/--keywords、--retest、执行器行为-i/--interactive、-u/--update-output、-j/--jobs、-d/--debug、Hg 配置--watchman、--with-hg、--extra-config-opt以及结果报告--json、-c/--cover、-H/--htmlcov等。基本语法缩进的 Bash 命令块每个.t测试文件看起来像一段带注释的缩进 Bash 脚本。命令前带有两个空格和$提示符紧跟着的缩进行则是该命令的期望输出Test echo works. This line is a comment. $ echo A A测试引擎会实际执行echo A并将真实输出与期望输出A逐字比对不一致即判定失败。多行命令heredoc使用 heredoc 可以将多行输入喂给命令输出同样逐行断言$ sha1sum EOF hello EOF f572d396fae9206628714fb2ce00f72e94f2258f注意续行行首使用提示符最终期望输出为命令的标准输出。Python 代码块.t文件内可以内嵌 Python 脚本表示 Python 提示符...表示续行 import sys for i in hello world.split(): ... sys.stdout.write(%s\n % i) hello world期望输出与命令输出同样逐行匹配这为需要复杂逻辑断言的场景提供了便利。退出码断言命令的退出码可以用[N]语法断言。例如下面的测试期望false以退出码 1 结束$ false [1]从零创建一个.t测试官方文档给出了最朴素的起步方法在 shell 中设置PS1$ 手动实验并复现你要测试的命令序列把可复现的命令复制到一个test-foo.t文件每行前加两个空格作为缩进也可以直接在test-foo.t中编辑$命令行然后运行run-tests.py -i test-foo.t即--interactive模式让运行器自动填充期望输出。交互模式是日常修改测试的重要工具运行器会提示接受实际输出自动把正确的输出回填到.t文件中。最佳实践写出高质量.t测试推荐测试骨架官方文档推荐的新测试写法如下$ newclientrepo EOS B | A EOS This is a comment $ touch something $ hg st # this is another comment ? something $ hg go $A -q创建新仓库的首选方式是newclientrepo。它是tests/tinit.sh中定义的辅助函数见 tinit.sh其底层会执行sl clone ... test:server $TESTTMP/reponame并sl up -q tip第 65–105 行相当于把「创建服务端仓库 克隆客户端仓库 切到最新提交」一步完成。默认情况下新测试会在以下三种组合上运行不带 Watchman 的 Sapling带 Watchman 的 Sapling带 EdenFS 的 Sapling。如果只想在特定组合下运行可以在文件顶部添加#require指令#require eden、#require no-eden、#require fsmonitor、#require no-fsmonitor。为每个子用例创建独立仓库创建新仓库在测试环境下是代价极低的操作却能避免多个子用例复用一个仓库时相互污染、导致后期难以排查问题。newclientrepo支持指定仓库名也支持指定服务端名$ newclientrepo $ pwd # the name of the repo is repoN by default $TESTTMP/repo1 $ hg config paths.default # similarly, the repo names are repoN test:repo1_server从 tinit.sh 的实现可以看出未指定名称时仓库按repo1、repo2……自动递增编号_repocount计数默认服务端名为${reponame}_server若指定了服务端名则第二个参数直接生效例如newclientrepo foo test:customservername。针对 Watchman / EdenFS 运行测试这两种组合目前只能通过 Buck 运行且测试名中的-和.需要转换为_。例如# Runs test-rust-checkout.t with Watchman enabled $ buck2 test fbcode//mode/opt :sl_watchman_run_tests -- test_rust_checkout_t # Runs test-rust-checkout.t with EdenFS enabled $ buck2 test fbcode//mode/opt :sl_edenfs_run_tests -- test_rust_checkout_t在 EdenFS 测试中EdenFS CLI 通过eden命令可用新仓库无论克隆还是新建都推荐通过newclientrepo创建以保证环境一致性。抑制无关输出并非所有输出都值得断言。例如测试hg log时hg update的输出与测试目标无关应该用-q静音$ hg update -q commit-x这能让测试更简洁也让后续批量修改update输出时更容易。同理如果修订号、分支名与测试目标无关应避免断言它们这样未来废弃这些特性时不需要同步改动测试。使用 drawdag 构造提交hg debugdrawdag或tinit.sh中定义的drawdag别名可以用更可读、更高效的方式创建提交newclientrepo也接受与 drawdag 相同的输入如上文的EOSheredoc 写法其中B、|、A描述了两个提交及其父子关系。drawdag 的完整语法参见 drawdag 详解。避免依赖上下文随着测试文件变长命令依赖「当前仓库状态」「当前目录」等隐式上下文会让测试难以阅读和修改。官方文档给出两条实用建议避免..路径与其cd ../repo1不如显式cd $TESTTMP/repo1避免用一串hg commit、hg update造仓库能用 drawdag 就用 drawdag实在不能用时插入一条hg log -G命令把仓库结构打印出来让测试自解释。高级特性深入.t测试引擎测试环境TESTTMP 与 TESTDIR每个测试都在一个临时目录中启动其路径可通过环境变量TESTTMP获取TESTDIR则指向tests/目录本身方便引用其他辅助脚本。测试启动时会 sourcetests/tinit.shtinit.sh其中定义的函数可以显著缩短测试。例如Use functions in tinit.sh: $ setconfig lfs.urlfile://$TESTTMP/lfs lfs.threshold10B $ enable lfs rebase $ newrepo它等价于下面这串手写命令$ cat $HGRCPATH EOF [extensions] lfs rebase [lfs] urlfile://$TESTTMP/lfs threshold10B EOF $ hg init repo1 $ cd repo1也就是说setconfig、enable、newrepo分别封装了「追加配置」「启用扩展」「初始化仓库并进入目录」的操作。除了newrepo本地仓库tinit.sh 还提供了newclientrepo克隆出客户端仓库、newserver创建服务端仓库、clone、switchrepo、dummysshcmd等一批通用函数第 52–191 行。newclientrepo还支持同时指定仓库名与服务端名$ newclientrepo foo $ newclientrepo bar test:customservername $ cd $TESTTMP/foo # this goes back to the foo repo此外测试运行还会套用tests/default_hgrc.py中定义的一组默认 Sapling 配置见 default_hgrc.py例如[ui] interactiveFalse、[devel] all-warningsTrue default-date0 0、[commands] status.relativeTrue update.checknoconflict、[remotefilelog] cachepath$TESTTMP/default-hgcache等。这些默认值会根据测试是否兼容debugruntest而有所不同——例如modernconfig分支才会启用[extensions] amend commitcloud与[mutation] enabledtrue。条件逻辑#require/#if/#else/#endif某些测试依赖特定能力如 POSIX、大小写不敏感的文件系统、已安装的特定程序。运行python tests/hghave --list可以列出所有可测试的能力。典型用法#require fsmonitor icasefs The test will be skipped if any of the requirement is not satisfied. #if symlink This block is skipped if symlink is not supported. $ ln -s a b #else This block is skipped if symlink is supported. $ cp a b #endif#if可以嵌套且一条语句可以包含多个能力#if symlink no-osx This block will only be run if symlinks are supported and macOS is not being used $ ln -s a b #if execbit This block will only be run if symlinks are supported, macOS is not being used, and execbit is supported $ chmod x a #endif #else This block will only be run if symlinks are not supported or macOS is being used $ cp a b #endif能力名前缀no-表示「不具备该能力」#require no-fsmonitor Skip this test on run-tests.py --watchman.多测试用例#testcases当大部分测试代码可以复用于不同的代码路径时#testcases可以定义测试用例名配合#if做特性分叉。测试会为每个用例各运行一次#testcases innodb rocksdb #if innodb $ setconfig db.engineinno #else $ setconfig db.enginerocks #endif混合 Python 代码块如果测试使用debugruntest引擎可以将 Python 代码块与 shell 输入直接混排if True: $ echo 1 1在 Python 中处理上一条命令的输出debugruntest会把上一条命令的输出存到 Python 变量_中方便做程序化断言而非逐字匹配$ echo 123 123 _ 123\n True assert _ True\n匹配动态输出(glob)、(re)、(esc)对每次运行都会变化的内容如时间戳可以在期望行末尾加空格和(glob)用*通配$ hg parents -r null --time time: real * secs (user * sys *) (glob)同样地可以用(re)启用正则匹配$ echo 3 \s*3 (re)转义序列也可以直接断言例如带颜色的模板输出$ hg debugtemplate {label(\test.test\, \output\n\)} --config color.test.testblue \x1b[34moutput\x1b[39m (esc)按特性匹配输出(feature !)与(?)可以用(feature-name !)把一行输出标记为「启用该特性时必须出现否则可选」$ hg debugfsinfo | grep eden fstype: eden (eden !)可以同时指定多个特性多个条件为「与」关系并可与 glob 混用$ hg go $B update failed to remove foo: Cant remove file *foo: The process cannot access the file because it is being used by another process. (os error 32)! (glob) (windows !) (no-eden !) 2 files updated, 0 files merged, 1 files removed, 0 files unresolved(?)则无条件地把该行输出标记为可选$ maybe-output-foobar foobar (?)更自由的匹配registerfallbackmatch.t测试还有一个更通用的输出匹配机制——registerfallbackmatch。它让测试无需为不同引擎写#if分叉。例如下面的hg goto在 EdenFS 与非 EdenFS 下输出不同$ hg goto foo 2 files updated, 0 files merged, 1 files removed, 0 files unresolved如果没有 fallback 匹配就得写成#if no-eden $ hg goto foo 2 files updated, 0 files merged, 1 files removed, 0 files unresolved #else $ hg goto foo update complete #endif而registerfallbackmatch正是让两种输出都能被接受的机制。可用的命令与二进制要让测试仅在某个二进制可用时才运行可以使用#require、#if块或( !)行匹配#require git $ git --version | wc -l 1 1 #if node $ node --version | wc -l 1 1 #endif $ lldb -P 21 | wc -l 1 1 (lldb !) [255] (no-lldb !)如前所述.t测试存在两套执行引擎可参见 run-tests.py 第 389–401 行对debugruntest兼容性的判断逻辑旧引擎在 macOS 与 Linux 上使用 Bash 执行命令ls、echo等常规命令就是系统命令git、unzip等二进制也直接使用系统提供即PATH中可见的命令都可用debugruntest引擎并不真正调用 BashShell 内建命令与 coreutils 由测试运行器自身实现甚至unzip等命令也在运行器内部实现。这样做的目的是提升与非 POSIX 操作系统的兼容性并获得更好的性能。测试级设置Test-level settings目前共有四个测试级设置指令#debugruntest-incompatible强制该测试使用旧版测试引擎#inprocess-hg-incompatible用于debugruntest测试。不设置时.t测试中每次调用 Sapling 都会启动一个新进程设置后行为有所变化更多细节见scm/sapling/testing下的文档#chg-compatible用于非debugruntest测试效果与「不使用#inprocess-hg-incompatible」类似让.t测试通过chg守护进程复用 Sapling 进程#modern-config-incompatible仅兼容debugruntest测试不应用于新测试它仅为历史遗留原因存在让测试默认使用更老的配置。Rust 测试遵循社区标准Rust 侧测试遵循 Rust 社区标准Rustdoc对于很可能被其他开发者使用的模块Rustdoc 非常适合展示函数用法示例尤其是用法不直观的函数原生 Rust 代码优先在模块内写单元测试/* module code */ #[cfg(test)] mod tests { use super::*; #[test] fn test_feature_x() { assert!(...); } }独立的集成测试放到tests/基准测试benchmarks放到benches/。在 Sapling 仓库中Rust 源码主要位于 eden/scm/lib如eden/scm/lib下的各 crate 与Cargo.toml原生命令行实现位于 eden/scm/saplingnative相关构建与依赖配置可参考 eden/scm/Cargo.toml。Python 测试单元测试与 doctestrun-tests.py不仅运行.t测试也支持.py文件中标准的 Python 单元测试。仓库中的示例为test-lock.py见 eden/scm/tests 目录下的test-*.py文件。运行方式python tests/run-tests.py test-lock.pyPython 函数还可以携带 doctest通过以下命令运行python tests/run-tests.py test-doctest.py如前所述由于 Python API 稳定性与耦合性问题Python 单元测试更适合逻辑相对独立的模块端到端的命令行行为验证则交给.t测试。测试文件在仓库中的分布与本文内容相关的核心文件与目录均可在当前仓库中找到路径作用tests/全部.t测试、.py单元测试与辅助脚本tests/run-tests.py.t/.py测试运行器支持-i、--watchman等参数tests/tinit.sh被所有.t测试 source 的辅助函数newrepo、newclientrepo、setconfig、enable等tests/default_hgrc.py测试默认 Sapling 配置按是否兼容debugruntest区分tests/hghave.py特性检测模块配合#require/#if使用drawdag 文档drawdag 提交构造语法详解结语如何选择测试类型回顾官方文档的指导原则编写 Sapling 测试时可按如下思路决策验证最终用户的命令行体验涉及hg/sl命令、repo 状态、EdenFS/Watchman 行为→ 首选.t测试验证相对独立的 Rust 模块逻辑→ 模块内#[cfg(test)]单元测试 Rustdoc 示例集成测试放tests/基准放benches/验证相对独立的 Python 逻辑→ 标准 Python 单元测试或 doctest复杂 repo 拓扑多条线、多分支、多提交→ 使用newclientrepo配合 drawdag 语法一个子用例一个仓库平台相关或输出易变的内容→ 善用#require/#if条件指令与(glob)/(re)/(feature !)/(?)输出匹配机制让测试在多个后端上稳定通过。遵循这些规范就能写出与仓库现有上千个测试同风格、可维护、跨平台稳定运行的测试。赞分享开发工具CLI后端【免费下载链接】saplingA Scalable, User-Friendly Source Control System.项目地址https://gitcode.com/gh_mirrors/sa/sapling点击查看免费下载相关推荐Lore 测试规范深度指南从 Rust 单元测试到 Python 冒烟测试的分层测试体系Lore 测试规范深度指南从 Rust 单元测试到 Python 冒烟测试的分层测试体系 Lore 是一个开源的下一代版本控制系统其代码库横跨 Rust核版本控制后端Sapling Mononoke 集成测试完整性规范为 SCS/EdenAPI/Git 协议编写可信赖的 .t 测试Sapling Mononoke 集成测试完整性规范为 SCS/EdenAPI/Git 协议编写可信赖的 .t 测试 MononokeSapling 的服务开发工具CLI后端SaplingEdenFS集成测试框架完全指南从编写 hg 集成测试到 FUSE io_uring 变体SaplingEdenFS集成测试框架完全指南从编写 hg 集成测试到 FUSE io_uring 变体 本文以 eden/integration/REA开发工具CLI后端上一篇3步解锁QQ音乐解析Python工具助你轻松获取无损音质与批量歌单下一篇深度探索SRWE你的窗口分辨率自由定制实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

为 models.dev 设计安全的自动化 PR 审查 Agent:pr-reviewer 的职责、判定规则与实现剖析

为 models.dev 设计安全的自动化 PR 审查 Agent:pr-reviewer 的职责、判定规则与实现剖析

人工智能大模型后端前端 【免费下载链接】models.dev An open-source database of AI models. 项目地址: https://gitcode.com/gh_mirrors/mo/models.dev 点击查看 免费下载 models.dev 是一个开源的 AI 模型数据库,仓库以 AGENTS.md 作为权威的模型/Pr…

2026/10/9 2:15:27 阅读更多 →
批量域名解析提速实战:massdns + aiodns 组合拳

批量域名解析提速实战:massdns + aiodns 组合拳

前几天晚上我盯着一份三千多行的域名列表发呆,任务是把它全部解析到IP,再按网段和用途归类。刚开始天真地以为写个脚本循环调解析接口就完事了,结果跑完一等就是四十多分钟,还动不动卡住,某个域名解析超时就能让整个脚…

2026/10/9 2:15:27 阅读更多 →
Xtreme Toolkit Pro v15.3.1 在 VS2017 下 MFC 界面换肤全攻略

Xtreme Toolkit Pro v15.3.1 在 VS2017 下 MFC 界面换肤全攻略

简介:Codejock.Xtreme.Toolkit.Pro.v15.3.1完整源码包,专为VS2017开发环境重新配置,面向需要开发专业MFC界面的C开发者。包内.sln工程属性已统一修改为32位与64位VS2017工程属性,打开即可直接编译,免去手动升级工程和调…

2026/10/9 2:15:27 阅读更多 →

最新新闻

大模型学习路线图:12步小白也能轻松入门并收藏!

大模型学习路线图:12步小白也能轻松入门并收藏!

本文提供一张清晰的十二步大模型学习路线图,帮助读者从入门到落地高效搭建完整知识体系。路线涵盖Python基础、Transformer原理、提示词工程、LangGraph、LangChain、RAG、Agent、多Agent协同、私有化部署、多模态技术、量化技术和模型微调。建议按顺序学习&#xf…

2026/10/9 2:44:43 阅读更多 →
2026瓷砖一线品牌有哪些?家装瓷砖品牌推荐

2026瓷砖一线品牌有哪些?家装瓷砖品牌推荐

2025年全国陶瓷砖产量掉了17.8%,现在行业开窑率连一半都不到。大家都在抢存量,挑瓷砖早就不只看花色和单价了。新国标GB/T 45817-2025把防污、耐磨这些指标分成了3A到5A三级。现在买砖得看品牌实力、制造产能、产品性能、研发技术、市场渠道、品牌口碑和…

2026/10/9 2:44:43 阅读更多 →
把 Claude/GPT 接进飞书、Telegram、Discord:一条命令跑起来的 OpenClaw 部署工具

把 Claude/GPT 接进飞书、Telegram、Discord:一条命令跑起来的 OpenClaw 部署工具

最近我把玩了这个项目一阵子,本文是第三方视角的记录,不是官方文档。能不能用、怎么用、适不适合你,看完自己判断。 我为什么关注它 事情是这样的:我自己的主力 AI 是 Claude 和 GPT,但我总不可能每次都开网页或终端去…

2026/10/9 2:44:43 阅读更多 →
DLMS/COSEM 蓝皮书解读(三十):IPv4 setup(class_id = 42)—— 电表接入 IPv4 网络必需的“地址/子网/网关/DNS“四件套

DLMS/COSEM 蓝皮书解读(三十):IPv4 setup(class_id = 42)—— 电表接入 IPv4 网络必需的“地址/子网/网关/DNS“四件套

DLMS/COSEM 蓝皮书解读(三十):IPv4 setup(class_id 42)—— 电表接入 IPv4 网络必需的"地址/子网/网关/DNS"四件套系列说明:本系列基于 DLMS UA《Blue Book(蓝皮书)第 16…

2026/10/9 2:44:43 阅读更多 →
大模型人才年薪300万起步!程序员如何抓住AI风口,实现薪资翻倍?

大模型人才年薪300万起步!程序员如何抓住AI风口,实现薪资翻倍?

文章指出互联网大厂为抢夺AI人才,不惜重金,其中大模型相关岗位的薪资待遇尤为诱人,甚至出现年薪300万的情况。这反映了AI时代程序员价值的重新评估:普通研发可能面临成本压缩,而掌握大模型技术的人才则价值倍增。文章建…

2026/10/9 2:44:43 阅读更多 →
电车冷却液的性能指标

电车冷却液的性能指标

电车冷却液和普通防冻液都是乙二醇水基,这是它们唯一像的地方。配方体系,两条路线:普通防冻液靠离子型缓蚀剂防腐——便宜、直接、效果好,代价是电导率高,普遍在 1000 μS/cm 以上,高的能到两三千。燃油车没…

2026/10/9 2:43:43 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/7 13:34:55 阅读更多 →