
数据集成数据工程数据分析【免费下载链接】cloudqueryData pipelines for cloud config and security data. Build cloud asset inventory, CSPM, FinOps, and vulnerability management solutions. Extract from AWS, Azure, GCP, and 70 cloud and SaaS sources.项目地址https://gitcode.com/gh_mirrors/cl/cloudquery点击查看免费下载本文以 CloudQuery CLI 仓库中的docs/Custom-Doc.md测试夹具为线索剖析插件发布cloudquery plugin publish时 Markdown 文档是如何被读取、规范化、按文件名 Slug 化并上传到 CloudQuery Hub 的全过程。读完本文你将掌握插件dist/docs目录的文档组织规则、页面命名约定以及如何用仓库中的测试用例验证自己的发布行为。一、Custom-Doc.md 是什么一份专为 Slug 化测试准备的文档在 cli/cmd/testdata/dist-v1-with-team-package-json/docs/Custom-Doc.md 中这份文档的完整内容只有 11 行--- title: Custom Documentation description: Custom Documentation --- # Custom Doc !-- vale off -- This is here only to test slugification of file names. !-- vale on --它包含三个典型要素YAML frontmatter声明title与description均为 Custom Documentation一级标题# Custom Doc正文核心信息This is here only to test slugification of file names.——这句话直接点明了它的存在意义这份文档不是面向用户的正式说明而是用于测试文件名被 Slug 化行为的测试夹具test fixture。它所在的目录dist-v1-with-team-package-json是仓库中模拟待发布插件构建产物dist 目录的样例数据其中package.json已包含完整的team与name字段见 cli/cmd/testdata/dist-v1-with-team-package-json/package.json。与之并列的 cli/cmd/testdata/dist-v1-no-team-package-json/docs/Custom-Doc.md 则是用于覆盖package.json 缺少 team 字段这一异常路径的镜像夹具——同一个文件名、同样的内容被复用到不同的测试场景中。二、Slug 化从 Markdown 文件名到 Hub 文档页面名所谓 slugificationSlug 化在 CloudQuery 发布流程中的具体含义是docs 目录下每个.md文件的文件名去掉扩展名就是最终在 CloudQuery Hub 上展示的文档页面名。这一逻辑的源码实现位于 cli/internal/publish/plugins.go 的UploadPluginDocs函数plugins.go#L184-L241dirEntries, err : os.ReadDir(docsDir) // ... for _, dirEntry : range dirEntries { if dirEntry.IsDir() { continue } fileExt : filepath.Ext(dirEntry.Name()) if fileExt ! .md { continue } content, err : os.ReadFile(filepath.Join(docsDir, dirEntry.Name())) // ... pages append(pages, cloudquery_api.PluginDocsPageCreate{ Content: contentStr, Name: strings.TrimSuffix(dirEntry.Name(), fileExt), }) }由此可以总结出三条明确的转换规则输入规则输出Custom-Doc.md去掉.md扩展名strings.TrimSuffix页面名Custom-Doc子目录dirEntry.IsDir()直接跳过不上传非.md文件如.png、.txtfilepath.Ext判断后跳过不上传也就是说Slug 化的实现是**文件名即页面名**连字符、大小写等字符都被原样保留Custom-Doc.md最终会成为名为Custom-Doc的文档页面而不是被改写为custom-doc或custom_doc。测试用例也正是据此断言请求体中页面的name字段恰为Custom-Doc见下文第七节。三、内容在传输前经历的两道加工页面名确定之后文档内容在进入请求体之前还会经历两道处理同样位于UploadPluginDocs内1. 内容规范化NormalizeContent读取文件内容后首先调用hub.NormalizeContent定义见 cli/internal/hub/util.gofunc NormalizeContent(s string) string { s strings.TrimSpace(s) s strings.ReplaceAll(s, \r\n, \n) s strings.ReplaceAll(s, \r, \n) return s }它做三件事去除首尾空白、将 Windows 换行符\r\n统一为\n、将旧式\r也统一为\n。这保证了无论开发者用何种操作系统、何种编辑器书写文档上传到 Hub 的内容都是同一种规范格式。2. 文档内图片处理ProcessDocument规范化之后内容还会经过images.ProcessDocument的处理plugins.go#L205-L208用于处理文档中引用的图片资源。这一步与页面名无关但说明了发布流程对文档中图片资产的托管支持。值得一提的是测试端同样调用了hub.NormalizeContent来构造期望值见 cli/cmd/plugin_publish_test.go 的readFile辅助函数确保测试对比时内容已被同一规则规范化避免换行符差异导致断言失败。四、文档上传在plugin publish全流程中的位置Custom-Doc.md的 Slug 化行为只有放在cloudquery plugin publish的完整执行链路中才能理解其价值。命令定义与主流程见 cli/cmd/plugin_publish.go。命令参数plugin_publish.go#L57-L59参数简写默认值说明--dist-dir-Ddist指向待发布的构建产物目录--ui-dir-U空可选已构建好的插件 UI 目录必须为目录--finalize-ffalse若为 true发布后将版本标记为非 draft 并对外可见执行步骤plugin_publish.go#L64-L180鉴权auth.NewTokenClient().GetToken()获取 API Token通常由cloudquery login写入失败直接报错读取 package.jsonpublish.ReadPackageJSON(distDir)读取并校验 schema_version仅支持 v1见 plugins.go#L163-L182确定插件标识优先使用 package.json 的team/name字段两者任一为空时才回退到命令行参数team/name见 plugin_publish.go#L92-L103创建草稿版本CreateNewPluginDraftVersion上报 message、protocols、supported_targets、checksums 等仅 source 插件上传表结构读取tables.json并上传上传文档调用UploadPluginDocs(ctx, c, teamName, kind, pluginName, version, docsDir, true)即本节讨论的 Slug 化流程上传二进制/镜像根据package_type走PublishNativeBinaries上传 zip 产物或PublishToDockerRegistry推送 Docker 镜像与 manifest可选上传 UI 资产当指定--ui-dir时执行可选Finalize若指定--finalize将draft置为false否则版本保持草稿态可在 Hub 上预览后再决定是否对外发布。可见文档上传发生在版本草稿创建之后、二进制上传之前是版本信息落地 Hub 的关键一环。五、Create 与 Replace两种文档写入模式的语义UploadPluginDocs的最后一个参数replace控制写入模式plugins.go#L216-L238replace true调用ReplacePluginVersionDocsWithResponse整组覆盖该版本的文档页面集合replace false调用CreatePluginVersionDocsWithResponse追加创建。在plugin publish主流程中该参数恒为trueplugin_publish.go#L137语义是以当前 dist 目录中的 docs 内容为准全量替换该版本文档。因此本地 docs 目录中多余的.md文件会一并被发布而缺失的旧页面则会被移除——这要求开发者在发布前保证 docs 目录的整洁与完整。六、宿主环境dist 目录结构与 package.json 字段Custom-Doc.md所在的dist-v1-with-team-package-json目录是一个完整的、可被测试代码直接消费的 dist 样例dist-v1-with-team-package-json/ ├── docs/ │ ├── Custom-Doc.md # 本主题的测试夹具 │ ├── configuration.md # 配置说明页 │ └── overview.md # 概览页 ├── package.json ├── plugin-test-v1.2.3-darwin-amd64.zip ├── plugin-test-v1.2.3-linux-amd64.zip └── tables.json其中package.jsonpackage.json承载了发布所需的全部元数据字段与PackageJSONV1结构体plugins.go#L36-L45一一对应字段示例值说明schema_version1仅 v1 受支持其他版本会报错nametest插件名teamcloudquery团队名与name共同构成team/namemessageMarkdown 文本版本发布说明changelog 内容versionv1.2.3版本号必须以v开头kindsourcesource或destinationprotocols[3]支持的协议版本列表supported_targets见下各平台构建产物的元信息package_typenativenative二进制或dockersupported_targets中的每个目标包含os、arch、path相对 dist 目录的产物路径与checksumsha256:前缀可被自动剥离见 plugins.go#L246-L249。七、测试如何验证 Slug 化行为Slug 化的正确性由 cli/cmd/plugin_publish_test.go 中的TestPluginPublish与checkCreateDocsRequest共同保障。checkCreateDocsRequestplugin_publish_test.go#L480-L516会解析文档上传请求体并断言want : map[string]any{ pages: []any{ map[string]any{ content: customDocContent, name: Custom-Doc, // ← Slug 化后的页面名 }, map[string]any{ content: configurationContent, name: configuration, }, map[string]any{ content: overviewContent, name: overview, }, }, }customDocContent由readFile(distDir /docs/Custom-Doc.md)读取即期望上传的内容就是本地文件的规范化原文期望的页面名就是去掉.md后的文件名——这正是对 Slug 化规则的双重验证既验证了内容逐字节一致也验证了文件名→页面名的映射。测试共覆盖三个场景plugin_publish_test.go#L28-L44场景dist 目录命令行参数旧格式 package.json 旧式参数dist-v1-no-team-package-json显式传cloudquery/test新格式 package.json 旧式参数dist-v1-with-team-package-json显式传cloudquery/test新格式 package.json 无参数dist-v1-with-team-package-json不传插件名第三种场景正是Custom-Doc.md存在的主战场team/name从 package.json 中读取命令行无需再传插件名若两者都为空且又没有命令行参数则会命中errInvalidPluginName错误invalid plugin name. Must be in format team_name/plugin_name...见 plugin_publish_test.go#L526-L558 对dist-v1-empty-team-and-name-package-json的验证。八、实操为自己的插件编写文档并发布基于以上机制为插件编写文档并发布的标准做法是组织 docs 目录在 dist 目录下创建docs/放置overview.md、configuration.md以及任意数量的自定义页面如Custom-Doc.md。文件名即最终页面名因此请使用语义清晰、URL 友好的命名连字符分隔并保证不含子目录与.md以外的文件会被忽略但可能造成预期之外的内容缺失编写 frontmatter每个页面可带title/descriptionfrontmatter用于 Hub 端展示正文使用标准 Markdown注意跨平台换行符会被自动规范化完善 package.json确保schema_version: 1、team、name、version以v开头等字段完整登录并发布cloudquery login cloudquery plugin publish --dist-dir dist最终对外可见不传--finalize时版本保持 draft可在 Hub 预览后再补一次 finalizecloudquery plugin publish --dist-dir dist --finalize若本地docs内容发生增删重新发布同一版本时replacetrue会整组覆盖文档页面因此发布前务必检查 docs 目录内是否有遗留的多余文件。九、小结一份只有一句话正文的Custom-Doc.md恰好是理解 CloudQuery 插件发布中文档管理机制的钥匙文件名通过strings.TrimSuffix被直接 Slug 化为 Hub 页面名内容经NormalizeContent规范化与图片处理后以整组替换的语义随cloudquery plugin publish一并上传并由仓库中的 plugin_publish_test.go 以真实 HTTP 请求断言的方式锁定了这一行为。理解了这套规则无论是调试发布失败、还是为插件规划文档结构都能做到有的放矢。赞分享数据集成数据工程数据分析【免费下载链接】cloudqueryData pipelines for cloud config and security data. Build cloud asset inventory, CSPM, FinOps, and vulnerability management solutions. Extract from AWS, Azure, GCP, and 70 cloud and SaaS sources.项目地址https://gitcode.com/gh_mirrors/cl/cloudquery点击查看免费下载相关推荐CloudQuery 插件表文档自动生成机制解析以嵌套关系表 relation_relation_table_b 的快照文档为例CloudQuery 插件表文档自动生成机制解析以嵌套关系表 relation_relation_table_b 的快照文档为例 CloudQuery 是开源数据集成数据工程数据分析CloudQuery 增量同步表文档解析与 Markdown 生成机制CloudQuery 增量同步表文档解析与 Markdown 生成机制 CloudQuery 的表格文档是理解数据管道结构的重要入口本篇文章以 increme数据集成数据工程数据分析CloudQuery 插件文档生成器深度解析从表格元数据到 Markdown 文档目录CloudQuery 插件文档生成器深度解析从表格元数据到 Markdown 文档目录 导读 本文以 CloudQuery CLI 仓库中 cli/inter数据集成数据工程数据分析上一篇Kanagawa.nvim 项目使用教程下一篇ggml完整生态指南10大开源项目与核心资源大全创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考