
Dagger TypeScript SDK 的 GeneratedCode 类理解 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本篇技术指南围绕 Dagger 0.21 TypeScript SDK 中GeneratedCode类的完整 API 展开讲解该类型如何承载一次 SDK codegen 的最终产物——即生成的源码目录以及如何通过vcsGeneratedPaths与vcsIgnoredPaths把生成结果自动写入.gitattributes与.gitignore从而让模块仓库里的生成代码与手写代码在版本控制中和平共处。读完本文你将掌握GeneratedCode全部方法与参数的语义、它在 Dagger 模块代码生成链路ModuleSource.codegen→ SDK 调用 → VCS 文件落地中的位置以及如何在自定义 SDK 中正确使用它。1.GeneratedCode是什么GeneratedCode是 Dagger 中运行某个 SDK 的 codegen 之后得到的结果这一抽象。其官方描述TypeScript SDK 参考文档与 Go 侧核心实现一致为The result of running an SDKs codegen.在 TypeScript SDK 中它位于client.gen.ts生成代码内由 sdk/typescript/src/api/client.gen.ts 中的export class GeneratedCode extends BaseClient定义对应的引擎侧核心类型定义在 core/codegen.gotype GeneratedCode struct { Code dagql.ObjectResult[*Directory] field:true doc:The directory containing the generated code. VCSGeneratedPaths []string field:true name:vcsGeneratedPaths doc:List of paths to mark generated in version control (i.e. .gitattributes). VCSIgnoredPaths []string field:true name:vcsIgnoredPaths doc:List of paths to ignore in version control (i.e. .gitignore). }一个GeneratedCode对象由三部分组成组成Go 字段TypeScript 方法含义生成代码目录Codecode()包含生成代码的Directory标记为生成物的路径VCSGeneratedPathsvcsGeneratedPaths()/withVCSGeneratedPaths()会写入.gitattributeslinguist-generated应被忽略的路径VCSIgnoredPathsvcsIgnoredPaths()/withVCSIgnoredPaths()会写入.gitignore也就是说它不只是一堆生成文件还携带了这些文件在版本控制中应该如何被看待的元信息。2. 类继承与构造函数GeneratedCode继承自BaseClient即所有 Dagger TypeScript API 对象的公共基类构造函数签名为constructor(ctx?: Context, _id?: ID)其中ctx?: Context——当前 GraphQL 客户端上下文_id?: ID——可选的类型别名 ID用于直接由 ID 恢复对象避免重新发起查询。文档明确标注Constructor is used for internal usage only, do not create object from it——构造函数仅供 SDK 内部使用用户不应手动new GeneratedCode(...)。实际使用中GeneratedCode由Client.generatedCode(code: Directory)工厂方法创建该方法定义在 sdk/typescript/src/api/client.gen.ts引擎侧对应的解析器为moduleSchema.generatedCode见 core/schema/module.go它接收一个DirectoryID加载后调用core.NewGeneratedCode(dir)返回结果func (s *moduleSchema) generatedCode(ctx context.Context, _ *core.Query, args struct { Code core.DirectoryID }) (*core.GeneratedCode, error) { ... dir, err : args.Code.Load(ctx, dag) ... return core.NewGeneratedCode(dir), nil }3. 读取方法code()、id()、vcsGeneratedPaths()、vcsIgnoredPaths()3.1code(): Directory返回包含生成代码的目录对象 Directory。这是整个GeneratedCode的核心载荷——后续把它 export 出去、或在其上继续叠加文件操作如 runCodegen 中通过withNewFile追加.gitattributes/.gitignore都围绕这个目录进行。3.2id(): PromiseID返回该GeneratedCode的唯一标识符类型为 ID。对应引擎侧实现了完整的对象持久化协议EncodePersistedObject/DecodePersistedObject见 core/codegen.go持久化载荷persistedGeneratedCodePayload包含三项type persistedGeneratedCodePayload struct { CodeResultID uint64 json:codeResultID VCSGeneratedPaths []string json:vcsGeneratedPaths,omitempty VCSIgnoredPaths []string json:vcsIgnoredPaths,omitempty }因此在跨会话、跨引擎调用时GeneratedCode可以按 ID 完整还原CodeResultID指向缓存中的Directory结果。TypeScript 端做了惰性优化若构造时已持有_idid()直接返回而不发起 GraphQL 查询见 client.gen.ts。3.3vcsGeneratedPaths(): Promisestring[]返回需要在版本控制中标记为生成物的路径列表对应.gitattributes中的linguist-generated标记例如让 GitHub 的 Linguist 统计语言占比时忽略它们。3.4vcsIgnoredPaths(): Promisestring[]返回需要在版本控制中忽略的路径列表对应.gitignore条目例如生成的sdk/目录或dagger.gen.go等中间产物。这两个 Getter 都是惰性 GraphQL 查询this._ctx.select(vcsGeneratedPaths)后调用ctx.execute()仅在真正取值时才发起请求。4. 链式修改方法with()、withVCSGeneratedPaths()、withVCSIgnoredPaths()4.1with(arg: (param: GeneratedCode) GeneratedCode): GeneratedCode在 Dagger 各语言 SDK 中通用的组合器把当前对象传入回调返回回调结果用于在不打断调用链的前提下做复用与分组逻辑const genCode dag .generatedCode(codeDir) .with((g) g.withVCSGeneratedPaths([/sdk/client.gen.ts]))4.2withVCSGeneratedPaths(paths: string[]): GeneratedCode设置标记为生成物的路径列表返回新的GeneratedCode不可变风格原对象不变。引擎侧解析器见 core/schema/modulesource.go其内部实现为code.WithVCSGeneratedPaths(args.Paths)。4.3withVCSIgnoredPaths(paths: string[]): GeneratedCode设置忽略路径列表。值得特别注意的是引擎侧有一个自动增强行为见 core/codegen.gofunc (code *GeneratedCode) WithVCSIgnoredPaths(paths []string) *GeneratedCode { code code.Clone() code.VCSIgnoredPaths paths // if the paths does not have a .env file we need to add it if !slices.Contains(code.VCSIgnoredPaths, .env) { code.VCSIgnoredPaths append(code.VCSIgnoredPaths, .env) } return code }也就是说无论调用方传入什么列表.env都会被自动追加到忽略列表中除非已存在这是 Dagger 对敏感环境变量文件的强制保护策略。此外两个WithVCS*方法都遵循克隆再修改Clone()的不可变语义避免污染原对象。5. 底层原理VCS 路径如何落地到.gitattributes与.gitignoreGeneratedCode上的 VCS 元信息并不是摆设。在ModuleSource.codegen执行链路中引擎的runCodegen见 core/schema/modulesource.go会真正把它们写入生成的上下文目录写入.gitattributes当vcsGeneratedPaths非空时读取模块源子路径下已有的.gitattributes若不存在则以空内容开始并保证以换行结尾对每个路径去重检查bytes.Contains(gitAttrsContents, []byte(fileName))已存在对应配置则跳过去掉路径前导/后追加一行/fileName linguist-generated通过withNewFile把新.gitattributes写回生成目录权限0o600。写入.gitignore当vcsIgnoredPaths非空且未关闭时是否写入受模块CodegenConfig.AutomaticGitignore开关控制默认true若模块配置文件名是dagger.json即 TOML 模块构建自已提交的生成文件会先从忽略列表中剔除与vcsGeneratedPaths重叠的路径——避免把本应提交的生成文件误忽略掉见 core/schema/modulesource.go 中的ignoresGeneratedPath过滤逻辑。6. 典型使用场景自定义 SDK 返回 GeneratedCode在集成测试数据中可以看到一个完整的自定义 SDK 示例core/integration/testdata/modules/go/config-include-exclude-coolsdk/coolsdk/main.gofunc (m *Coolsdk) Codegen(modSource *dagger.ModuleSource, introspectionJson *dagger.File) *dagger.GeneratedCode { // ... return dag.GeneratedCode( // directory containing the generated code ).WithVCSGeneratedPaths(...) }该Codegen方法返回*dagger.GeneratedCodeGo SDK 侧等价类型并可用WithVCSGeneratedPaths/WithVCSIgnoredPaths链式声明 VCS 规则。在引擎侧这个返回值会经由codeGeneratorModule.Codegen见 core/sdk/module_code_generator.go执行先为 SDK 模块作用域化源码、抓取 schema 内省 JSON再调用 SDK 模块上的codegen字段得到dagql.Result[*core.GeneratedCode]。随后引擎的runSDKCodegen与runCodegen依次消费generatedCode.Code、generatedCode.VCSGeneratedPaths、generatedCode.VCSIgnoredPaths完成生成目录的装配与 VCS 文件的写入。7. 实践要点与注意事项不要手动构造对象GeneratedCode构造函数仅供内部使用应通过Client.generatedCode(code: Directory)创建。不可变链式调用withVCSGeneratedPaths/withVCSIgnoredPaths返回新对象原对象不被修改多次调用以后者为准。.env强制忽略withVCSIgnoredPaths会自动追加.env无需也无法移除。路径格式VCS 路径以模块源子路径为基准写入.gitattributes时会自动去掉前导/同时会与已有条目去重重复配置不会二次追加。TOML 模块的特殊过滤基于dagger.json构建的模块其生成文件与忽略列表重叠时会以提交生成文件为准避免本地模块上下文丢失生成产物相关行为可对照 core/schema/modulesource.go 的过滤逻辑与 core/codegen.go 的自动追加逻辑。类型别名与关联类id()返回类型为 IDcode()返回 Directory可以继续使用Directory的 export / 文件操作能力将生成代码物化到宿主机。综上GeneratedCode是连接SDK 代码生成与模块仓库版本控制策略的关键枢纽一面承载生成产物目录一面承载.gitattributes/.gitignore规则最终由引擎的runCodegen统一落地保证 Dagger 模块的开发体验与仓库整洁度。【免费下载链接】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),仅供参考