Help us shape the future of Go! Take the 2026 Go Developer Survey

workspace

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 37 Imported by: 0

Documentation

Overview

Package workspace 定义执行环境工具用的工作区:按路径读写文件、启动进程。 本机实现基于 os、os.Root 和真实 bash;SSH 实现经 SFTP 读写文件、在远端 bash 里运行命令;虚拟实现基于 go-bash 的内存文件系统和解释器。 路径都是工作区里的绝对路径;读取不限范围,WriteFile 等写入只能在工作区根目录之内,命令不受这个限制。 流式的 OpenFileReader、CreateFileWriter 和 CopyFile 还接受相对根目录的路径,写入也不限于根目录。

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrOutsideWorkspace 表示写操作的目标不在工作区根目录内。
	ErrOutsideWorkspace = errors.New("path is outside the workspace root")
	// ErrNotRegularFile 表示读取目标不是普通文件。
	ErrNotRegularFile = errors.New("path is not a regular file")
	// ErrTTYUnsupported 表示这个工作区不能在终端里运行命令。
	ErrTTYUnsupported = errors.New("this workspace does not support interactive commands")
	// ErrTTYInputUnsupported 表示向不在终端里运行的命令写终端输入。
	ErrTTYInputUnsupported = errors.New("this command is not running in a terminal")
	// ErrTTYStdinUnsupported 表示 TTY 命令的请求带了 Stdin;TTY 命令的输入只能经 Process.WriteTerminalInput 写入。
	ErrTTYStdinUnsupported = errors.New("interactive commands take input through the terminal, not Stdin")
)

Functions

func CopyDirectory

func CopyDirectory(ctx context.Context, source Workspace, sourcePath string,
	target Workspace, targetPath string, skippedNames []string) error

CopyDirectory 跨工作区复制完整目录。

func CopyFile

func CopyFile(ctx context.Context, source Workspace, sourcePath string, target Workspace, targetPath string) error

CopyFile 跨工作区流式复制普通文件并保留权限。

func GetFileText

func GetFileText(ctx context.Context, source Workspace, path string) (string, error)

GetFileText 分块读取文件全文并返回文本。

func QuoteShellWord

func QuoteShellWord(word string) string

QuoteShellWord 把文本编码为 bash 的单个参数。

Types

type AgentsInstructionFile

type AgentsInstructionFile struct {
	// Path 是这份 AGENTS.md 清理后的绝对路径。
	Path string
	// Text 是文件全文。
	Text string
}

AgentsInstructionFile 是从工作区读到的一份 AGENTS.md。

func GetFileAgentsInstructions

func GetFileAgentsInstructions(ctx context.Context, work Workspace, path string) ([]AgentsInstructionFile, error)

GetFileAgentsInstructions 按从工作区根目录到文件所在目录的顺序读取沿途的 AGENTS.md。

func GetWorkspaceAgentsInstructions

func GetWorkspaceAgentsInstructions(ctx context.Context, work Workspace) ([]AgentsInstructionFile, error)

GetWorkspaceAgentsInstructions 从工作区根目录往上找最近的 Git 根目录,按从 Git 根目录到工作区根目录的顺序读取沿途的 AGENTS.md。

type DirectoryEntry

type DirectoryEntry struct {
	Name        string
	IsDirectory bool
	IsFile      bool
}

DirectoryEntry 是目录中的一个直接子项。

type DirectoryFile

type DirectoryFile struct {
	// RelativePath 是相对遍历根目录的路径,用 / 分隔。
	RelativePath string
	// Mode 是跟随符号链接后的权限位。
	Mode        fs.FileMode
	IsDirectory bool
}

DirectoryFile 是 ListDirectoryFiles 收集到的一项。

func ListDirectoryFiles

func ListDirectoryFiles(ctx context.Context, source Workspace, root string, skippedNames []string) ([]DirectoryFile, error)

ListDirectoryFiles 遍历目录并按相对路径排序返回目录和普通文件。

type FileContent

type FileContent struct {
	Content []byte
	// Size 是文件报告的大小;/proc 等文件可能为 0。
	Size int64
	// EOF 这次读取是否已经读到文件末尾?
	EOF bool
}

FileContent 是 ReadFile 读到的一段内容。

type FileMetadata

type FileMetadata struct {
	IsDirectory bool
	// IsFile 是不是普通文件?
	IsFile     bool
	IsSymlink  bool
	Size       int64
	Mode       fs.FileMode
	ModifiedAt time.Time
}

FileMetadata 描述一个路径的类型、大小、权限位与修改时间。

type LocalWorkspaceOpt

type LocalWorkspaceOpt struct {
	// RootDirectory 是工作区根目录,必须是绝对路径。
	RootDirectory string
	// Environment 是执行命令用的环境变量,格式同 os.Environ;为 nil 时继承当前进程的环境。
	Environment []string
}

LocalWorkspaceOpt 保存本机工作区的根目录和命令环境变量。

func NewLocalWorkspaceOpt

func NewLocalWorkspaceOpt(rootDirectory string) *LocalWorkspaceOpt

NewLocalWorkspaceOpt 保存本机工作区根目录。

func (*LocalWorkspaceOpt) WithEnvironment

func (o *LocalWorkspaceOpt) WithEnvironment(environment []string) *LocalWorkspaceOpt

WithEnvironment 设置命令环境变量并返回本配置。

type Process

type Process interface {
	// Wait 等待命令结束并返回退出码;返回时输出已全部写入请求中的 Writer。被 Terminate 结束时退出码为 -1。
	Wait() (int, error)
	// Terminate 结束命令所在的整个进程组;没能确认结束时返回错误,可以重试;进程组已不存在时返回 nil。
	Terminate() error
	// WriteTerminalInput 把 data 原样写进 TTY 命令的终端,返回实际写入的字节数;
	// 非 TTY 命令返回 ErrTTYInputUnsupported,命令已结束时返回写入错误。
	WriteTerminalInput(data []byte) (int, error)
	// ResizeTerminal 修改 TTY 命令的终端行列数;非 TTY 命令返回 ErrTTYInputUnsupported,virtual 命令返回 ErrTTYUnsupported。
	ResizeTerminal(rows, cols uint16) error
	// Close 放手这条命令:关闭本地这一端,让 Wait 尽快返回。SSH 关闭命令的会话,不证明远端已停止,Wait 随后返回错误;
	// 本机和 virtual 等同于 Terminate。只在不能无限等待的收尾路径上、Terminate 失败之后调用。
	Close() error
}

Process 是 StartProcess 启动的一条命令。

type ProcessRequest

type ProcessRequest struct {
	// Command 是交给 bash -c 执行的命令文本。
	Command string
	// Directory 是命令的工作目录,绝对路径。
	Directory string
	// TTY 是否在终端里运行命令?在终端里运行时输出全部写入 Stdout。
	TTY bool
	// Rows、Cols 是 TTY 命令的初始终端行列数;为零时按 24×80。
	Rows, Cols uint16
	// Stdin 是非 TTY 命令的一次性输入,nil 时读到空输入;TTY 命令的输入用 Process.WriteTerminalInput,传 Stdin 返回错误。
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer
}

ProcessRequest 描述一条要启动的 bash 命令。

type SSHWorkspace

type SSHWorkspace interface {
	Workspace
	// Close 关闭当前连接;之后的调用返回 net.ErrClosed。可重复调用。
	Close() error
}

SSHWorkspace 是经 SSH 访问的远端工作区:文件操作走 SFTP,命令在 exec 会话中由远端 bash 执行; 连接在首次调用时建立,断开后由下一次调用重新建立。

func NewSSHWorkspace

func NewSSHWorkspace(opt *SSHWorkspaceOpt) (SSHWorkspace, error)

NewSSHWorkspace 校验根目录并解析 SSH 地址,保存工作区配置。

type SSHWorkspaceOpt

type SSHWorkspaceOpt struct {
	// RootDirectory 是远端工作区根目录的绝对路径。
	RootDirectory string
	// Address 是 [user@]host[:port];省略 user 时使用本机用户名,省略 port 时为 22。
	Address string
	// IdentityFile 是本机私钥路径,可为空。
	IdentityFile string
	// Telemetry 是遥测管道,用于连接建立、断开与保活失败的日志;nil 时使用全局兜底。
	Telemetry *telemetry.Telemetry
}

SSHWorkspaceOpt 是 SSH 工作区的远端根目录与连接参数。

func NewSSHWorkspaceOpt

func NewSSHWorkspaceOpt(rootDirectory, address, identityFile string) *SSHWorkspaceOpt

NewSSHWorkspaceOpt 保存远端根目录、地址和私钥路径。

type VirtualFile

type VirtualFile struct {
	// Content 是现成的文件内容。
	Content []byte
	// Load 在第一次读取时调用一次,返回文件内容。
	Load func(ctx context.Context) ([]byte, error)
}

VirtualFile 是虚拟工作区的一个初始文件。

type VirtualWorkspaceOpt

type VirtualWorkspaceOpt struct {
	// RootDirectory 是工作区在虚拟文件系统中的绝对路径,省略时为 /workspace。
	RootDirectory string
	// Files 是创建时写入的文件,键为绝对路径,父目录自动创建。
	Files map[string]*VirtualFile
}

VirtualWorkspaceOpt 保存虚拟工作区的根目录和初始文件。

func NewVirtualWorkspaceOpt

func NewVirtualWorkspaceOpt(rootDirectory string, files map[string]*VirtualFile) *VirtualWorkspaceOpt

NewVirtualWorkspaceOpt 保存虚拟根目录和初始文件列表。

type Workspace

type Workspace interface {
	// GetRootDirectory 返回工作区根目录的绝对路径,工具以它为相对路径的基准。
	GetRootDirectory() string
	// GetHomeDirectory 返回工作区所在机器上当前用户的主目录:本机是 serve 进程的用户(os.UserHomeDir),
	// SSH 是登录用户(SFTP 的初始目录,sftp.Client.Getwd);virtual 没有主目录,返回 errors.ErrUnsupported。
	GetHomeDirectory(ctx context.Context) (string, error)
	// ReadFile 跟随符号链接,从 offset 起读取最多 limit 字节,不足时读到文件末尾;目标不是普通文件时返回 ErrNotRegularFile。
	ReadFile(ctx context.Context, path string, offset int64, limit int) (*FileContent, error)
	// WriteFile 写入完整内容,父目录须已存在;目标在工作区外时返回 ErrOutsideWorkspace;
	// createOnly 且目标已存在时返回满足 fs.ErrExist 的错误。
	WriteFile(ctx context.Context, path string, content []byte, mode fs.FileMode, createOnly bool) error
	// OpenFileReader 打开文件顺序读取,跟随符号链接,不限于工作区根目录;path 为相对根目录的路径或绝对路径。
	// 文件不存在时返回满足 fs.ErrNotExist 的错误;读完由调用方 Close。ctx 只约束打开。
	OpenFileReader(ctx context.Context, path string) (io.ReadCloser, error)
	// CreateFileWriter 创建或覆盖一个文件并返回写入端,权限位为 mode(不受 umask 影响);
	// path 为相对根目录的路径或绝对路径,可以在根目录外;父目录不存在时创建;Close 返回 nil 才算写完。ctx 只约束创建。
	CreateFileWriter(ctx context.Context, path string, mode fs.FileMode) (io.WriteCloser, error)
	// GetMetadata 返回路径的元数据;followSymlinks 为 false 时描述符号链接本身;不存在时返回满足 fs.ErrNotExist 的错误。
	GetMetadata(ctx context.Context, path string, followSymlinks bool) (*FileMetadata, error)
	// ReadDirectory 按名称顺序返回目录的直接子项,不跟随符号链接。
	ReadDirectory(ctx context.Context, path string) ([]*DirectoryEntry, error)
	// CreateDirectory 递归创建工作区内的目录,已存在时成功。
	CreateDirectory(ctx context.Context, path string) error
	// Remove 删除工作区内的一个文件或空目录。
	Remove(ctx context.Context, path string) error
	// StartProcess 在 request.Directory 启动一条 bash 命令;ctx 只约束启动,结束命令使用 Process.Terminate。
	// request.Stdin 非 nil 时,调用方不再写入后要关闭它的写端,命令才能结束读取。
	StartProcess(ctx context.Context, request *ProcessRequest) (Process, error)
	// Dial 从工作区所在的机器建立一条网络连接:本机直接连;SSH 经这条 SSH 连接转发,由远端发起,
	// 地址也在远端解析;virtual 返回 errors.ErrUnsupported。
	Dial(ctx context.Context, network, address string) (net.Conn, error)
	// GetHTTPProxy 返回从工作区所在机器发出 HTTP 请求时要经过的代理,签名同 http.Transport.Proxy:
	// 本机按 serve 进程的 HTTPS_PROXY、HTTP_PROXY、NO_PROXY(http.ProxyFromEnvironment);
	// SSH 拿不到远端 shell 的代理设置,返回 nil 表示直连;virtual 返回 nil。
	GetHTTPProxy(request *http.Request) (*url.URL, error)
}

Workspace 是一个 Executor 的工作区,工具按路径读写文件、启动命令;实现可被多个工具并发调用。

func NewLocalWorkspace

func NewLocalWorkspace(opt *LocalWorkspaceOpt) (Workspace, error)

NewLocalWorkspace 校验并保存本机工作区配置。

func NewVirtualWorkspace

func NewVirtualWorkspace(opt *VirtualWorkspaceOpt) (Workspace, error)

NewVirtualWorkspace 创建内存工作区及初始文件。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL