ARTICLE DETAIL

资讯详情

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

Cobra 文档生成实战:用 spf13/cobra/doc 包为命令树自动生成 ReST 文档

Cobra 文档生成实战:用 spf13/cobra/doc 包为命令树自动生成 ReST 文档 Cobra 文档生成实战用 spf13/cobra/doc 包为命令树自动生成 ReST 文档【免费下载链接】cobraA Commander for modern Go CLI interactions项目地址: https://gitcode.com/GitHub_Trending/co/cobra本文以 Cobra 仓库的 ReST 文档生成指南 为核心讲解如何用doc包中的GenReST、GenReSTTree及其 Custom 变体把cobra.Command自动渲染为 reStructuredTextReST文档既能对整个命令树批量产出.rst文件如 Kubernetes kubectl 的文档场景也能对单个命令精细控制输出。读完本文你可以掌握树形/单命令两种生成方式、filePrepender与linkHandler两个回调的定制能力Hugo front matter、Sphinx 交叉引用并从 doc/rest_docs.go 的源码层面理解每段 ReST 输出的确切构成。为什么选 ReST 格式Cobra 的 文档生成体系 支持四种输出格式Man 页、Markdown、ReST 和 YAML。如果你的文档管线基于 Sphinx典型如 kubectl 的 man 页与站点文档ReST 是最合适的中间格式它支持显式交叉引用:ref:、.. _anchor:锚点能天然表达父命令—子命令的树状链接结构。快速开始生成一个单命令的 ReST 文件对单个cobra.Command生成 ReST 文档极其简单示例如下package main import ( log github.com/spf13/cobra github.com/spf13/cobra/doc ) func main() { cmd : cobra.Command{ Use: test, Short: my test program, } err : doc.GenReSTTree(cmd, /tmp) if err ! nil { log.Fatal(err) } }运行后你会在/tmp目录得到一个 ReST 文档test.rst。文件名由GenReSTTreeCustom中的命名规则决定见 doc/rest_docs.go命令的完整路径CommandPath()即各级命令名以空格连接中的空格全部替换为下划线再拼接.rst后缀。生成整个命令树的 ReST 文档GenReSTTree会递归遍历命令树为每个命令各生成一个文件。Cobra 官方文档给出的典型场景是为 Kubernetes 项目中 kubectl 命令生成文档package main import ( log io os k8s.io/kubernetes/pkg/kubectl/cmd cmdutil k8s.io/kubernetes/pkg/kubectl/cmd/util github.com/spf13/cobra/doc ) func main() { kubectl : cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, io.Discard, io.Discard) err : doc.GenReSTTree(kubectl, ./) if err ! nil { log.Fatal(err) } }这会在指定目录此处为./下生成一整套文件命令树中每个命令对应一个.rst文件。从源码实现看doc/rest_docs.go#L145-L153GenReSTTreeCustom采用先递归子命令、后写当前命令的后序遍历先对每个通过IsAvailableCommand()且不是额外帮助主题的子命令递归调用自身再为当前命令创建文件并渲染。两个过滤条件决定了哪些命令会被写入文档——被标记隐藏或弃用的命令、以及额外帮助主题命令都会跳过。需要留意源码注释中的一个已知限制doc/rest_docs.go#L132-L137如果命令名中包含-GenReSTTree可能无法正确工作。例如cmd下同时存在sub和sub-third两个子命令而sub又有子命令third时cmd-sub-third.1对应.rst同理到底对应哪个命令的 help 输出是未定义的。这是命名规则空格转下划线与连字符天然冲突导致的。生成单个命令的 ReST 文档如果你希望对输出有更多控制或只想为某一个命令而非整棵命令树生成文档可以使用GenReST而不是GenReSTTreeout : new(bytes.Buffer) err : doc.GenReST(cmd, out) if err ! nil { log.Fatal(err) }GenReST只会把cmd这一个命令的 ReST 文档写入out缓冲区doc/rest_docs.go#L57-L59。它的底层实现是GenReSTCustom(cmd, w, defaultLinkHandler)即默认链接处理器版本的封装。一份 ReST 输出包含哪些部分阅读GenReSTCustom的实现doc/rest_docs.go#L62-L130可以完整还原每个命令文档的结构这也是你拿到生成文件后应核对的内容清单锚点.. _ref:其中ref是命令路径空格替换为下划线供其他文档做:ref:交叉引用标题命令完整路径 等长下划线装饰线简介Short字段原文Synopsis 小节内容取自Long若Long为空则回退使用Short若命令可执行cmd.Runnable()还会输出UseLine()作为用法行Examples 小节仅当cmd.Example非空时出现且每行都会用indentString缩进两格doc/rest_docs.go#L172-L186保证落在::字面块内Options / Options inherited from parent commands由printOptionsReSTdoc/rest_docs.go#L30-L49分别渲染NonInheritedFlags()与InheritedFlags()各自包裹在::字面块中且仅在对应 flag 集合存在可用项时才输出小节标题SEE ALSO 小节由 doc/util.go 的hasSeeAlso决定是否出现——只要命令有父命令、或存在任一可用子命令即出现。父命令条目通过linkHandler渲染为链接子命令按名称排序byName并跳过不可用命令与额外帮助主题自动生成标记末尾追加*Auto generated by spf13/cobra on 日期*除非命令设置了DisableAutoGenTag该字段定义见 command.go在 文档生成总览 中也有说明。注意 SEE ALSO 中父命令的DisableAutoGenTag会沿父链向上传染给当前命令doc/rest_docs.go#L105-L109。仓库自带的测试用例验证了上述行为doc/rest_docs_test.go 中TestGenRSTDoc断言输出包含Long、Example、本命令 flagboolone、继承 flagrootflag、父命令Short与子命令Short且不包含弃用命令的ShortTestGenRSTNoHiddenParents验证把父级持久 flag 设为Hidden后rootflag与Options inherited from parent commands小节整体消失TestGenRSTNoTag验证DisableAutoGenTag生效时输出不含 Auto generatedTestGenRSTTree则在临时目录中执行GenReSTTree并断言do.rst文件被创建。这些测试所用的命令树定义在 doc/cmd_test.go。定制输出filePrepender 与 linkHandler 回调GenReST和GenReSTTree都有带回调的替代版本用于精细控制输出func GenReSTTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string, string) string) error { //... }func GenReSTCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string, string) string) error { //... }以上为文档中的签名摘录完整实现分别见 doc/rest_docs.go#L145-L170 与 doc/rest_docs.go#L62-L130。用 filePrepender 为 Hugo 添加 front matterfilePrepender接收完整的输出文件路径其返回值会被原样前置到渲染好的 ReST 文件头部。典型用例是为生成的文档添加 front matter以便与 Hugo 配合使用const fmTemplate --- date: %s title: %s slug: %s url: %s --- filePrepender : func(filename string) string { now : time.Now().Format(time.RFC3339) name : filepath.Base(filename) base : strings.TrimSuffix(name, path.Ext(name)) url : /commands/ strings.ToLower(base) / return fmt.Sprintf(fmTemplate, now, strings.Replace(base, _, , -1), base, url) }从实现看filePrepender的返回值通过io.WriteString直接写入新建文件doc/rest_docs.go#L163-L165发生在正文渲染之前——不定制时GenReSTTree传入的emptyStr回调会返回空串文件即为纯正文。用 linkHandler 适配 Sphinx 交叉引用linkHandler接收命令名与引用锚点即命令路径空格转下划线的结果返回渲染后的链接文本。默认的defaultLinkHandler生成的是 ReST 内联超链接形式name ref.rst_doc/rest_docs.go#L52-L54。在将 rst 转 html或使用 Sphinx 这类依赖:ref:的文档工具链时可替换为 Sphinx 交叉引用格式// Sphinx cross-referencing format linkHandler : func(name, ref string) string { return fmt.Sprintf(:ref:%s %s, name, ref) }这样 SEE ALSO 小节里的父命令、子命令条目就会输出为:ref:形式交由 Sphinx 构建期解析为正确锚点。小结整树生成用doc.GenReSTTree(cmd, dir)每个可用命令各产出一个.rst文件名是命令路径空格转下划线加.rst单命令生成用doc.GenReST(cmd, w)输出内容覆盖锚点、标题、Synopsis、Examples、两组 Options 与 SEE ALSO需要 front matter 或自定义链接格式时改用GenReSTTreeCustom/GenReSTCustom并传入filePrepender、linkHandler回调注意命令名含-时的文件命名冲突限制以及DisableAutoGenTag对页脚标记的控制参考实现与测试doc/rest_docs.go、doc/rest_docs_test.go、doc/util.go。【免费下载链接】cobraA Commander for modern Go CLI interactions项目地址: https://gitcode.com/GitHub_Trending/co/cobra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表