Dagger TypeScript API 参考:ContainerDirectoryOpts 类型别名与 expand 环境变量展开机制
2026/9/16 20:09:00 网站建设 项目流程

Dagger TypeScript API 参考:ContainerDirectoryOpts 类型别名与 expand 环境变量展开机制

【免费下载链接】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 v0.20 TypeScript SDK 的 API 参考文档 ContainerDirectoryOpts.md,完整解析ContainerDirectoryOpts类型别名的唯一属性expand的语义、默认值与取值行为,并结合Container.directory()方法签名、引擎侧expandEnvVar实现与集成测试用例,说明"按容器环境变量展开路径"这一能力在 Dagger 中的底层原理与可复制用法。读完后可掌握:何时应显式传入expand、展开规则(${VAR}$VAR两种形式)、以及对 Secret/Volatile 环境变量的硬性限制。

1. 类型定义:ContainerDirectoryOpts 是什么

原始参考文档定义了@dagger.io/dagger(即api/client.gen)模块下的类型别名:

ContainerDirectoryOpts=object

该对象是Container.directory()方法的可选参数(opts)类型,用于控制"从容器根文件系统取回目录"这一操作对路径参数path的处理方式。文档列出的属性只有一项:

属性类型必填说明
expand?boolean否(optional)根据容器当前定义的环境变量,替换path中的"${VAR}"$VAR(例如"/$VAR/foo")

对应到仓库中 TypeScript SDK 的实际类型声明(自动生成代码),定义位于 client.gen.ts:

export type ContainerDirectoryOpts = { /** * Replace "${VAR}" or "$VAR" in the value of path according to the current * environment variables defined in the container (e.g. "/$VAR/foo"). */ expand?: boolean }

可以看出文档与实现完全一致:expand是唯一字段且为可选,未传入时引擎侧使用默认值false(见后文 Go schema 定义中的default:"false"标签),即默认不做任何展开,path原样使用。

2. 使用方:Container.directory() 方法签名

ContainerDirectoryOpts的唯一消费点是Container类上的directory方法,其签名(同样见 client.gen.ts)为:

/** * Retrieve a directory from the container's root filesystem * * Mounts are included. * @param path The path of the directory to retrieve (e.g., "./src"). * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according * to the current environment variables defined in the container (e.g. "/$VAR/foo"). */ directory = (path: string, opts?: ContainerDirectoryOpts): Directory => { const ctx = this._ctx.select("directory", { path, ...opts }) return new Directory(ctx) }

要点:

  • 返回值:同步返回一个Directory对象(惰性求值,后续调用.file(...).entries()等才真正执行查询),因此可以自然嵌入管道式链式调用;
  • 路径语义:从容器根文件系统取目录,且文档注释明确"Mounts are included"——已挂载的目录会包含在取回结果中;
  • 参数传递方式:SDK 通过this._ctx.select("directory", { path, ...opts })expand作为 GraphQL 查询的可选字段下发给引擎。

一个完整可运行的示例(与仓库集成测试中的场景一一对应,见 container_test.go):

import { dag } from "@dagger.io/dagger" const c = await dag() const contents = await c .container() .from("alpine:latest") .withEnvVariable("foo", "bar") .withDirectory( "/some-path/${foo}", // 目标路径同样支持展开 c.directory().withNewFile("/some-file.txt", "contents in foo file"), { expand: true } ) .directory("/some-path/${foo}", { expand: true }) // 取出 /some-path/bar .file("some-file.txt") .contents() console.log(contents) // "contents in foo file"

对照 Go SDK 的写法即ctr.Directory("/some-path/${foo}", dagger.ContainerDirectoryOpts{Expand: true}),语义与字段名一一对应(expandExpand)。

3. 引擎侧实现:expand 如何工作

在 Dagger 引擎(核心 schema 层),Container.directory对应的查询处理函数接收一个带Expand字段的参数结构体,其默认值为false,并立刻调用expandEnvVar处理路径,见 container.go:

Expand bool `default:"false"` ... path, err := expandEnvVar(ctx, parent.Self(), args.Path, args.Expand)

核心展开逻辑集中在 expandEnvVar:

func expandEnvVar(ctx context.Context, parent *core.Container, input string, expand bool) (string, error) { if !expand { return input, nil // 默认不展开,路径原样返回 } cfg, err := parent.ImageConfig(ctx) // 从容器镜像配置读取环境变量 ... secretEnvs := []string{} for _, secret := range parent.Secrets { secretEnvs = append(secretEnvs, secret.EnvName) } volatileEnvs := []string{} core.WalkEnv(parent.VolatileEnv, func(name, _, _ string) { volatileEnvs = append(volatileEnvs, name) }) expanded := os.Expand(input, func(k string) string { if slices.Contains(secretEnvs, k) { secretEnvFoundError = fmt.Errorf("expand cannot be used with secret env variable %q", k) return "" } if slices.Contains(volatileEnvs, k) { secretEnvFoundError = fmt.Errorf("expand cannot be used with volatile env variable %q", k) return "" } v, _ := core.LookupEnv(cfg.Env, k) return v }) ... }

从源码实现可以确认以下行为细节,这些是参考文档未展开、但对实际使用很关键的规则:

  1. expand: false(默认)时零开销:函数直接原样返回输入,不触发任何容器状态读取;
  2. 变量来源是容器的"已定义环境变量":实现通过parent.ImageConfig(ctx)读取镜像配置的Env,因此只有事先通过withEnvVariable/WithEnvVariable等 API 写入容器的变量才可能被展开,而不是宿主机或引擎的环境;
  3. 使用os.Expand语义:Go 的os.Expand同时支持${VAR}$VAR两种形式,与文档描述("Replace$\{VAR\}or$VAR")完全吻合;未定义的变量会被替换为空字符串;
  4. 硬性安全限制:expand不能用于引用 Secret 环境变量(WithMountedSecret注入的变量名)或 Volatile 环境变量,命中时直接报错expand cannot be used with secret/volatile env variable,防止敏感值被固化进路径字符串。

此外,通用入口 ExpandContainerInput 也承担了同样的"按容器环境变量展开输入字符串"职责,供需要展开的其他路径类输入复用。

4. 集成测试验证:expand 在目录 API 上的行为

仓库的集成测试对expand的目录场景做了直接验证,位于 container_test.go。其中两条用例与ContainerDirectoryOpts直接相关:

  • env variable is expanded in WithDirectory:先以Expand: true把目录写入/some-path/${foo}(展开为/some-path/bar),再以dagger.ContainerDirectoryOpts{Expand: true}"/some-path/${foo}"取回该目录,最终读出文件内容断言成功;
  • env variable is expanded in Directory:先用字面量路径/some-path/bar写入,再用ContainerDirectoryOpts{Expand: true}"/some-path/${foo}"取出,验证"取回目录"一侧的展开。

同文件还覆盖了WithFileFileWithMountedDirectoryWithoutDirectory等兄弟 API 的展开行为(如 L5341-L5419),说明expand是容器路径类 API 的通用能力族。

5. 同族类型:哪些 Opts 也带 expand

expand并非ContainerDirectoryOpts独有。在同一个 type-aliases 参考目录下,还有多个兄弟 Opts 类型提供相同的expand?属性,例如:

  • ContainerFileOpts.md —Container.file()的路径展开;
  • ContainerExistsOpts.md —Container.exists()的路径展开(该类型额外含expectedType?doNotFollowSymlinks?);
  • ContainerWithDirectoryOpts.md — 写入目录一侧的路径展开。

引擎侧也印证了这一点:在 core/schema/container.go 中,expandEnvVarWithFileWithDirectoryWithMountedFileFileWithoutDirectory等十余个查询处理函数复用,每次都以Expand bool \default:"false"`` 的形式出现,说明这是引擎对"容器内路径字符串"的统一处理约定。

6. 使用建议与适用前提

基于上述文档与源码证据,给出可操作的使用要点:

  1. 何时需要expand: true:当目标目录路径依赖容器内动态确定的值(如通过withEnvVariable设置的构建产物子目录)时,在directory()调用中传入{ expand: true };若路径是静态字面量,省略该参数即可,行为完全一致且避免不必要的状态读取;
  2. 两种变量写法都支持:"/builds/${BUILD_ID}""/builds/$BUILD_ID"均可,但建议统一使用花括号形式以避免相邻标识符造成的歧义;
  3. 不要依赖宿主环境:expand只解析容器自身ImageConfig中的环境变量,宿主机 shell 变量不会进入展开范围;
  4. 避免引用 Secret 变量:将 Secret 挂载为环境变量后,若路径字符串中出现同名变量,expand会直接报错而非静默替换,这是设计上的安全边界;
  5. 版本前提:本文基于 version-0.20 API 参考与当前仓库的 TypeScript SDK 生成代码(client.gen.ts);该类型由 Dagger 的 GraphQL schema 经 codegen 生成,后续版本中新增字段(若有)以对应版本的参考文档为准。

参考路径汇总

内容路径
原始 API 参考文档(本文主体)ContainerDirectoryOpts.md
TS SDK 类型与方法生成代码sdk/typescript/src/api/client.gen.ts
引擎侧目录查询与展开调用core/schema/container.go
展开核心实现expandEnvVar
通用展开入口core/container.go
集成测试验证core/integration/container_test.go

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询