尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Dagger TypeScript SDK 的 CurrentModuleGeneratorsOpts 详解:用 include 精确筛选模块生成器

Dagger TypeScript SDK 的 CurrentModuleGeneratorsOpts 详解:用 include 精确筛选模块生成器 Dagger TypeScript SDK 的 CurrentModuleGeneratorsOpts 详解用 include 精确筛选模块生成器【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger导读CurrentModuleGeneratorsOpts是 Dagger TypeScript SDKdagger.io/dagger在api/client.gen模块中定义的一个类型别名它是CurrentModule.generators()方法的可选参数对象。本文从该类型在 SDK 中的定义出发结合仓库内 TypeScript 生成代码与 Go 侧 GraphQL Schema 实现深入讲解其唯一字段include的模式匹配规则、底层执行链路并给出在模块函数内按需筛选生成器的实战写法。读完本文你将能够在 Dagger 模块中精确控制本次只运行哪些代码生成器从而在 CI、本地开发或工作流编排中按需触发代码生成。一、类型定义一个可选的 include 模式数组在 Dagger v0.19 的 TypeScript API 参考文档中CurrentModuleGeneratorsOpts的定义极为简洁CurrentModuleGeneratorsOpts object它只包含一个可选属性属性类型必填说明include?string[]否Only include generators matching the specified patterns仅包含与指定模式匹配的生成器这份文档对应的真实 TypeScript 源码位于仓库 sdk/typescript/src/api/client.gen.ts由 Dagger 的代码生成器根据引擎 GraphQL Schema 自动产出其内容与文档完全一致export type CurrentModuleGeneratorsOpts { /** * Only include generators matching the specified patterns */ include?: string[] }从类型结构可以确认两点事实整体可选include字段是可选的整个opts参数在调用时也可省略省略时等价于返回模块定义的所有生成器数组语义传入多个模式时按任一匹配即命中OR 语义处理这一点可以从底层实现中确认详见第三节。同目录下还有一个结构完全相同的兄弟类型ModuleGeneratorsOpts见 ModuleGeneratorsOpts.md 与 client.gen.ts 附近定义它服务于Module.generators()方法区别仅在于调用主体不同。二、方法签名CurrentModule.generators(opts?) 与返回类型CurrentModuleGeneratorsOpts只被一个方法消费即CurrentModule类上的generators方法。SDK 源码 sdk/typescript/src/api/client.gen.ts 中给出了带注释的完整签名/** * Return all generators defined by the module * param opts.include Only include generators matching the specified patterns * experimental */ generators (opts?: CurrentModuleGeneratorsOpts): GeneratorGroup { const ctx this._ctx.select(generators, { ...opts }) return new GeneratorGroup(ctx) }需要注意的要点返回类型是GeneratorGroup而不是单个生成器。GeneratorGroup封装了一个或多个生成器的集合其 API 同样定义在 client.gen.ts包括list()列出组内每个生成器及其详情changes(opts?)上一次运行合并后的 changeset文件差异isEmpty()上一次运行产生的 changeset 是否为空loadFailures()收集生成器时被容忍的加载失败信息。该方法被标记为experimental在 GraphQL Schema 中同样标注为 highly experimental and may be removed or replaced entirely见 core/schema/module.go因此生产环境使用时需注意 API 后续可能演进。CurrentModule代表正在其中执行的模块与通用的Module不同CurrentModule.generators()让模块代码在运行期读取自身定义的生成器集合是实现自省式生成管线的入口。三、include 的底层实现从 TypeScript 到 Go 引擎的完整链路要理解include的确切行为需要沿调用链深入 Go 引擎侧。3.1 GraphQL 字段定义在引擎 Schema 中currentModule.generators字段定义于 core/schema/module.godagql.Func(generators, s.currentModuleGenerators). Experimental(This API is highly experimental and may be removed or replaced entirely.). Doc(Return all generators defined by the module). Args( dagql.Arg(include).Doc(Only include generators matching the specified patterns), ),模块级别的module.generators与之对称同样接收include参数core/schema/module.go。3.2 参数解析与分组构建对应的 Go 解析函数currentModuleGenerators位于 core/schema/module.gofunc (s *moduleSchema) currentModuleGenerators( ctx context.Context, mod *core.CurrentModule, args struct { Include dagql.Optional[dagql.ArrayInput[dagql.String]] }, ) (*core.GeneratorGroup, error) { var include []string if args.Include.Valid { for _, pattern : range args.Include.Value { include append(include, pattern.String()) } } return core.NewGeneratorGroup(ctx, mod.Module, include) }这段代码清楚展示了include在 GraphQL 层是[String]字符串数组可为空省略时include为空切片此时NewGeneratorGroup不做任何过滤传入时逐个取出字符串原样交给core.NewGeneratorGroup。3.3 模式匹配的核心RollupGenerator 与 GlobNewGeneratorGroupcore/generators.go先把模块挂载为模块树再调用RollupGeneratorfunc NewGeneratorGroup(ctx context.Context, mod dagql.ObjectResult[*Module], include []string) (*GeneratorGroup, error) { rootNode, err : NewModTree(ctx, mod) ... generatorNodes, err : rootNode.RollupGenerator(ctx, include, nil) ... }RollupGeneratorcore/modtree.go在模块树中遍历只保留IsGenerator为 true 的节点并把include数组传给通用的RollupNodes过滤逻辑。模式匹配的最终语义由ModTreePath.Glob与Match定义core/modtree.gofunc (p ModTreePath) Glob(ctx context.Context, pattern string) (bool, error) { // Normalize both pattern and path to CLI case (kebab-case) for consistent matching slashPattern : strings.Join(NewModTreePath(pattern).CliCase(), /) slashPath : strings.Join(p.CliCase(), /) if match, err : doublestar.PathMatch(slashPattern, slashPath); err ! nil { return false, err } else if match { return true, nil } ... } func (node *ModTreeNode) Match(ctx context.Context, patterns []string) (bool, error) { ... if len(patterns) 0 { return true, nil } for _, pattern : range patterns { if match, err : node.Path().Glob(ctx, pattern); err ! nil { return false, err } else if match { return true, nil } patternAsPath : NewModTreePath(pattern) if patternAsPath.Contains(ctx, node.Path()) { return true, nil } } return false, nil }由此可以得出include模式的四条确定规则路径即身份模式匹配的是生成器在模块树中的路径而不是文件名或函数名本身kebab-case 归一化模式与路径都会统一转换为 CLI 风格strcase.ToKebab后再匹配因此changelog:generate与changelog:generate这类写法是稳定的支持 doublestar 通配匹配使用doublestar.PathMatch支持*、**、?等 glob 通配符与dagger generateCLI 的选择器语义一致例如protobuf:*表示某模块下所有以protobuf开头的生成器前缀包含也命中除了 glob 精确匹配只要模式是节点路径的祖先前缀patternAsPath.Contains(...)该节点同样被包含——这意味着指定一个模块名即可选中该模块下的全部生成器。四、实战示例在模块函数内按模式筛选生成器CurrentModuleGeneratorsOpts的典型使用场景是模块内部需要按需触发自身的部分代码生成任务。例如只运行changelog模块中名为generate的生成器import { dag, CurrentModule } from dagger.io/dagger; // 在模块函数内部访问 CurrentModule async function runOnlyChangelog(mod: CurrentModule): Promiseboolean { const generators mod.generators({ include: [changelog:generate], }); // 运行选中的生成器GeneratorGroup 上没有显式 run 时的等价做法 // 可在 SDK 中通过 list() 逐个获取 Generator 再调用 const list await generators.list(); for (const g of list) { await g.run(); } // 判断本次生成是否产生了差异 return generators.isEmpty(); }需要说明的是SDK 中GeneratorGroup与Generator类的run/changes/isEmpty方法均对应引擎侧 GraphQL 字段见 core/schema/generators.go 中list、run、changes、isEmpty的定义模块作者也可以直接基于GeneratorGroup的changes()获取合并后的 changeset 再做处理而不是逐个执行。筛选更多生成器时只需追加模式mod.generators({ include: [protobuf:*, changelog:generate], });省略include则返回模块定义的全部生成器const all mod.generators();五、与 dagger generate CLI 的对应关系CurrentModuleGeneratorsOpts.include并不是孤立设计它和 Dagger CLI 的dagger generate命令共享同一套选择器语义方便用户在交互式命令行与编程式 API 之间无缝切换使用方式筛选语法含义CLI见 docs/current_docs/using/generating.mdxdagger generate protobuf:*运行某模块全部匹配生成器CLIdagger generate changelog:generate运行单个生成器CLIdagger generate -l列出所有可用生成器SDKmod.generators({ include: [protobuf:*] })编程式等价筛选SDKmod.generators({ include: [changelog:generate] })编程式等价筛选两者的模式匹配都由引擎同一套模块树路径逻辑支撑见上文ModTreePath.Glob因此在 CLI 中验证过的选择器写法可以直接迁移到 SDK 调用中。另一个相关事实dagger check --generate会把生成器作为只读检查运行若生成的产物与已提交内容不一致则失败docs/current_docs/using/generating.mdx。这意味着编程式使用CurrentModuleGeneratorsOpts筛选出的生成器集合也可以被编排进先生成、再验证的流水线中而GeneratorGroup.isEmpty()正好可用于判断生成结果是否有漂移。六、注意事项与边界实验性 APIgenerators及CurrentModuleGeneratorsOpts在 Schema 中被明确标注为高度实验性Experimental见 core/schema/module.go在升级 Dagger 版本时需留意签名变动。include 只筛选、不改写include只决定返回哪些生成器不会改变生成器本身的运行行为或输出多个生成器结果合并时的冲突策略由GeneratorGroup.changes(opts.onConflict)另行控制见 client.gen.ts 与 core/schema/generators.go 中默认FAIL_EARLY的合并策略。空数组行为include: []与省略include等价均返回全部生成器若想确认某个模块下到底有哪些生成器可用于筛选可先调用generators().list()查看路径清单。模式基于路径而非函数名筛选模式对应生成器在模块树中的命令路径kebab-case编写模式前建议先用dagger generate -l或list()确认实际路径。总结CurrentModuleGeneratorsOpts是 Dagger TypeScript SDK 为CurrentModule.generators()提供的唯一可选参数其include: string[]字段依托引擎侧模块树路径 doublestar glob 的匹配机制实现了与dagger generateCLI 完全一致的生成器筛选语义。掌握它你就可以在 Dagger 模块中按模块名、通配模式或精确路径精准控制代码生成任务的范围为 CI 中的定向生成、增量生成与漂移校验提供编程式基础。更多相关类型与类可继续阅读 api/client.gen 索引以及GeneratorGroup、Generator的 SDK 参考文档。【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表