cli: Improve `rad config`

This commit is contained in:
cloudhead 2024-01-29 11:07:38 +01:00
parent d7ca9ad3c0
commit 3ff1ddd5e3
No known key found for this signature in database
2 changed files with 54 additions and 5 deletions

View File

@ -1,5 +1,6 @@
#![allow(clippy::or_fun_call)] #![allow(clippy::or_fun_call)]
use std::ffi::OsString; use std::ffi::OsString;
use std::process;
use anyhow::anyhow; use anyhow::anyhow;
@ -15,8 +16,12 @@ pub const HELP: Help = Help {
Usage Usage
rad config [<option>...] rad config [<option>...]
rad config show
rad config init
rad config edit
If no argument is specified, prints the current radicle configuration as JSON. If no argument is specified, prints the current radicle configuration as JSON.
To initialize a new configuration file, use `rad config init`.
Options Options
@ -25,13 +30,24 @@ Options
"#, "#,
}; };
pub struct Options {} #[derive(Default)]
enum Operation {
#[default]
Show,
Init,
Edit,
}
pub struct Options {
op: Operation,
}
impl Args for Options { impl Args for Options {
fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> { fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
use lexopt::prelude::*; use lexopt::prelude::*;
let mut parser = lexopt::Parser::from_args(args); let mut parser = lexopt::Parser::from_args(args);
let mut op: Option<Operation> = None;
#[allow(clippy::never_loop)] #[allow(clippy::never_loop)]
while let Some(arg) = parser.next()? { while let Some(arg) = parser.next()? {
@ -39,20 +55,52 @@ impl Args for Options {
Long("help") | Short('h') => { Long("help") | Short('h') => {
return Err(Error::Help.into()); return Err(Error::Help.into());
} }
Value(val) if op.is_none() => match val.to_string_lossy().as_ref() {
"show" => op = Some(Operation::Show),
"edit" => op = Some(Operation::Edit),
"init" => op = Some(Operation::Init),
unknown => anyhow::bail!("unknown operation '{unknown}'"),
},
_ => return Err(anyhow!(arg.unexpected())), _ => return Err(anyhow!(arg.unexpected())),
} }
} }
Ok((Options {}, vec![])) Ok((
Options {
op: op.unwrap_or_default(),
},
vec![],
))
} }
} }
pub fn run(_options: Options, ctx: impl term::Context) -> anyhow::Result<()> { pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
let profile = ctx.profile()?; let profile = ctx.profile()?;
let path = profile.home.config(); let path = profile.home.config();
let output = term::json::to_pretty(&profile.config, path.as_path())?;
output.print(); match options.op {
Operation::Show => {
term::json::to_pretty(&profile.config, path.as_path())?.print();
}
Operation::Init => {
if path.try_exists()? {
anyhow::bail!("configuration file already exists at `{}`", path.display());
}
profile.config.write(&path)?;
}
Operation::Edit => {
let Some(cmd) = term::editor::default_editor() else {
anyhow::bail!("no editor configured; please set the `EDITOR` environment variable");
};
process::Command::new(cmd)
.stdout(process::Stdio::inherit())
.stderr(process::Stdio::inherit())
.stdin(process::Stdio::inherit())
.arg(&path)
.spawn()?
.wait()?;
}
}
Ok(()) Ok(())
} }

View File

@ -16,6 +16,7 @@ const COMMANDS: &[Help] = &[
rad_auth::HELP, rad_auth::HELP,
rad_checkout::HELP, rad_checkout::HELP,
rad_clone::HELP, rad_clone::HELP,
rad_config::HELP,
rad_fork::HELP, rad_fork::HELP,
rad_help::HELP, rad_help::HELP,
rad_id::HELP, rad_id::HELP,