cli-anything-rekordbox 评估流水线实战:从 Smoke 测试到 SQLCipher 数据库写入与虚拟 MIDI 实机验证
【免费下载链接】CLI-Anything"CLI-Anything: Making ALL Software Agent-Native" -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything
导读
本文围绕 eval/eval_pipeline.md 中定义的cli-anything-rekordbox评估流水线展开,系统讲解其三层验证体系:零依赖的 Smoke 测试、依赖 Rekordbox 6/7 的数据库手动集成验证、以及依赖虚拟 MIDI 端口的实机控制验证。读完本文,你将掌握每条评估命令的预期输出、其背后的源码实现与安全守卫机制(写前备份、运行中写入拒绝等),并能在自己的环境中复现整个验证流程,为后续开发与维护这一 Agent 原生 DJ 工具链建立可回归的验收基线。
为什么需要一个三层评估流水线
Pioneer 官方没有为 Rekordbox 提供公开的播放/控制 REST API,可编程化的真实入口只有两个:加密的 master.db 曲库数据库(SQLCipher 加密,由pyrekordbox直连)和虚拟 MIDI 控制面(由mido驱动的.midi.csv映射)。因此,rekordbox_cli.py 将两条通道统一封装进同一个 Click CLI,而评估流水线也天然划分为两个隔离的验证层次:
- Smoke 层:不依赖任何外部软件,只验证包导入、CLI 解析和写入守卫逻辑;
- 集成层:又细分为"数据库手动集成"(需要 Rekordbox 6/7 真实安装与 master.db)和"MIDI 实机集成"(需要虚拟 MIDI 端口、Rekordbox 前台运行且映射已启用)。
这种分层设计的好处在于:CI 中可以无成本运行 Smoke 层保证基础质量;而在有真实 DJ 环境的机器上,再通过手动集成与 MIDI 集成步骤验证端到端行为是否如预期。
第一层:Smoke 测试 —— 零依赖的回归基线
流水线第一行给出了 Smoke 层入口:
pytest cli_anything/rekordbox/tests/对应测试文件为 tests/test_smoke.py,共包含 8 个用例,覆盖三个主题。
导入与 CLI 解析(test_import / test_cli_help / test_subcommand_help)
test_import验证import cli_anything.rekordbox可正常导入(test_smoke.py#L9-L10);test_cli_help以子进程方式运行python -m cli_anything.rekordbox --help,断言退出码为 0 且输出包含 "Pioneer Rekordbox" 字样(test_smoke.py#L13-L18)。这里的关键在于cli_anything.rekordbox包通过main.py 暴露main()入口,因此可以python -m方式启动;test_subcommand_help遍历library、playlist、deck、status、install-mapping、mix六个子命令,逐一断言--help退出码为 0(test_smoke.py#L21-L25),这实际上是在静态层面锁定了 CLI 的命令树结构。
写保护选项的存在性(test_playlist_write_options_are_documented)
该用例检查playlist create --help输出中包含--force与--no-backup两个选项(test_smoke.py#L28-L33)。它们不是装饰选项,而是写安全模型的公开接口,在 playlist create 中分别被定义为"允许在 Rekordbox 运行时写库(但仍会先备份)"和"在 Rekordbox 关闭时跳过写前备份"。
写入守卫逻辑(test_write_guard_* 三连)
写入守卫是这套 CLI 最核心的安全设计,Smoke 层用三个用例把它钉死:
test_write_guard_refuses_running_rekordbox_without_force:当 Rekordbox 进程在运行时,_open_db_for_write(force=False, backup=True, ...)必须抛出click.ClickException("Refusing..."),并且根本不会打开数据库(monkeypatch 使_open_db直接pytest.fail),证明守卫发生在任何数据库 I/O 之前(test_smoke.py#L36-L43);test_write_guard_requires_backup_for_forced_running_write:即使--force放行了运行中写入,也必须要求备份存在,否则依然拒绝(test_smoke.py#L46-L53);test_write_guard_creates_backup_before_write:用临时目录构造一个伪造的master.db,验证写前会在同目录的cli-anything-backups子目录生成带时间戳的.bak备份文件,且字节内容与源文件完全一致(test_smoke.py#L56-L82)。
对照源码,这三个用例精确映射到 _open_db_for_write 的分支逻辑:
if running and not force: raise click.ClickException("Refusing to ... while Rekordbox is running. ...") if running and not backup: raise click.ClickException("Refusing forced write while Rekordbox is running without a backup")进程探测由 _is_rekordbox_running 完成:Windows 上查tasklist中的rekordbox.exe,macOS/Linux 上查pgrep -x rekordbox,兜底再扫描ps -A输出;同时支持用环境变量CLI_ANYTHING_REKORDBOX_RUNNING=1强制覆盖探测结果,方便在无法真实启动 Rekordbox 的 CI 环境模拟"运行中"状态。备份逻辑 _backup_database 不仅备份master.db本体,还会把-wal与-shm两个 SQLite WAL 伴生文件一并复制,确保在 WAL 模式下的备份一致性。
数据文件完整性(test_data_file_present)
最后一个 Smoke 用例断言随包分发的 data/Bunker.midi.csv 存在,且首行必须以@file,1,开头(test_smoke.py#L85-L91)。这一行是 Pioneer.midi.csv格式的元数据头,@file后的数字是格式版本号。该文件由 setup.py 的package_data声明("cli_anything.rekordbox": ["skills/*.md", "data/*.csv"])随包发布,缺失将直接导致install-mapping命令不可用。
第二层:数据库手动集成验证 —— 五步走通 master.db 读写链路
该层要求本机真实安装Rekordbox 6/7(首次运行后才会生成可读的 master.db),验证 CLI 与加密曲库之间的真实读写链路。
步骤 1:status 检查运行时与曲库状态
cli-anything-rekordbox status预期:track_count为非零数值。status命令(rekordbox_cli.py#L483-L496)一次性报告三方面状态:可用 MIDI 输出端口列表(midi_outputs)、数据库路径(db_path)、曲库规模(track_count与playlist_count)。若pyrekordbox未安装或 master.db 无法解锁,会在db_error字段返回异常信息而不是崩溃。
数据库打开逻辑见 _open_db:调用Rekordbox6Database(unlock=True)完成 SQLCipher 解密——Rekordbox 6/7 的 master.db 使用静态 AES-256 密钥(同一代安装共享),由pyrekordbox自动提取,这也是整套方案能直连数据库的根基。注意此层为只读操作,不触发任何写守卫。
步骤 2:library search 检索默认 Demo 曲目
cli-anything-rekordbox library search "Demo"预期:返回 Pioneer 安装自带的默认 Demo 曲目。搜索实现位于 library search:遍历db.get_content()的全部曲目,对Title与ArtistName做不区分大小写的子串匹配,--limit默认截断到 20 条;每条结果输出id、title、artist、bpm(源码中 BPM 存储值需除以 100 还原,如c.BPM / 100.0)与genre。这一步骤同时验证了 SQLCipher 解密、曲库遍历与字段解析三个环节。
步骤 3~5:playlist 的创建、追加与清空(写链路)
cli-anything-rekordbox playlist create eval-test cli-anything-rekordbox playlist add eval-test --track-title "Demo Track 1" cli-anything-rekordbox playlist clear eval-testcreate预期返回status: created(含新 playlist 的id)。源码先做幂等检查:同名 playlist 已存在时返回already exists(rekordbox_cli.py#L290-L293),随后才进入写守卫路径并调用db.create_playlist(name);add预期返回status: added。--track-title按标题子串定位曲目(也可用--track-id精确指定),随后db.add_to_playlist(pl, track);clear预期返回removed > 0,即真实移除了至少一条曲目。实现中遍历pl.Songs并逐个db.remove_from_playlist计数(rekordbox_cli.py#L349-L354)。
这三个写命令的共性在于:任何一次库写入前都会经过_open_db_for_write守卫并生成备份,提交时则走 _commit_db_write——先db.registry.autoincrement_local_update_count(set_row_usn=True)递增本地更新计数(同步 USN 行号,保证 Rekordbox 自身能识别外部变更),再session.commit()并clear_buffer()。这是外部写库不破坏 Rekordbox 内部状态机、重启后能正常识别改动的重要细节。执行playlist create/clear命令后,返回结果中还会附带safety信息(备份路径、rekordbox 是否在运行、是否为 force 写入),便于审计。
第三层:MIDI 集成验证 —— 通过虚拟 MIDI 驱动真实界面
这一层要求更严苛的运行环境:虚拟 MIDI 端口 + Rekordbox 前台运行 + MIDI 映射已启用。它验证的是 CLI 通过 MIDI 通道驱动 Rekordbox 界面控件的链路。
步骤 6:install-mapping 安装 Bunker 映射
cli-anything-rekordbox install-mapping预期:至少有一个路径写入成功(installed_to列表非空)。该命令(rekordbox_cli.py#L499-L531)把随包分发的Bunker.midi.csv复制进 Rekordbox 的MidiMappings目录,候选路径按平台探测:
- Windows:依次尝试
C:\Program Files\rekordbox\rekordbox {7.2.8|7.2.7|7.2.6|6.8.6}\MidiMappings(版本硬编码在源码中,若你的安装版本不同需用--rekordbox-dir显式指定); - macOS:
/Applications/rekordbox 7/rekordbox.app/Contents/Resources/MidiMappings。
安装时若目标是LoopBe Internal MIDI.midi.csv,源码还会改写 CSV 首行@file头中的设备名(Bunker→LoopBe Internal MIDI),使映射与虚拟端口名精确对应(rekordbox_cli.py#L523-L527)。权限不足时条目会被标记为PERMISSION_DENIED:前缀而非静默失败。
步骤 7:手动启用 LoopBe 内部 MIDI
在 Rekordbox 的Preferences → Controller → MIDI中勾选启用 LoopBe Internal MIDI 端口。这是唯一必须人工完成的步骤,因为端口枚举发生在 Rekordbox 进程内部,无法通过 CLI 自动完成。
步骤 8~9:deck eq 设置 EQ 旋钮到中间位
cli-anything-rekordbox deck eq --deck 1 --hi 0.5 --mid 0.5 --lo 0.5 --port LoopBe预期:Rekordbox 中 Deck 1 的 HI/MID/LO 三个 EQ 旋钮均被推到 12 点方向(noon,即 0.5 的归一化中间值)。EQ 实现(rekordbox_cli.py#L436-L456)的关键是14-bit 高分辨率 CC(Control Change)编码:值域0..1先映射到0..16383(int(hi * 16383)),再由 _cc14 拆成两条 7-bit 消息——MSB(高 7 位)与 LSB(低 7 位)分别发送:
- HI:CC 0x07 / LSB 0x27
- MID:CC 0x0B / LSB 0x2B
- LO:CC 0x0F / LSB 0x2F
对照 Bunker.midi.csv 中的映射行(EQHigh/EQMid/EQLow均声明为KnobSliderHiRes),可以确认这套 14-bit 编码与映射文件声明的控件类型完全吻合。通道号取deck_n - 1(Deck 1 → 通道 0),端口通过 _open_midi 按子串(默认LoopBe)在mido.get_output_names()中做不区分大小写的匹配,找不到匹配端口时会列出全部可用端口并报错退出。
评估运行环境与前置条件汇总
| 层次 | 前置条件 | 失败时的典型现象 |
|---|---|---|
| Smoke | Python 3.10+、pip install -e .(含 pytest) | 导入错误、--help非 0 退出 |
| DB 手动集成 | Rekordbox 6/7 已安装且 master.db 已生成;pyrekordbox可解锁 | db_error字段报错、track_count 为 0 |
| MIDI 集成 | 虚拟 MIDI 驱动(Windows:loopMIDI / LoopBe / teVirtualMIDI;macOS:IAC Driver;Linux:ALSAsnd-virmidi)+ Rekordbox 运行 + 映射启用 | No MIDI output port matching ...、EQ 旋钮无反应 |
安装与依赖声明见 setup.py:运行时依赖为click>=8.0.0、prompt-toolkit>=3.0.0、mido>=1.3.0、python-rtmidi>=1.5.0、pyrekordbox>=0.4.0;Windows 上的 UI 自动化增强依赖放在cli-anything-rekordbox[windows]extras 中。详细的命令分组、参数说明与架构图可进一步查阅 skills/SKILL.md 与 README.md。
Agent 消费视角:--json 输出与 REPL 模式
虽然评估流水线没有显式列出 JSON 断言,但所有命令都通过统一的 _emit 输出:挂上全局--json标志后,返回结构化 JSON(json.dumps(..., default=str, indent=2)),否则输出人类可读的key: value文本。因此评估时的任何一步都可以无缝切换为 Agent 可解析的机器格式,例如:
cli-anything-rekordbox --json status cli-anything-rekordbox --json library search "Demo"此外,不带子命令直接运行cli-anything-rekordbox会进入基于prompt_toolkit的 REPL 交互模式(rekordbox_cli.py#L162-L187),支持逐行输入子命令、help查看帮助、exit/quit退出。这为人工排查与快速手测提供了比逐条敲 shell 命令更顺手的界面。
从源码结构看可扩展的验证点
从 rekordbox_cli.py 的完整命令树可以推断,评估流水线未来还可覆盖以下行为(当前 eval_pipeline.md 尚未收录):
library info TRACK_ID的单曲元数据完整性(BPM、Key、时长、文件路径);library dump --out的整库 JSON 导出与文件落地校验;deck play/sync/hot-cue的其余 MIDI 命令(_tap采用 30ms 短按、hot-cue 用 velocity 7/0 触发,slot 限 1..8);deck crossfade FROM TO --secs的 64 步 14-bit 渐变序列(CC 0x1F/0x3F);- 顶层的
mix A B --secs端到端混音编排(当前实现负责曲库检索与提示下一步,真正的加载仍需在 Rekordbox UI 手动完成)。
这些命令的预期输出均可依据源码中的参数校验(如deck_n仅接受 1/2、hot-cue slot仅接受 1..8、--secs/--steps数值边界)设计成与现有 Smoke 用例同构的断言,从而把评估流水线从"人工三步验证"升级为"可回归的自动化矩阵"。
小结
cli-anything-rekordbox的评估流水线用三层递进的验证策略,覆盖了从纯 Python 逻辑到真实数据库、再到真实 MIDI 界面的完整控制链:Smoke 层以 tests/test_smoke.py 守住导入、CLI 解析与写保护安全底线;数据库手动集成层通过status、library search与 playlist 三写命令验证 SQLCipher 直连读写;MIDI 集成层通过install-mapping与deck eq验证虚拟 MIDI 实机控制。每一条验证命令都能在源码中找到精确的实现对应,从而保证评估结果既可复现、又可审计——这正是 Agent 原生工具链在真实桌面软件(DJ 软件)上落地时所必需的质量闭环。
【免费下载链接】CLI-Anything"CLI-Anything: Making ALL Software Agent-Native" -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考