snapshot-checker
v0.1.4
Published
CLI 工具:按顺序执行 bat / mac / shell 命令
Downloads
316
Readme
snapshot-checker
按顺序执行 bat、mac、shell 命令的 CLI 工具。支持命令组:可为每组命名,用 --group 指定执行某一或多个组;不指定时默认执行当前系统支持的所有命令(按 defaultGroupOrder 顺序)。
命令类型
| kind | 说明 | 默认执行范围 |
|--------|------|----------------|
| bat | Windows 下用 cmd /c 执行 | 仅 Windows |
| mac | 面向 macOS 的命令 | 仅 macOS |
| shell| 通用 shell,使用当前系统默认 shell | 全平台 |
安装与运行
npm install
npm run build
npm start -- foo # 或: node dist/cli.js foo开发时可直接用 tsx 跑(无需 build):
npm run dev -- run
# 或
npm run run:example配置命令与组(commands 目录)
所有命令配置均放在项目根目录的 commands/ 目录中:
commands/*.ts:场景配置文件,例如foo.ts、bar.ts,通过snapshot-checker foo/snapshot-checker bar等命令使用
一个最简单的配置文件形如:
export const groups: Groups = {
env: [
{ kind: 'shell', description: '打印当前目录', run: 'pwd' },
{ kind: 'shell', description: 'Node 版本', run: 'node -v' },
],
list: [
{ kind: 'shell', description: '列出文件', run: 'ls -la' },
],
};
export const defaultGroupOrder: string[] = ['env', 'list'];- 不指定
--group时:按defaultGroupOrder依次执行各组,且只执行当前系统支持的命令(shell 全平台;bat 仅 Windows;mac 仅 macOS)。 - 指定
--group env list时:按给定顺序执行这些组内、且当前系统支持的命令。
每条命令可加 cwd 指定工作目录。
内置指令(embed)
除平台命令外,还支持内置指令(kind: 'embed'),由执行器内部实现,不依赖系统 shell。
sleep <seconds>
按指定秒数等待,例如:
{ kind: 'embed', run: 'sleep 3', description: '等待 3 秒' }timeout <seconds>(兼容 timieout <seconds>)
最多等待指定秒数,并实时显示剩余时间;在可交互终端下,用户按任意键可立即结束等待。
示例:
{
kind: 'embed',
run: 'timeout 30',
description: '最多等待 30 秒,按任意键跳过',
}行为说明:
- 使用同一行原地刷新倒计时(
[timeout] 剩余 Ns...)。 - 到达超时时间后自动继续后续命令。
- 若检测到键盘输入则立即结束等待并继续。
- 在非 TTY 环境(如某些 CI)中会退化为仅按时间等待,不监听按键。
仓库内完整示例见 commands/timeout_demo.ts(npm run dev -- timeout_demo 或 node dist/cli.js timeout_demo)。
通用 lib 工具函数
推荐将通用逻辑放在 src/lib/ 下(例如 src/lib/foo.ts),在场景文件中直接调用这些函数:
import { buildTag, buildUserGreeting } from '../src/lib/foo.js';
{
kind: CommandKind.BuiltinFunction,
description: '调用 lib/foo 的工具函数写入变量',
func: (ctx) => {
const user = ctx.user ?? 'unknown';
ctx.builtinTag = buildTag('context_demo');
ctx.fromFoo = buildUserGreeting(user);
},
}仓库内完整示例见 commands/context_demo.ts。
命令之间传递变量(上下文)
命令执行器内置了一个简单的上下文对象,允许前一条命令将自己的输出写入变量,后续命令通过模板占位符引用这些变量。通过 CLI 跑场景时,该上下文在整个场景执行期间(含不同 group、不同块之间)同一份共享,因此可以把变量从 getUser 组传到 greet 组。仓库内示例见 commands/context_demo.ts。
- **写入变量:**在命令上增加
captureToVar元数据 - **读取变量:**在
run/file/args/cwd/description中使用{{varName}}占位符
示例:
// commands/example.ts
import type { Groups } from '../src/types.js';
export const groups: Groups = {
env: [
{
kind: 'shell',
description: '获取当前用户名',
run: 'whoami',
// 将整段 stdout 写入变量 user
// (比如 "alice"),供后续命令使用
// @ts-expect-error: 由执行器在运行时识别的扩展字段
captureToVar: {
name: 'user',
},
},
],
greet: [
{
kind: 'shell',
description: '使用上一条命令得到的用户名',
run: 'echo "hello, {{user}}"',
},
],
};
export const defaultGroupOrder = ['env', 'greet'];仅提取输出的一部分
如果需要从输出中提取一部分(比如只要第一行的数字),可以使用 pattern 和 groupIndex:
{
kind: 'shell',
description: '获取某个进程 pid',
run: 'pidof my-app',
// @ts-expect-error: 由执行器在运行时识别的扩展字段
captureToVar: {
name: 'pid',
pattern: '^(\\d+)', // 匹配第一行的数字
groupIndex: 1, // 取第 1 个捕获组
},
},
{
kind: 'shell',
description: '用 pid 做点事',
run: 'echo "pid is {{pid}}"',
}captureToVar 字段说明:
- name: 变量名(如
pid、user) - from: 可选,
"stdout"(默认)或"stderr",表示从哪个输出中取值 - pattern: 可选,正则表达式字符串;不传时使用整个输出(去掉首尾空白)
- groupIndex: 可选,指定要取的捕获组索引,默认
1
多场景配置示例:foo / bar
- 在
commands/config.ts中定义默认场景(供run使用) - 在
commands/foo.ts中定义foo场景:
// commands/foo.ts
export const groups: Groups = {
env: [
{ kind: 'shell', description: '[foo] 打印当前目录', run: 'pwd' },
{ kind: 'shell', description: '[foo] 显示 Node 版本', run: 'node -v' },
],
list: [{ kind: 'shell', description: '[foo] 列出当前目录', run: 'ls -la' }],
};
export const defaultGroupOrder: string[] = ['env', 'list'];- 在
commands/bar.ts中定义bar场景:
// commands/bar.ts
export const groups: Groups = {
env: [
{ kind: 'shell', description: '[bar] 打印当前目录', run: 'pwd' },
{ kind: 'shell', description: '[bar] 显示 Node 版本', run: 'node -v' },
],
list: [{ kind: 'shell', description: '[bar] 列出当前目录', run: 'ls -la' }],
extra: [{ kind: 'shell', description: '[bar] 额外命令示例', run: 'echo extra from bar' }],
};
export const defaultGroupOrder: string[] = ['env', 'extra', 'list'];CLI 会自动将 commands 目录下除 config.* 外的每个文件视为一个场景命令,文件名即子命令名:
commands/foo.ts→snapshot-checker foocommands/bar.ts→snapshot-checker bar
CLI 选项
--wait:所有前台命令跑完后,继续等待后台命令(background: true)自然退出再结束进程;不加则前台全部结束后会优雅结束这些后台子进程并立即退出 CLI。snapshot-checker <scene>— 使用commands/<scene>.ts中的配置执行命令,例如:snapshot-checker foo使用commands/foo.ts的groups与defaultGroupOrdersnapshot-checker bar使用commands/bar.ts的groups与defaultGroupOrdersnapshot-checker foo --list仅列出foo场景中的命令,不执行snapshot-checker bar --list仅列出bar场景中的命令,不执行
简单用例
# 使用 foo 场景(commands/foo.ts)执行命令
node dist/cli.js foo
# 仅查看 foo 场景中的命令(不执行)
node dist/cli.js foo --list
# 使用 bar 场景(commands/bar.ts)执行命令
node dist/cli.js bar --group env,extra
# 仅查看 bar 场景中的命令(不执行)
node dist/cli.js bar --list项目结构
src/
cli.ts # CLI 入口,负责解析参数并调用执行逻辑
runCommand.ts # 单条/多条命令执行(无 group 概念)
runGroups.ts # 组规格解析、分块、按组执行(含组间间隔)
executor.ts # 统一导出 runCommand + runGroups
types.ts # 类型定义
index.ts # 库导出(从 commands/config.ts 导出默认 groups)
commands/
foo.ts # foo 场景示例:自定义 groups/defaultGroupOrder
bar.ts # bar 场景示例:自定义 groups/defaultGroupOrder
demos/
consumer-app/ # 独立示例:npm install snapshot-checker 后的调用方式发布到 npm
npm login
npm run build # prepublishOnly 也会在 publish 时执行
npm publish若包名 snapshot-checker 已被占用,请在 package.json 中改为作用域包(如 @your-org/snapshot-checker)并相应更新下文导入路径。
作为库使用(npm install 之后)
安装:
npm install snapshot-checker在业务项目中调用运行接口(入口与源码中 src/index.ts 导出一致),并从一个或多个包内场景模块生成命令组(发布产物中为 dist/commands/*.js,通过 exports 暴露):
import { resolveScenario, runScenarioGroups } from 'snapshot-checker';
import * as contextDemo from 'snapshot-checker/commands/context_demo';
import * as forkall from 'snapshot-checker/commands/forkall';
const { groups, defaultGroupOrder } = resolveScenario(forkall, {
app: 'com.example.app',
eventPath: 'snapshot/hmb_forkall_report_image_failure',
mode: 'monitor',
});
await runScenarioGroups({ groups, defaultGroupOrder, stopOnError: true });也可在业务项目自建 commands/*.ts,仅使用 snapshot-checker 的执行 API(runScenarioGroups、getGroupChunks 等),不引用包内场景。
独立 Node 示例工程(依赖 registry 上的本包):见 demos/consumer-app/README.md。
在该示例目录中可直接运行:
cd demos/consumer-app
npm install
npm run context
npm run forkallLicense
MIT
