feat(cli): render a consumer's own blueprint with aura graph <file> (#28)
aura graph was the last verb still sample-bound: its no-subcommand arm always rendered the embedded r_sma_open.json, so a downstream researcher who authored their own blueprint could introspect it as data but not RENDER it to see mis-wiring before a run — the Construction-layer milestone payoff only half realized. Give GraphCmd a first-positional blueprint (args_conflicts_with_subcommands so it coexists with build/introspect/register), and branch the no-subcommand arm on is_blueprint_file, mirroring dispatch_run: read the file, reload it via blueprint_from_json against the project/std vocabulary, and render_html it; the no-argument form still renders the embedded sample. The library-packaging half (a downstream-linkable render crate) is dropped — the ratified consumer surface is CLI-over-blueprint-data (decision on #28). The nested-composite render is not a concern: the old graph.rs ascii render that carried the unimplemented! was retired, render_html serializes via model_to_json with no panic, and #26 is already closed. closes #28
This commit is contained in:
@@ -2038,7 +2038,10 @@ struct NewCmd {
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
#[command(args_conflicts_with_subcommands = true)]
|
||||
struct GraphCmd {
|
||||
/// A blueprint .json file to render (omit for the built-in sample).
|
||||
blueprint: Option<String>,
|
||||
#[command(subcommand)]
|
||||
sub: Option<GraphSub>,
|
||||
}
|
||||
@@ -2665,14 +2668,32 @@ fn dispatch_chart(a: ChartCmd, env: &project::Env) {
|
||||
|
||||
fn dispatch_graph(a: GraphCmd, env: &project::Env) {
|
||||
match a.sub {
|
||||
None => {
|
||||
let bp = blueprint_from_json(
|
||||
include_str!("../examples/r_sma_open.json"),
|
||||
&|t| env.resolve(t),
|
||||
)
|
||||
.expect("the shipped r-sma example reloads into a renderable blueprint");
|
||||
print!("{}", render::render_html(&bp));
|
||||
}
|
||||
None => match is_blueprint_file(&a.blueprint) {
|
||||
Some(path) => {
|
||||
let doc = std::fs::read_to_string(path).unwrap_or_else(|e| {
|
||||
eprintln!("aura: {path}: {e}");
|
||||
std::process::exit(2);
|
||||
});
|
||||
let bp = blueprint_from_json(&doc, &|t| env.resolve(t)).unwrap_or_else(|e| {
|
||||
let mut msg = graph_construct::blueprint_load_prose(&e);
|
||||
if let Some(hint) = graph_construct::unresolved_namespace_hint(&e, env) {
|
||||
msg.push_str(" — ");
|
||||
msg.push_str(&hint);
|
||||
}
|
||||
eprintln!("aura: {path}: {msg}");
|
||||
std::process::exit(2);
|
||||
});
|
||||
print!("{}", render::render_html(&bp));
|
||||
}
|
||||
None => {
|
||||
let bp = blueprint_from_json(
|
||||
include_str!("../examples/r_sma_open.json"),
|
||||
&|t| env.resolve(t),
|
||||
)
|
||||
.expect("the shipped r-sma example reloads into a renderable blueprint");
|
||||
print!("{}", render::render_html(&bp));
|
||||
}
|
||||
},
|
||||
Some(GraphSub::Build) => graph_construct::build_cmd(env),
|
||||
Some(GraphSub::Introspect(i)) => graph_construct::introspect_cmd(i, env),
|
||||
Some(GraphSub::Register { file }) => graph_construct::register_cmd(&file, env),
|
||||
|
||||
Reference in New Issue
Block a user