从零构建系统工具:先写验收脚本,再补漂亮交互
从零构建系统工具:先写验收脚本,再补漂亮交互
一、系统工具先证明能解决问题
从零构建系统级工具时,很容易先做漂亮命令行界面、彩色输出和交互提示。这些体验很重要,但第一阶段更重要的是证明工具真的解决问题。能否稳定输入、执行、输出、失败可解释,才是基础。
验收脚本能帮助工具保持方向。每新增一个能力,都用脚本验证输入、输出、退出码和错误路径。工具还小的时候建立验收习惯,后面会省很多返工。
二、验收脚本定义最小闭环
flowchart TD A[命令输入] --> B[执行工具] B --> C[检查退出码] C --> D[检查输出] D --> E[检查副作用]系统工具通常会读写文件、调用命令或访问网络。验收脚本要确认副作用是否符合预期,比如是否生成目标文件,是否没有修改不该修改的目录。
漂亮交互可以后加,但命令契约要早定。参数、退出码、stdout、stderr、配置文件位置,这些都是用户和脚本依赖的接口。
三、脚本要覆盖失败路径
#!/usr/bin/env bash set -euo pipefail cargo run -- check ./examples/ok.toml if cargo run -- check ./examples/bad.toml; then echo "bad config should fail" exit 1 fi失败路径比成功路径更能检验工具质量。配置错误、文件不存在、权限不足、网络超时,都应有明确错误信息和非 0 退出码。
stdout: 给机器消费的结果 stderr: 给人看的诊断信息 exit code: 给脚本判断成功失败这三个通道不要混乱。CLI 工具如果把错误写到 stdout,会让管道和脚本很难处理。
四、交互体验建立在契约之上
彩色输出、进度条、提示语都可以提升体验,但它们不应破坏脚本使用。可以提供--json或--plain模式,让自动化场景稳定读取。
还要保持默认安静。工具成功时输出关键结果,失败时输出足够诊断。不要为了显得热闹,把每一步都打印出来。系统工具越稳定,越不需要吵。
验收脚本还要固定测试目录。不要在真实项目根目录里随便生成文件,可以使用临时目录,测试结束后清理。这样脚本能反复运行,不会污染工作区。
如果工具会调用外部命令,应在验收脚本里模拟失败。比如 Git 不存在、配置文件缺失、权限不足。成功路径只能证明工具会跑,失败路径才能证明工具可靠。
输出格式也要纳入验收。人类模式可以有颜色,机器模式必须稳定。--json输出字段一旦发布,就要按兼容协议维护。系统工具经常被脚本调用,输出就是 API。
最后,验收脚本应进入 CI。每次修改都跑最小闭环,避免漂亮交互改坏核心能力。工具变复杂前,先让回归保护站好。
验收脚本还要覆盖升级路径。旧配置、旧缓存、旧输出文件在新版本下能否读取,关系到真实用户体验。系统工具一旦被脚本依赖,破坏兼容会让用户很难升级。
可以把验收用例写成 fixtures。输入文件、期望输出、期望退出码放在同一目录,新增场景时只加样例。这样比把所有逻辑写死在 shell 里更容易维护。
对网络相关功能,要准备 mock 服务。真实外部服务会抖动,CI 中不应依赖它。mock 可以固定返回超时、限流和成功结果,覆盖更多错误路径。
最后,交互体验也可以验收。比如--help是否包含关键选项,错误提示是否包含修复建议。系统工具的可用性,不只来自核心算法。
一个小经验:验收脚本里加上timeout命令。如果工具默认不设超时,验收脚本可以兜底。比如timeout 10 cargo run -- check bad.toml || echo "timeout as expected"。工具还在快速迭代时,超时保护比完美体验更优先。
五、总结
从零构建系统工具时,先写验收脚本,验证输入、输出、退出码和失败路径,再逐步补交互体验。
漂亮界面会加分,但稳定契约才是工具能被长期使用的原因。