oclif readme --multi 实战:嵌套主题(Nested Topics)多页 README 自动生成

📅 发布时间:2026/9/25 5:03:41
oclif readme --multi 实战:嵌套主题(Nested Topics)多页 README 自动生成
开发工具【免费下载链接】oclifCLI for generating, building, and releasing oclif CLIs. Built by Salesforce.项目地址https://gitcode.com/gh_mirrors/oc/oclif点击查看免费下载oclif readme是 oclif 提供的 README 自动生成命令可把 CLI 的全部命令用法、主题Topic说明和目录TOC同步写入 README.md。本文以仓库测试夹具 test/fixtures/cli-with-nested-topics/README.md 为“黄金样本”结合 src/readme-generator.ts 与 src/commands/readme.ts 的源码实现深入讲解--multi多页模式、嵌套主题的过滤与分页规则、--nested-topics-depth深度控制以及--no-aliases别名过滤等实战要点。读完本文你将能在自己的 oclif CLI 项目中复现同样结构的多页文档目录并理解每一行生成结果的来源。一、这份 fixture 文档是什么一次生成结果的“证据快照”test/fixtures/cli-with-nested-topics/README.md 并不是一篇普通的技术文档而是 oclif 项目用于验证readme命令行为的一份测试夹具。文档开头明确写着它的用途This file is a test for runningoclif-dev readmewith aliases. If the --no-aliases flag is passed as a flag, no aliases should be in the README.也就是说它要验证两件事readme命令能在 README 中正确生成 Usage、Commands、Command Topics 三块内容当传入--no-aliases时命令列表里不得出现别名alias。同一份夹具还配合 test/fixtures/cli-with-nested-topics/package.json 定义了roottopic:subtopic1与roottopic:subtopic2两个嵌套主题因此这份 README 又充当了“嵌套主题在多页模式下输出形态”的黄金样本——你看到的每一行生成结果都可以在下方源码中找到对应逻辑。这也意味着阅读本文后你不仅能看懂这份 fixture还能把它当作自己 CLI 文档生成的验收标准。二、README 自动更新的基石三类占位标记oclif readme不会重写整个文件而是通过扫描占位标记进行局部替换。标记的完整说明写在 src/commands/readme.ts 的description中The readme must have any of the following tags inside of it for it to be replaced or else it will do nothing: # Usage !-- usage -- # Commands !-- commands -- # Table of contents !-- toc --即在 README 中先写好注释型占位符命令执行时用生成内容替换标记之间的区间。替换逻辑位于 src/readme-generator.ts 的replaceTag()方法若文件中同时存在!-- tag --与!-- tagstop --则把两者之间的旧内容整体替换为!-- tag --\n新内容\n!-- tagstop --若只有起始标记而没有stop标记则只在起始标记后插入新内容若连起始标记都没有则什么都不做。三种标记在 fixture 中的落点非常清晰toc 标记!-- toc --与!-- tocstop --之间生成“本文档标题”目录#开头标题的锚点列表usage 标记!-- usage --与!-- usagestop --之间生成安装、版本、帮助信息的 sh-session 代码块commands 标记!-- commands --与!-- commandsstop --之间生成命令清单——在多页模式下这里填充的正是 “# Command Topics” 主题索引。replaceTag()的调用顺序见generate()方法src/readme-generator.ts先替换 usage再替换 commands单页模式走commands()多页模式走multiCommands()最后基于更新后的README 重新生成 toc保证目录与正文一致。三、Usage 区块标准 CLI 使用说明模板fixture 中!-- usage --之间的内容是一段固定模板$ npm install -g cli-command-with-alias $ oclif COMMAND running command... $ oclif (--version) cli-command-with-alias/0.0.0 darwin-arm64 node-v20.11.0 $ oclif --help [COMMAND] USAGE $ oclif COMMAND ...这段输出的生成函数是 src/readme-generator.ts 的usage()方法它由当前配置动态拼装npm install -g ${this.config.name}包名取自 package.json 的name$ ${this.config.bin} (--version)版本参数除了--version还会读取pjson.oclif.additionalVersionFlags并排序后以|连接版本字符串cli-command-with-alias/0.0.0 darwin-arm64 node-v20.11.0由name/version 平台-架构 node版本组成其中0.0.0来自该 fixture 未发布时的默认版本号。因此在真实 CLI 中只要package.json的name、bin、version正确这块内容会自动对齐无需手工维护。四、嵌套主题从哪来命令目录结构与 topics 配置嵌套主题nested topics并非凭空声明而是由两层信息共同决定。第一层命令文件目录结构。该夹具的命令树位于 test/fixtures/cli-with-nested-topics/src/commands/roottopic/subtopic1/hello.ts 与subtopic2/hello.ts。oclif 会把commands目录下的相对路径映射为命令 idroottopic/subtopic1/hello.ts对应命令roottopic:subtopic1:helloroottopic/subtopic2/hello.ts对应roottopic:subtopic2:hello冒号:即默认的主题分隔符。两个 hello 命令都通过static aliases [hi]声明了别名这是测试--no-aliases行为的关键前提。第二层package.json 的oclif.topics元数据。test/fixtures/cli-with-nested-topics/package.json 中oclif: { commands: ./lib/commands, bin: oclif, helpClass: ./lib/help, topics: { roottopic: { description: Root topic description, hidden: true }, roottopic:subtopic1: { description: Subtopic1 description }, roottopic:subtopic2: { description: Subtopic2 description } } }每个主题的description会直接进入生成的 “Command Topics” 列表hidden: true则让该主题在文档中不出现。这正是 fixture 中只有roottopic:subtopic1、roottopic:subtopic2两行、却没有根主题roottopic的原因——根主题被隐藏了尽管它真实存在且拥有命令。五、--multi 多页模式Command Topics 章节是如何生成的fixture README 中最关键的一段是# Commands !-- commands -- # Command Topics - oclif roottopic:subtopic1 - Subtopic1 description - oclif roottopic:subtopic2 - Subtopic2 description !-- commandsstop --注意这里同时保留了 “# Commands” 标题和 “# Command Topics” 小节。原因是替换只发生在标记之间——!-- commands --标记位于 “# Commands” 标题之下而多页模式生成的内容自身以 “# Command Topics” 开头于是两个标题先后出现。这是--multi模式的典型输出形态可以看作生成器忠实于占位符位置、不做额外假设的体现。生成逻辑当--multi开启时generate()调用 src/readme-generator.ts 的multiCommands()方法它按以下步骤工作主题过滤默认只保留未隐藏!t.hidden且不含冒号!t.name.includes(:)的主题若指定了nestedTopicsDepth则改为保留“冒号数量 深度值”的主题见下文第六节。命令关联过滤topics.filter((t) commands.find((c) c.id.startsWith(t.name)))——只保留至少拥有一个前缀匹配命令的主题空主题不会出现在文档中。排序去重按主题名排序并去重。逐主题生成页面对每个主题调用createTopicFile()src/readme-generator.ts把文件写到path.join(., dir, topic.name.replaceAll(:, /) .md)即docs/roottopic/subtopic1.md、docs/roottopic/subtopic2.md。子页面内容包含\oclif roottopic:subtopic1标题、主题描述以及该主题下所有命令的完整用法清单同样通过commands() 渲染。返回索引在 README 中生成 “# Command Topics” 列表每行格式为* oclif 主题名 - 描述其中描述取render(t.description)的第一行。每个主题页面内命令的筛选条件是c.id topic.name || c.id.startsWith(topic.name :)即包含主题自身的命令及其所有子命令。而单页模式下的commands()src/readme-generator.ts则会把全部命令平铺成锚点列表与详细区块两种模式各有适用场景命令量少用单页主题复杂用多页。六、--nested-topics-depth控制嵌套深度的精确开关当主题层级较深如roottopic:subtopic1:section时--multi默认只生成一层主题索引。要控制嵌套层级需要--nested-topics-depth标志。对应源码在 src/readme-generator.tstopics nestedTopicsDepth ? topics.filter((t) !t.hidden (t.name.match(/:/g) || []).length nestedTopicsDepth) : topics.filter((t) !t.hidden !t.name.includes(:))判断标准是主题名中冒号的数量roottopic:subtopic1含 1 个冒号roottopic:subtopic1:section含 2 个冒号。设--nested-topics-depth 2则冒号数 2 的主题即 0 或 1 个冒号的主题都会被纳入索引不传该标志时则退化为“只允许 0 个冒号的顶层主题”。该标志在 src/commands/readme.ts 中定义为整数类型并声明dependsOn: [multi]——即它必须与--multi搭配使用单独传入会被 oclif 校验拒绝。这也是官方oclif readme --help见 docs/readme.md中--nested-topics-depthvalue ... Use with --multi enabled.的语义来源。七、--no-aliases命令清单中的别名过滤回到 fixture 的原始目的——别名测试。readme命令的--aliases标志支持--no-aliases反写allowNo: true默认值为true见 src/commands/readme.ts。过滤逻辑位于generate()中src/readme-generator.tsconst commands uniqBy( this.config.commands .filter((c) !c.hidden c.pluginType core) .filter((c) (this.options.aliases ? true : !c.aliases.includes(c.id))) .map((c) (this.config.isSingleCommandCLI ? {...c, id: } : c)) .sort((a, b) a.id.localeCompare(b.id)), (c) c.id, )要点--no-aliases生效时凡是c.aliases中包含自身 id 的命令都会被剔除——即“该命令本身是被当作别名挂载的”这种情形不出现在文档中别名展示与否只影响命令是否进入清单命令自身的aliases声明不受影响单命令 CLIisSingleCommandCLI会把命令 id 清空避免文档中出现无意义的前缀命令按 id 字典序排序并以 id 去重。所以用oclif readme --no-aliases重新生成后README 中不应再出现任何别名命令条目这正是 fixture 注释中承诺的验收行为。八、topicSeparator空格分隔主题的变体验证嵌套主题的分隔符并非只能使用冒号。仓库还提供了变体夹具 test/fixtures/cli-with-nested-topics-with-space-separator/package.json它在oclif配置中额外声明topicSeparator: 此时 Command Topics 索引中的展示名会从oclif roottopic:subtopic1变为oclif roottopic subtopic1。对应实现见 src/readme-generator.ts 的multiCommands()模板* \${this.config.bin} ${t.name.replaceAll(:, this.config.topicSeparator)}\}.md)可见展示名用topicSeparator替换冒号而磁盘文件名始终用/替换冒号docs/roottopic/subtopic1.md既保持了用户可读的展示风格又保证了文件路径跨平台安全。九、实战在自己的 oclif CLI 中复现多页文档要在你自己的项目里得到与 fixture 一致的生成结果只需四步搭建嵌套命令树在src/commands/下按目录层级组织命令例如src/commands/roottopic/subtopic1/hello.ts命令类继承oclif/core的Command并用static description、static aliases声明元信息。在 package.json 声明主题元数据在oclif.topics中为每个主题含隐藏的根主题配置description需要隐藏时加hidden: true如需空格风格展示追加topicSeparator: 。在 README.md 写好占位标记放置!-- toc --、!-- usage --、!-- commands --三对标记对应章节标题可自行安排否则命令不会修改文件。运行多页生成命令$ oclif readme --multi --nested-topics-depth 2 --output-dir docs --no-aliases相关标志速查完整列表见 docs/readme.md 与 src/commands/readme.ts标志默认值说明--[no-]aliasestrue命令清单是否包含别名--no-aliases关闭--multifalse为每个主题生成独立 markdown 页面--nested-topics-depthn无多页模式下最大嵌套深度须与--multi搭配--output-dirdirdocs多页文档输出目录--dir为其别名--readme-pathpathREADME.md要更新的 README 文件路径--dry-runfalse只打印生成结果不写文件--plugin-directorydir当前目录指定要生成 README 的插件目录--repository-prefixtpl仓库模板源码链接 URL 模板也可用oclif.repositoryPrefix配置--[no-]source-linkstrue是否为每个命令生成“查看源码”链接--tsconfig-pathpathtsconfig.json用于推断编译输出目录的 tsconfig 路径--versionvpackage.json 版本生成源码链接时使用的版本号值得注意的细节命令执行时会先读取tsconfig.json的compilerOptions.outDir默认lib若该编译输出目录不存在会给出警告见 src/commands/readme.ts因为生成器基于编译后的命令元数据工作——先执行tsc再运行oclif readme是稳妥的顺序。此外--dry-run可在不改动文件的前提下预览完整输出适合接入 CI 做文档一致性校验。十、从样本到原理核心实现速览最后把本文涉及的源码锚点汇总便于继续深入入口命令与标志定义src/commands/readme.ts —— 负责解析标志、加载配置、实例化生成器生成器主流程src/readme-generator.ts ——generate()按 usage → commands → toc 顺序替换多页主题生成src/readme-generator.ts ——multiCommands()的主题过滤、排序、关联与索引渲染主题子页面写入src/readme-generator.ts ——createTopicFile()生成docs/topic.md别名过滤与排序src/readme-generator.ts ——--no-aliases的剔除逻辑官方命令文档docs/readme.md ——oclif readme全部标志与占位标记的权威说明测试夹具样本与变体test/fixtures/cli-with-nested-topics/README.md、test/fixtures/cli-with-nested-topics/package.json、test/fixtures/cli-with-nested-topics-with-space-separator/package.json。总而言之oclif readme --multi的价值在于把“命令文档”从手写负担变成可校验的生成产物占位标记决定了内容落在哪里topics配置决定了主题如何描述与隐藏--nested-topics-depth决定嵌套层级--no-aliases决定别名是否入册而topicSeparator则决定用户在帮助与文档中看到的主题书写风格。理解了这五件事你就能像 oclif 官方测试那样用一份 fixture 牢牢锁住自己 CLI 的文档形态。赞分享开发工具【免费下载链接】oclifCLI for generating, building, and releasing oclif CLIs. Built by Salesforce.项目地址https://gitcode.com/gh_mirrors/oc/oclif点击查看免费下载相关推荐README自动生成工具readme-scribe使用教程README自动生成工具readme scribe使用教程 1. 项目介绍 readme scribe 是一个GitHub Action它能够自动生成和更新mQwen-Image-Layered完全指南从安装到图像分解的30分钟快速上手教程Qwen Image Layered完全指南从安装到图像分解的30分钟快速上手教程 Qwen Image Layered是一款强大的图像分层分解工具通过La人工智能大模型计算机视觉AI 应用媒体生成Qwen项目名称这是项目描述... {{INSERT_DYNAMICT_CONTENT_HERE}} 步骤2生成GitHub个人访问令牌 为了使 readme scribe创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考