Documentation
¶
Overview ¶
Package envfile 解析 handoff 的 env 文件,并把它换算成可注入子进程的环境变量。
职责:
- Parse:把 dotenv 形态的文本解析为有序 KV,值支持单层 $VAR/${VAR} 展开
- Resolver(resolver.go):按 agent 名定位 <DataDir>/env/<文件名>,读盘并 返回 KEY=VALUE 切片
边界:
- 不是 shell:不做命令替换、不支持多行值、不支持行内注释(理由见 Parse 注释)
- 不管密钥:不加密、不接 secret 后端;值一律不进日志(本包只在 Resolver 里 打 key 名)
- 不启动进程:注入由各 adapter 自行完成(经 executor.StartReq.Env)
resolver.go —— env 文件的定位、读盘与日志。
职责:
- Dir:收口 <DataDir>/env 的目录布局知识,避免各调用方自己拼路径后漂移
- Resolver.For:按 agent 名解析出可注入的 KEY=VALUE 切片
- Resolver.Preflight:agentd 启动时把坏文件暴露在启动日志里
边界:
- 不解析语法(交 Parse)、不注入进程(交各 adapter)、不缓存(见 For 注释)
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type KV ¶
KV 是一条解析结果,按文件内首次出现的顺序排列。
func Parse ¶
Parse 解析 env 文件内容。
参数:
- r: 文件内容
- lookup: 展开时的外部变量查找(生产传 os.LookupEnv);nil 表示外部无变量
返回:
- kvs: 按首次出现顺序排列的键值对(重复键后者覆盖前者的值,位置保持在首次出现处)
- dups: 出现过重复定义的键名,供调用方打 WARN(本函数是纯函数,不打日志)
- err: 语法错误(带行号与原行)或超出大小上限
语法(完整规则见 spec §3):
- 行尾 \r 先剥离(兼容 CRLF);trim 后的空行与 # 开头行跳过
- 可选 `export ` 前缀;第一个 = 分割;key 须匹配 keyRe
- 值 trim 后:'...' 字面量不展开,"..." 与无引号都展开
为什么不支持行内注释:`HTTPS_PROXY=http://host/a#b` 里 # 是合法字符,支持行内 注释会把这类值静默吃掉半截——症状是「代理配了但连不上」,离根因隔了十万八千里。
为什么展开时文件内的键优先于外部环境:让文件自洽,读文件的人不必脑补外部环境 是什么。查不到的变量展开为空串(os.Expand 的默认行为)。
type Resolver ¶
type Resolver struct {
// contains filtered or unexported fields
}
Resolver 按 agent 名把配置里的文件名换算成可注入的环境变量。
无状态:每次 For 都重新读盘,因此多个实例之间不会发散(见 For 的热更新说明)。
func NewResolver ¶
NewResolver 构造 Resolver。
参数:
- dir: env 文件目录,通常取 Dir(cfg.DataDir)
- m: agent 名 → 文件名映射(取自 config 的 env 段);nil 视为空映射
- log: 日志入口;nil 时退回 slog.Default()
func (*Resolver) For ¶
For 返回该 agent 启动时应注入的环境变量(KEY=VALUE 形式)。
参数:
- agent: executor 名(如 opencode)
返回:
- 该 agent 未配置 env 文件时返回 (nil, nil)——不是错误,是「没配」
- 文件名非法 / 打不开 / 解析失败时返回错误,错误文本带完整路径与行号
注意:
- 每次调用都重新读盘,不缓存。改了代理下一个任务就生效,不必重启 agentd (重启会打断正在跑的任务的事件订阅,代价不小);读一个几百字节的文件 相对于拉起一个 agent 的开销可以忽略
- 日志只打 key 名,绝不打值:环境类变量里 HTTPS_PROXY=http://user:pass@host 是正常写法,值里带凭据的概率不低
Click to show internal directories.
Click to hide internal directories.