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

资讯详情

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

Dagger TypeScript SDK 中的 DirectoryStatOpts 详解:Directory.stat() 与 doNotFollowSymlinks 符号链接处理实战

Dagger TypeScript SDK 中的 DirectoryStatOpts 详解:Directory.stat() 与 doNotFollowSymlinks 符号链接处理实战 Dagger TypeScript SDK 中的 DirectoryStatOpts 详解Directory.stat() 与 doNotFollowSymlinks 符号链接处理实战【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/daggerDirectoryStatOpts是 Dagger TypeScript SDKdagger.io/dagger为Directory.stat()方法定义的可选参数类型别名用于控制目录/文件状态查询时的符号链接行为。本文以 Dagger v0.20 版本 API 参考文档为主体结合 TypeScript SDK 生成代码sdk/typescript/src/api/client.gen.ts与 Go 引擎层实现core/directory.go、core/schema/directory.go系统讲解该类型别名的定义、Directory.stat()的调用方式、doNotFollowSymlinks的底层原理并给出可直接运行的实战示例。读完本文你将掌握如何在 Dagger 管道中精确地探测路径状态、识别符号链接并理解引擎层os.Stat/os.Lstat的选择逻辑。DirectoryStatOpts 类型别名定义在 Dagger v0.20 的 TypeScript SDK 中DirectoryStatOpts位于api/client.gen模块其完整定义如下export type DirectoryStatOpts { /** * If specified, do not follow symlinks. */ doNotFollowSymlinks?: boolean }该定义可直接在 SDK 生成源码 sdk/typescript/src/api/client.gen.ts#L1457-L1462 中验证。它对应 Dagger 引擎 GraphQL Schema 中stat字段的可选参数相关 Schema 文档见 core/schema/testdata/base_schema.graphqlsdoNotFollowSymlinks: Boolean false。属性说明属性类型可选说明doNotFollowSymlinksboolean是optional如果指定为true则不跟随符号链接symlink直接返回符号链接自身的信息。该选项的语义与 POSIXlstat()一致默认情况下不传该选项或传false对路径执行的是stat()语义跟随符号链接设置为true后则执行lstat()语义不跟随符号链接。在 GraphQL Schema 层该参数的默认值为false见 core/schema/directory.go 中statArgs结构的DoNotFollowSymlinks bool \default:false 定义。Directory.stat() 方法DirectoryStatOpts 的唯一消费方DirectoryStatOpts是Directory类中stat方法的可选参数类型。在 TypeScript SDK 中其方法签名如下sdk/typescript/src/api/client.gen.ts#L7103-L7120/** * Return file status * param path Path to stat (e.g., /file.txt). * param opts.doNotFollowSymlinks If specified, do not follow symlinks. */ stat async ( path: string, opts?: DirectoryStatOpts, ): PromiseStat | null { const ctx this._ctx.select(stat, { path, ...opts }).select(id) const response: Awaitedstring | null await ctx.execute() if (response null) { return null } return new Stat(ctx.copy().selectNode(response, Stat)) }从源码可以看出三个关键点path为必填字符串表示要查询状态的路径文档示例为/file.txtopts可选类型即为DirectoryStatOpts展开后与path一并作为 GraphQL 查询参数下发返回值是Stat | null当目标路径不存在时返回null否则返回封装好的Stat对象。在 GraphQL 层对应的 schema 定义位于 core/schema/directory.go#L142-L147dagql.NodeFunc(stat, s.stat). Doc(Return file status). Args( dagql.Arg(path).Doc(Path to stat (e.g., /file.txt).), dagql.Arg(doNotFollowSymlinks).Doc(If specified, do not follow symlinks.), ),引擎层实现在 core/schema/directory.go#L1133-L1144将参数透传给core.Directory.Stat。doNotFollowSymlinks 的底层原理os.Stat 与 os.Lstat 的切换理解doNotFollowSymlinks的行为需要深入引擎层的实现。在 core/directory.go#L3439-L3500 中Directory.Stat的核心逻辑如下osStatFunc : os.Stat rootPathFunc : containerdfs.RootPath if doNotFollowSymlinks { // symlink testing requires the Lstat call, which does NOT follow symlinks osStatFunc os.Lstat // similarly, containerdfs.RootPath cant be used, since it follows symlinks rootPathFunc RootPathWithoutFinalSymlink }这段代码揭示了两个层面的行为差异1. 系统调用层面的切换默认doNotFollowSymlinksfalse使用os.Stat跟随符号链接返回的是符号链接指向的目标的信息开启doNotFollowSymlinkstrue使用os.Lstat不跟随符号链接返回的是符号链接本身的信息此时Stat.FileType会识别为SYMLINK_TYPE。2. 路径解析层面的切换除了系统调用本身路径解析也做了对应调整。containerdfs.RootPath会跟随符号链接解析容器路径而开启该选项后引擎改用 core/util.go#L320-L333 中定义的RootPathWithoutFinalSymlink// RootPathWithoutFinalSymlink joins a path with a root, evaluating and bounding all // symlinks except the final component of the path (i.e. the basename component). // This is useful for the case where one needs to reference a symlink rather than // following it (e.g. deleting a symlink) func RootPathWithoutFinalSymlink(root, containerPath string) (string, error) { linkDir, linkBasename : filepath.Split(containerPath) resolvedLinkDir, err : containerdfs.RootPath(root, linkDir) if err ! nil { return , err } return path.Join(resolvedLinkDir, linkBasename), nil }该函数会解析路径中除最后一段basename之外的所有符号链接但保留最后一层不解析——这正是为了能够对符号链接本身执行lstat。同时它会校验路径边界若中间段符号链接指向根目录之外则返回错误从而保证容器文件系统的隔离性。3. 路径不存在时的行为当目标路径不存在时Stat返回nullTypeScript 层或os.PathError{Op: stat, Path: targetPath, Err: syscall.ENOENT}引擎层详见 core/directory.go#L3440-L3442 与 core/directory.go#L3475-L3477。stat 的返回值Stat 对象与 FileType 枚举Directory.stat()返回的Stat对象在 TypeScript SDK 中定义于 sdk/typescript/src/api/client.gen.ts#L15325-L15333其字段包括字段类型含义idIDStat 对象的唯一标识fileTypeFileType文件类型枚举namestring文件名permissionsnumber权限位POSIX 权限sizenumber文件大小字节其中fileType对应的FileType枚举包含以下成员见 docs/versioned_docs/version-0.20/reference/typescript/api/client.gen/enumerations/FileType.mdDirectoryType目录、RegularType普通文件、SymlinkType符号链接、Unknown未知类型。引擎层对这些类型的判定逻辑在 core/directory.go#L3481-L3497m : fileInfo.Mode() stat : Stat{ Size: int(fileInfo.Size()), Name: fileInfo.Name(), Permissions: int(fileInfo.Mode().Perm()), } if m.IsDir() { stat.FileType FileTypeDirectory } else if m.IsRegular() { stat.FileType FileTypeRegular } else if mfs.ModeSymlink ! 0 { stat.FileType FileTypeSymlink } else { stat.FileType FileTypeUnknown }结合doNotFollowSymlinks的语义即可得出一个实用结论只有在开启doNotFollowSymlinks时路径为符号链接的stat才会返回SymlinkType默认情况下返回的是链接目标如目标目录则为DirectoryType的信息。实战示例在 TypeScript 中探测符号链接下面给出一个完整的 TypeScript 使用示例演示DirectoryStatOpts的两种用法import { connect } from dagger.io/dagger connect(async (client) { // 读取宿主目录作为 Dagger Directory 对象 const dir client.host().directory(.) // 用法一默认查询跟随符号链接 const statFollowed await dir.stat(/link-to-dir) // 用法二开启 doNotFollowSymlinks不跟随符号链接 const statRaw await dir.stat(/link-to-dir, { doNotFollowSymlinks: true, }) if (statRaw null) { console.log(path does not exist) } else { console.log(raw fileType:, statRaw.fileType) // 若 /link-to-dir 是符号链接此处为 SymlinkType console.log(size:, statRaw.size) console.log(permissions:, statRaw.permissions) console.log(name:, statRaw.name) } })要点若/link-to-dir是指向目录的符号链接statFollowed的fileType为DirectoryType而statRaw的fileType为SymlinkType若路径不存在两者都返回nullopts参数可省略等价于传入{ doNotFollowSymlinks: false }。在 Go 模块Dagger Go SDK 生成代码中同样的选项定义于 sdk/typescript/runtime/internal/dagger/dagger.gen.go#L4760-L4767// DirectoryStatOpts contains options for Directory.Stat type DirectoryStatOpts struct { DoNotFollowSymlinks bool } func (r *Directory) Stat(path string, opts ...DirectoryStatOpts) *Stat相关 APIexists() 与 Container.stat() 的同名选项doNotFollowSymlinks并非DirectoryStatOpts独有理解它的使用范围有助于避免混淆Directory.exists()同样接收doNotFollowSymlinks参数见 core/directory.go#L3367-L3368并且当targetType ExistsTypeSymlink时引擎会强制以不跟随符号链接方式调用Stat来判定路径是否为符号链接stat, err : dir.Stat(ctx, self, srv, targetPath, doNotFollowSymlinks || targetType ExistsTypeSymlink)这意味着即使调用方未显式设置该选项只要指定了期望类型为符号链接引擎也会自动采用lstat语义。对应的 TypeScript 类型别名为DirectoryExistsOpts可参考 docs/versioned_docs/version-0.20/reference/typescript/api/client.gen/type-aliases/DirectoryExistsOpts.md。Container.stat()容器内的路径状态查询同样支持doNotFollowSymlinks选项ContainerStatOptsSchema 定义见 core/schema/container.go#L610-L620TypeScript 类型别名文档为 docs/versioned_docs/version-0.20/reference/typescript/api/client.gen/type-aliases/ContainerStatOpts.md。使用建议与注意事项判断路径是否是符号链接时必须开启doNotFollowSymlinks否则stat会跟随链接返回目标信息fileType无法反映链接本身的类型路径不存在时返回null调用前无需先用exists()判断直接判空即可路径为空字符串会被引擎直接拒绝并返回ENOENT见 core/directory.go#L3440-L3442传参时应避免空路径该选项默认值为false在 GraphQL Schema 中显式声明doNotFollowSymlinks: Boolean falseTypeScript 侧为可选字段可省略不传该选项同时存在于Directory与Container两类对象的stat/exists方法中语义一致可交叉参考。小结DirectoryStatOpts是 Dagger TypeScript SDK 中一个轻量但语义精确的选项类型仅含doNotFollowSymlinks一个布尔字段却串联起从 TypeScript API 层、GraphQL Schema 层到 Go 引擎层的完整符号链接处理链路os.Stat/os.Lstat切换与RootPathWithoutFinalSymlink路径边界校验。在实际管道开发中无论是判断挂载目录中是否存在符号链接、还是精确获取链接目标的元数据掌握该选项都能让你的状态探测逻辑更加严谨可控。参考资源关联 API 文档DirectoryStatOpts 类型别名SDK 生成源码sdk/typescript/src/api/client.gen.ts引擎实现core/directory.go、core/util.goSchema 定义core/schema/directory.go、core/schema/testdata/base_schema.graphqlsTypeScript SDK 总览docs/versioned_docs/version-0.20/reference/typescript/README.md【免费下载链接】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),仅供参考
返回列表