ma_core/config/cli.rs
1//! Command-line argument struct for ma-core-based binaries.
2//!
3//! Flatten [`MaArgs`] into your own `#[derive(Parser)]` struct so that every
4//! binary in the ma ecosystem accepts a consistent set of arguments:
5//!
6//! ```rust,ignore
7//! use clap::Parser;
8//! use ma_core::config::MaArgs;
9//!
10//! const MA_DEFAULT_SLUG: &str = "panteia";
11//!
12//! #[derive(Parser)]
13//! struct Cli {
14//! #[command(flatten)]
15//! ma: MaArgs,
16//! }
17//!
18//! fn main() -> anyhow::Result<()> {
19//! let cli = Cli::parse();
20//! let config = ma_core::config::Config::from_args(&cli.ma, MA_DEFAULT_SLUG)?;
21//! config.init_logging()?;
22//! Ok(())
23//! }
24//! ```
25
26use std::path::PathBuf;
27
28use clap::Args;
29
30/// Standard ma-core CLI arguments.
31///
32/// Add these to your binary with `#[command(flatten)]`.
33///
34/// `MA_CONFIG` and `MA_SLUG` are the only statically-named environment
35/// variables; all other fields are resolved dynamically in
36/// [`super::Config::from_args`] using the binary's compile-time `MA_DEFAULT_SLUG`
37/// constant as a prefix (e.g. `MA_PANTEIA_LOG_LEVEL`), with a plain
38/// `MA_LOG_LEVEL`-style fallback.
39#[derive(Args, Debug, Clone, Default)]
40pub struct MaArgs {
41 /// Path to the YAML config file. Overrides the slug-derived default
42 /// (`XDG_CONFIG_HOME/ma/<slug>.yaml`).
43 ///
44 /// Environment variable: `MA_CONFIG`
45 #[arg(long, env = "MA_CONFIG")]
46 pub config: Option<PathBuf>,
47
48 /// Runtime slug. Overrides `MA_DEFAULT_SLUG` for file naming
49 /// (`<slug>.yaml`, `<slug>.bin`, `<slug>.log`) only.
50 ///
51 /// The env-var prefix `MA_<MA_DEFAULT_SLUG>_*` is always determined by
52 /// the compile-time constant — this value does **not** change the prefix.
53 ///
54 /// Environment variable: `MA_SLUG`
55 #[arg(long, env = "MA_SLUG")]
56 pub slug: Option<String>,
57
58 /// Log level for the log file (`trace`, `debug`, `info`, `warn`, `error`).
59 ///
60 /// Resolved via `MA_<MA_DEFAULT_SLUG>_LOG_LEVEL` → `MA_LOG_LEVEL` → YAML
61 /// → default `"info"`.
62 #[arg(long)]
63 pub log_level: Option<String>,
64
65 /// Path to the log file. Defaults to `XDG_DATA_HOME/ma/<slug>.log`.
66 ///
67 /// Resolved via `MA_<MA_DEFAULT_SLUG>_LOG_FILE` → `MA_LOG_FILE` → YAML
68 /// → XDG default.
69 #[arg(long)]
70 pub log_file: Option<PathBuf>,
71
72 /// Log level for stdout output (`trace`, `debug`, `info`, `warn`, `error`).
73 ///
74 /// Resolved via `MA_<MA_DEFAULT_SLUG>_LOG_LEVEL_STDOUT` →
75 /// `MA_LOG_LEVEL_STDOUT` → YAML → default `"warn"`.
76 #[arg(long)]
77 pub log_level_stdout: Option<String>,
78
79 /// Path to the encrypted secret bundle file.
80 /// Defaults to `XDG_CONFIG_HOME/ma/<slug>.bin`.
81 ///
82 /// Resolved via `MA_<MA_DEFAULT_SLUG>_SECRET_BUNDLE` →
83 /// `MA_SECRET_BUNDLE` → YAML → XDG default.
84 #[arg(long)]
85 pub secret_bundle: Option<PathBuf>,
86
87 /// Passphrase to unlock the secret bundle.
88 ///
89 /// In headless configs this is stored in cleartext in the YAML file.
90 /// Prefer setting via environment variable rather than CLI to avoid
91 /// shell history exposure.
92 ///
93 /// Resolved via `MA_<MA_DEFAULT_SLUG>_SECRET_BUNDLE_PASSPHRASE` →
94 /// `MA_SECRET_BUNDLE_PASSPHRASE` → YAML.
95 #[arg(long)]
96 pub secret_bundle_passphrase: Option<String>,
97
98 /// Kubo RPC API URL. Defaults to `http://127.0.0.1:5001`.
99 ///
100 /// Resolved via `MA_<MA_DEFAULT_SLUG>_KUBO_RPC_URL` →
101 /// `MA_KUBO_RPC_URL` → YAML → default.
102 #[arg(long)]
103 pub kubo_rpc_url: Option<String>,
104
105 /// IPNS key alias used in Kubo. Defaults to the slug.
106 ///
107 /// Resolved via `MA_<MA_DEFAULT_SLUG>_KUBO_KEY_ALIAS` →
108 /// `MA_KUBO_KEY_ALIAS` → YAML → slug.
109 #[arg(long)]
110 pub kubo_key_alias: Option<String>,
111
112 /// Generate a headless config with a fresh secret bundle, write both
113 /// files with 0600 permissions, and exit.
114 ///
115 /// If `--secret-bundle-passphrase` is not provided, a random passphrase
116 /// is generated and written into the config file.
117 #[arg(long)]
118 pub gen_headless_config: bool,
119}