ARTICLE DETAIL

资讯详情

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

Dagger TypeScript SDK 目录过滤指南:深入解析 DirectoryFilterOpts 与 Directory.filter()

Dagger TypeScript SDK 目录过滤指南:深入解析 DirectoryFilterOpts 与 Directory.filter() Dagger TypeScript SDK 目录过滤指南深入解析 DirectoryFilterOpts 与 Directory.filter()【免费下载链接】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 中Directory是构建、测试与交付流水线的核心数据模型之一而DirectoryFilterOpts是 TypeScript SDK 为Directory.filter()方法提供的选项类型用于按 glob 模式或 .gitignore 规则生成目录快照的子集。本文以dagger.io/daggerTypeScript SDK 在 v0.20 版本中导出的DirectoryFilterOpts类型别名为主体结合该仓库的 TypeScript 客户端生成源码、Go 运行时与核心 schema 实现系统讲解exclude、include、gitignore三个选项的含义、底层实现与优先级语义并给出可直接运行的实战示例帮助你精确控制进入构建上下文的文件集合。DirectoryFilterOpts一次看懂类型定义DirectoryFilterOpts是 Dagger TypeScript SDK 导出的类型别名其完整定义位于sdk/typescript/src/api/client.gen.tsexport type DirectoryFilterOpts { /** * If set, paths matching one of these glob patterns is excluded from the new snapshot. * Example: [node_modules/, .git*, .env] */ exclude?: string[] /** * If set, only paths matching one of these glob patterns is included in the new snapshot. * Example: (e.g., [app/, package.*]). */ include?: string[] /** * If set, apply .gitignore rules when filtering the directory. */ gitignore?: boolean }从类型结构看它本质上是一个全部字段均可选optional的纯数据对象被用作Directory.filter(opts?: DirectoryFilterOpts): Directory方法的唯一入参。三个字段的语义如下字段类型默认行为作用excludestring[]不排除任何路径命中任一 glob 模式的路径从新快照中移除includestring[]包含所有路径仅保留命中任一 glob 模式的路径gitignorebooleanfalse过滤时应用.gitignore规则对应地Go 运行时中也有完全一致的结构体DirectoryFilterOpts见 sdk/typescript/runtime/internal/dagger/dagger.gen.go字段为Exclude []string、Include []string、Gitignore bool其生成代码逐一通过querybuilder.IsZeroValue判断后作为可选参数附加到filter查询选择器上。这说明该类型别名是 SDK 各语言代码生成器统一产出的选项对象模式TypeScript 与 Go 的调用方式一一对应。Directory.filter()从哪里来、返回什么DirectoryFilterOpts只服务于Directory类上的一个方法。在 sdk/typescript/src/api/client.gen.ts 中其签名与 JSDoc 注释如下/** * Return a snapshot with some paths included or excluded * param opts.exclude If set, paths matching one of these glob patterns is excluded from the new snapshot. Example: [node_modules/, .git*, .env] * param opts.include If set, only paths matching one of these glob patterns is included in the new snapshot. Example: (e.g., [app/, package.*]). * param opts.gitignore If set, apply .gitignore rules when filtering the directory. */ filter (opts?: DirectoryFilterOpts): Directory { const ctx this._ctx.select(filter, { ...opts }) return new Directory(ctx) }关键特性返回值仍是Directoryfilter()不会立即执行任何 I/O而是把filter选择器追加到惰性求值的查询上下文中返回一个新的Directory实例。因此它可以继续链式调用entries()、file()、dockerBuild()等方法直到真正触发执行如entries()、contents()等异步方法时引擎才落盘计算。opts 可省略不传任何选项时等价于什么都不过滤返回原目录快照。惰性语义与 Dagger 整体设计一致Directory是快照的抽象句柄filter只是定义了一个新的快照变换最终由引擎缓存并执行。三个选项的语义详解与实战exclude剔除不需要的路径exclude接收一组 glob 模式命中任一模式的路径会被从新快照中排除。文档中给出的典型示例是排除依赖目录、隐藏文件与环境变量文件import { connect } from dagger.io/dagger const filtered client.host().directory(.) .filter({ exclude: [node_modules/, .git*, .env], })在上述示例中node_modules/目录后缀带/表示匹配该目录及其整棵子树.git*匹配.git、.gitignore、.gitattributes等以.git开头的隐藏条目.env精确匹配环境变量文件本身。从实现上看exclude既可命中文件也可命中目录仓库集成测试 core/integration/directory_test.go 中的TestDirectoryFilterIncludeExclude验证了Exclude: [subdir]可以整体剔除一个子目录也验证了Exclude: [*.rar]可以按后缀过滤散落在各层级的文件。include白名单式保留include接收一组 glob 模式只有命中任一模式的路径会被保留其余全部丢弃。文档示例const filtered client.host().directory(.) .filter({ include: [app/, package.*], })该示例只保留app/目录与package.json、package-lock.json这类以package.开头的文件非常适合在打包场景下构造最小构建上下文。测试同样验证了 include 的匹配行为对一个包含a.txt、b.txt、c.txt.rar及subdir/的目录执行Include: [*.rar]最终entries()只返回[c.txt.rar]。gitignore复用仓库忽略规则gitignore是一个布尔开关。置为true时Dagger 会在过滤时应用目标目录内的.gitignore规则const filtered client.host().directory(.) .filter({ gitignore: true })测试用例构造了内容为b.txt\nsubdir/\n的.gitignore文件后调用Filter(dagger.DirectoryFilterOpts{Gitignore: true})结果中b.txt与subdir/被剔除而.gitignore自身、a.txt、c.txt.rar得以保留——即.gitignore不会忽略自己。gitignore适合直接接住仓库既有的忽略配置避免在流水线里重复维护一套 glob 白名单。它也可以与exclude、include组合使用组合优先级见下一节。include 与 exclude 的优先级语义由测试确认当include与exclude同时出现时二者并非简单的取并集。仓库集成测试TestDirectoryFilterIncludeExclude明确验证了如下规则exclude 优先于 includeInclude: [*.txt]且Exclude: [b.txt]时结果为[a.txt]反过来Include: [a.txt]且Exclude: [*.txt]时结果为[]。即先按 include 做白名单收缩再按 exclude 做黑名单剔除exclude 永远压过 include。过滤作用于目录的每一层对subdir执行filter({ exclude: [*.rar] })时其内部的d.txt、e.txt正常保留f.txt.rar被剔除说明模式匹配是递归、逐条目进行的。这一语义与底层CopyFilter的实现一致见下节在编写流水线时请牢记不要指望 include 能救回被 exclude 命中的路径。源码级实现从 GraphQL 选择器到 CopyFilter理解DirectoryFilterOpts的底层机制可以沿两条路径追溯路径一TypeScript → Go 运行时filter (opts?) this._ctx.select(filter, { ...opts })生成一个名为filter的 GraphQL 选择器。在 Go 运行时 sdk/typescript/runtime/internal/dagger/dagger.gen.go 中对应生成方法为func (r *Directory) Filter(opts ...DirectoryFilterOpts) *Directory { q : r.query.Select(filter) // exclude 可选参数 if !querybuilder.IsZeroValue(opts[i].Exclude) { q q.Arg(exclude, opts[i].Exclude) } // include、gitignore 同理 return Directory{query: q} }未设置的选项通过零值判断被省略不会出现在 GraphQL 请求中。路径二引擎侧 schema 实现在 core/schema/directory.go 中filter选择器对应的参数类型FilterArgs直接内嵌core.CopyFilter其解析函数把三个参数原样转发给withDirectory选择器type FilterArgs struct { core.CopyFilter } func (s *directorySchema) filter(ctx context.Context, parent dagql.ObjectResult[*core.Directory], args FilterArgs) (inst dagql.ObjectResult[*core.Directory], err error) { // 内部等价于在 scratch 目录上执行 // withDirectory(path/, sourceparent, exclude..., include..., gitignore..., owner) ... }也就是说Directory.filter在引擎内部被降级实现为从空目录scratch复制父目录内容并应用复制过滤规则。而CopyFilter正是这套规则的数据结构定义于 core/directory.gotype CopyFilter struct { Exclude []string default:[] Include []string default:[] Gitignore bool default:false } func (cf *CopyFilter) IsEmpty() bool { return len(cf.Exclude) 0 len(cf.Include) 0 !cf.Gitignore }它同时被withDirectory、withDirectoryDockerfileCompat等目录复制操作的持久化状态复用见 core/directory.go 中persistedDirectoryWithDirectoryLazy等结构体的Filter CopyFilter字段并在 schema 的copyFilterInputs中被序列化为 GraphQL 输入。由此可以推断过滤规则随目录快照一起被持久化、参与内容寻址与缓存相同的exclude/include/gitignore组合在多个流水线节点中可被缓存命中IsEmpty()用于短路优化——没有任何过滤规则时跳过额外处理。完整实战示例为构建上下文瘦身下面是一个把过滤 构建串起来的端到端 TypeScript 示例可用于在 CI 中把仓库目录裁剪后再交给dockerBuildimport { connect } from dagger.io/dagger connect(async (client) { // 1. 读取仓库目录 const repo client.host().directory(.) // 2. 过滤先按 .gitignore 剔除再补一刀排除大目录 const buildCtx repo.filter({ gitignore: true, exclude: [dist/, coverage/, *.tar.gz], }) // 3. 白名单收紧可选与 exclude 组合时 exclude 优先 const minimalCtx repo.filter({ include: [src/, Dockerfile, package.json, yarn.lock], }) // 4. 用过滤后的快照执行构建 const built buildCtx.dockerBuild().stdout() console.log(await built) })组合建议只想少带一点优先gitignore: true加少量exclude与仓库日常忽略规则保持一致需要严格白名单用include精确枚举同时留意exclude会压过include过滤后再挂载filter()返回的Directory也可作为withMountedDirectory、withDirectory的 source 参数用于把裁剪后的目录挂进容器从而减小上下文传输与缓存体积。小结与注意事项DirectoryFilterOpts是Directory.filter()的选项对象包含exclude、include、gitignore三个可选字段其类型定义与 JSDoc 见 sdk/typescript/src/api/client.gen.tsGo 侧对应结构体见 sdk/typescript/runtime/internal/dagger/dagger.gen.go。filter返回新的惰性Directory不会立即触发 IO它内部复用withDirectoryCopyFilter的复制过滤机制core/schema/directory.go、core/directory.go过滤规则参与快照持久化与缓存。优先级语义exclude 覆盖 include模式递归作用于各层目录由集成测试 core/integration/directory_test.go 的TestDirectoryFilterIncludeExclude逐条验证。实际匹配行为目录后缀/、通配符、.gitignore不忽略自身可直接参考上述测试用例在自定义 glob 前先跑一遍测试数据构造避免踩中模式语义的坑。【免费下载链接】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),仅供参考
返回列表