mirror of
https://github.com/PR0M3TH3AN/Marlin.git
synced 2025-09-08 07:08:44 +00:00
Generate CLI cheatsheet at build time
This commit is contained in:
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -58,6 +58,14 @@ jobs:
|
||||
if-no-files-found: ignore
|
||||
retention-days: 7
|
||||
|
||||
- name: Upload CLI Cheatsheet
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: marlin-cli-cheatsheet
|
||||
path: docs/cli_cheatsheet.md
|
||||
if-no-files-found: warn
|
||||
retention-days: 7
|
||||
|
||||
coverage:
|
||||
name: Code Coverage (Tarpaulin)
|
||||
needs: comprehensive-tests
|
||||
|
@@ -78,3 +78,7 @@ Before a milestone is declared **shipped**:
|
||||
| 3 | **DP‑001 Schema v1.1** draft | @carol | **30 May 25** |
|
||||
| 4 | backup prune CLI + nightly job | @dave | **05 Jun 25** |
|
||||
|
||||
## CLI Cheatsheet
|
||||
|
||||
The full command reference is generated during the build of the CLI. See
|
||||
[docs/cli_cheatsheet.md](docs/cli_cheatsheet.md).
|
||||
|
@@ -32,3 +32,7 @@ dirs = "5"
|
||||
[features]
|
||||
# Enable JSON output with `--features json`
|
||||
json = ["serde_json"]
|
||||
|
||||
[build-dependencies]
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_yaml = "0.9"
|
||||
|
@@ -1,11 +1,59 @@
|
||||
// cli-bin/build.rs
|
||||
//
|
||||
// The CLI currently needs no build-time code-generation, but Cargo
|
||||
// insists on rerunning any build-script each compile. Tell it to
|
||||
// rebuild only if this file itself changes.
|
||||
// Build script to generate the CLI cheatsheet at compile time. It
|
||||
// parses `src/cli/commands.yaml` and emits a simple Markdown table of
|
||||
// commands and flags to `docs/cli_cheatsheet.md`.
|
||||
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use serde_yaml::Value;
|
||||
|
||||
fn main() {
|
||||
// If you later add code-gen (e.g. embed completions or YAML), add
|
||||
// further `cargo:rerun-if-changed=<path>` lines here.
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rerun-if-changed=src/cli/commands.yaml");
|
||||
|
||||
if let Err(e) = generate_cheatsheet() {
|
||||
eprintln!("Failed to generate CLI cheatsheet: {e}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_cheatsheet() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let yaml_str = fs::read_to_string("src/cli/commands.yaml")?;
|
||||
let parsed: Value = serde_yaml::from_str(&yaml_str)?;
|
||||
|
||||
let mut table = String::from("| Command | Flags |\n| ------- | ----- |\n");
|
||||
|
||||
if let Value::Mapping(cmds) = parsed {
|
||||
for (cmd_name_val, cmd_details_val) in cmds {
|
||||
let cmd_name = cmd_name_val.as_str().unwrap_or("");
|
||||
if let Value::Mapping(cmd_details) = cmd_details_val {
|
||||
if let Some(Value::Mapping(actions)) = cmd_details.get(&Value::String("actions".into())) {
|
||||
for (action_name_val, action_body_val) in actions {
|
||||
let action_name = action_name_val.as_str().unwrap_or("");
|
||||
let flags = if let Value::Mapping(action_map) = action_body_val {
|
||||
match action_map.get(&Value::String("flags".into())) {
|
||||
Some(Value::Sequence(seq)) => seq
|
||||
.iter()
|
||||
.filter_map(|v| v.as_str())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
_ => String::new(),
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let flags_disp = if flags.is_empty() { "—" } else { &flags };
|
||||
table.push_str(&format!("| `{}` | {} |\n", format!("{} {}", cmd_name, action_name), flags_disp));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs::create_dir_all(Path::new("docs"))?;
|
||||
fs::write("docs/cli_cheatsheet.md", table)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Reference in New Issue
Block a user