cli API

Luna-Flow/mare_mark/cli 是 mare-mark 可执行程序:它把 JSONL 事件文件渲染为 HTML 报告,并重放记录下来的验证失败。本页记录命令行以及该包的公开辅助函数。参见 cli 设计。

源码:src/cli/cli.mbt、src/cli/main.mbt(native)、src/cli/main_unimplemented.mbt(其他目标)、src/cli/replay_native.mbt。

命令行

在检出的仓库中用 moon run src/cli --target native -- <arguments> 运行。

mare-mark <replay|report> [options] [input] [output]
调用方式效果
mare-mark report <input.jsonl> <output.html>解析事件并写出一份自包含的 HTML 报告
mare-mark report - -从 stdin 读取事件,把 HTML 写到 stdout
mare-mark report --quiet ...不打印进度摘要
mare-mark report --open ...用 open 打开写出的文件(macOS)
mare-mark replay <artifact.jsonl> --dry-run打印第一个 validation_failure 的命令、参数和超时
mare-mark replay <artifact.jsonl> --yes以该超时执行该命令并打印其 stdout
mare-mark --version, -V打印 mare-mark 0.3.0
mare-mark --help、-h 或不带参数打印用法;若指定了命令,则打印该命令的帮助

选项可以出现在命令之后的任何位置。未知选项以及多于两个的位置参数都是错误。replay 拒绝以 - 作为输入,并且没有 --yes 时拒绝执行。

退出码:成功时为 0;文件无法读写、JSONL 无效、或重放失败或超时时为 1;用法错误(未知命令或选项、缺少参数、缺少 --yes)时为 2。在 native 以外的目标上,report 通过 render_jsonl_report 工作,而 replay 以 2 退出。

写出文件后,report 会打印输出文件的绝对路径、非空输入行数和耗时。耗时以微秒为单位测量,但标注为 ms。

包函数

该包是一个可执行包(pkgtype(kind: "executable"))。它的公开函数是构成 main 的基本组件,并由该包的测试覆盖。MoonBit 0.10 仍允许其他包导入可执行包,但会警告这将来会成为错误,因此不要在你自己的包中基于这些函数进行构建。

请求

Command

Command 是由第一个参数选出的子命令。

pub enum Command {
  Replay
  Report
  Help
  Version
  Unknown(String)
}

CliRequest

CliRequest 是解析后的命令行。

pub struct CliRequest {
  command : Command
  input : String?
  output : String?
  dry_run : Bool
  yes : Bool
  quiet : Bool
  open : Bool
  show_help : Bool
  error : String?
}

input 和 output 是前两个位置参数。error 保存第一个用法错误("unknown option '…'"、"too many positional arguments")。

parse_args

parse_args 解析完整的参数向量,包括程序名。

pub fn parse_args(Array[String]) -> CliRequest

索引 1 选择命令(replay、report、--version/-V、--help/-h;少于两个参数时得到 Help)。只要任意位置出现 --help 或 -h,结果就只包含 show_help = true 和命令。否则,从索引 2 开始的参数是标志(--dry-run、--yes、--quiet、--open)、位置参数或错误;- 视为位置参数。

test "parse a report command" {
  let request = @cli.parse_args(["mare-mark", "report", "--quiet", "events.jsonl", "report.html"])
  inspect(request.command is Report, content="true")
  inspect(request.input == Some("events.jsonl"), content="true")
  inspect(request.quiet, content="true")
  let wrong = @cli.parse_args(["mare-mark", "report", "--fast", "a", "b"])
  inspect(wrong.error == Some("unknown option '--fast'"), content="true")
}

usage, command_help

usage 返回总体帮助文本;command_help 返回 Report 或 Replay 的帮助,对其他命令返回 usage()。

pub fn usage() -> String
pub fn command_help(Command) -> String

报告

render_jsonl_report

render_jsonl_report 读取 JSONL 文件,渲染它并写出 HTML。

pub fn render_jsonl_report(String, String, target? : String) -> Result[String, String]

参数:输入路径、输出路径和目标标签(默认为 "unknown")。返回输出路径;若输入不可读、事件无效或输出不可写,则返回错误消息。

report_html

report_html 就是 @report.html。

pub fn report_html(@ir_model.PlotDocument) -> String

重放

replay_spec_from_jsonl

replay_spec_from_jsonl 从 JSONL 文本中提取第一个 validation_failure 事件的重放命令。

pub fn replay_spec_from_jsonl(String) -> Result[@model.ReplaySpec, String]

在它之前的行会被检查是否为有效的 JSON 对象且具有受支持的 artifact_version,除此之外被跳过。该事件必须有字符串类型的 replay_command;replay_arguments 保留其中的字符串元素,replay_timeout_ms 默认为 5000。错误情形:无效 JSON、非对象行、不受支持的版本、缺少命令,或者根本没有失败事件。

test "read a replay artifact" {
  let artifact =
    #|{"type":"observation","implementation":"a","dataset_id":0,"elapsed_us":1.0}
    #|{"type":"validation_failure","replay_command":"worker","replay_arguments":["fast","42"],"replay_timeout_ms":250}
  let spec = @cli.replay_spec_from_jsonl(artifact).unwrap()
  inspect(spec.command, content="worker")
  debug_inspect(spec.arguments, content="[\"fast\", \"42\"]")
  inspect(spec.timeout_ms, content="250")
  inspect(@cli.replay_spec_from_jsonl("") is Err("no validation_failure event found"), content="true")
}

load_replay_spec

load_replay_spec 读取文件并调用 replay_spec_from_jsonl。

pub fn load_replay_spec(String) -> Result[@model.ReplaySpec, String]