跳转到主要内容

保留契约,演进 CLI

拆分 Barn 命令树、应用编排与输出处理时,哪些行为必须保留。

Barn 已经使用 Cobra。2026-11-04 CLI 提案最值得保留的部分,是对命令语法、应用编排与外部行为的拆分。本文结合 2026-11-09 发布的 v1.1.0 源码整理这些设计;包结构拆分与较大范围的命令重组仍是提案,当前用法见 CLI 参考。

保留已有边界

cmd/barn/command_*.go 定义各命令族。每次执行都会新建 Cobra 命令树,避免参数值在多次调用间泄漏。处理函数收集 commandOutcome,由统一出口渲染文本或结构化结果;类型化错误保留退出码、原因、恢复建议以及可用的部分结果。Linux 生命周期、镜像校验和原生 Mac 行为继续由各领域包实现。

这些边界已经承载了几项重要契约:

契约 重构必须保留的行为
部署选择 BARN_HOME 下的一套 Linux 部署,以及 mac/ 子目录下的具名 Mac VM
配置来源 期望状态命令解析清单;启动、停止、状态与访问命令使用已应用状态
机器可读输出 既有字段和类型、JSON/YAML 一致性,以及失败时有用的部分结果
交互访问 真实终端文件描述符、子进程信号与远端退出码
帮助与补全 既有别名、局部参数、平台范围与离线补全

搬迁命令不能让无效清单悄悄回退到旧状态,不能把 init -o FILE 改作输出格式,也不能将 up、restart、reload、recreate 合并成一个动作。这些差异决定了命令读取哪份配置、可以修改哪些资源。

收敛展示参数的解析

当前 prepareOutput 在 Cobra 之前扫描展示参数,并通过 commandFlagValues 区分参数名和参数值。后续简化应让同一棵命令树驱动正常解析、帮助、补全与命令说明导出,同时保留一个范围受限的入口,为解析失败选择错误展示格式。

优先级应始终是 显式 CLI 值 → 选中的环境默认值 → 内置默认值,确定最终来源后再验证。Barn 1.0.0 已修复无效环境默认值阻断有效 CLI 覆盖的问题。重构还要保留显式布尔 false 和看起来像参数的值:-o --json 可能是在指定文件名,而远端 -- 分隔符之后的内容全部属于客机命令。

--json --help 继续输出文本帮助;裸 barn 在文本模式打印完整帮助,在结构化模式保留 actions[]。提案中的机器可读帮助 schema 应作为独立、显式的接口,从命令树生成。

区分结果与数据流

单次结果的 JSON/YAML 命令在 stdout 输出一个结果文档,进度、警告和诊断走 stderr。保留 .nodes、.results 等命令特有的结果结构;统一套上新的 data 对象会破坏已有自动化。

SSH 与持续跟随的日志需要流式路径,保留空参数、引用边界、第二个 --、取消与客机非零退出码。结构化模式的交互 SSH 将会话输出送到 stderr,最终报告送到 stdout;日志跟随则输出 NDJSON 或 YAML 文档流。渲染器不能把交互会话安全地缓存成普通结果对象,弃用提示也不能混入结构化 stdout。

先拆职责,再改行为

提案将职责分为三层:

层次 职责
cmd/barn 进程入口、信号与退出状态
拟新增的 internal/cli Cobra 树、参数验证、展示与输入输出流连接
应用编排与既有领域包 类型化请求和结果、生命周期、宿主网络、镜像与 Mac VM

按操作实际需要注入输入输出流、环境读取、确认器与运行器。领域服务保持独立于 Cobra,避免用通用分发器抹掉请求类型。确认与 SSH 必须全程使用注入的输入流;只设置 Cobra 输入流、其他位置仍读取全局 os.Stdin,会让测试与嵌入调用出现分歧。

提案希望将副作用移到验证完成之后。锁定的 Cobra 1.10.2 在必填参数与参数组校验之前调用 pre-run hook,因此这些 hook 只适合做规范化和检查。当前生命周期命令有意在部分配置检查前记录 begin 事件,让早期失败可追踪;改变这一顺序需要明确审计策略。新增 --dry-run 需要真正只读、与执行范围一致的规划器,不能调用修改逻辑后仅跳过最后一次写入。

确认、权限与执行是不同的事实。既有 network 和 hosts 命令可以成功返回 applied=false 的计划,自动化需要检查该字段或传入 --yes;确认不会绕过身份、归属或完整性检查。同样,status 可能协调中断后的运行记录,不能只凭命令名称像查询就认定它完全只读。

按实际进展修订提案

原提案既包含长期契约,也包含有日期边界的产品选择。截至 2026-11-09:

  • 1.0.0 已实现裸命令完整帮助、结构化 actions[]、适用销毁命令的确认别名,以及输出环境变量优先级修复。
  • CLI 仍位于 cmd/barn/。拟议的 internal/cli 提取、--format、image update 与 ssh-config show/install/uninstall 命令树尚未落地。
  • 1.1.0 已为适用的清单操作加入 --image/-I 与 --arch/-A 覆盖参数,统一了结果表格与终端实时进度表(在提示或报错前冻结已打印行),将终端输出收口为纯 ASCII 符号与 [DONE]/[FAILED]/[CANCELLED] 状态标签,将 barn purge 设为默认直接执行并提供 --ask 确认提示,同时将 YAML 解析升级到 go.yaml.in/yaml/v4。

后续行为调整需要独立决策与迁移说明。

逐步验证契约

先在命令行为和状态格式不变的前提下提取职责,再增加兼容入口,最后单独审阅默认值或选择范围的变化。旧、新程序应依次操作受控测试夹具;帮助、补全与无效输入测试除了检查输出,还应检查是否意外创建文件、启动子进程或访问网络。

回归范围包括 CLI/环境优先级、stdout/stderr 分离、部分失败、远端参数边界、真实 PTY 信号以及确认范围。复用 cli_test.go、output_test.go、remote_command_test.go 与 signal_test.go;测试搬入新包时,同步更新 CI 的包路径与构建目标。修改 VM 或宿主网络行为时,补充对应的物理宿主验收。

表格阅读