cli/main: refactor external command
Refactors the external command logic into a struct. This allows for methods to maitain the logic of an external command. It also allows for a cleaner output for the executable name – avoiding the debug output of OsString using `""`.
This commit is contained in:
parent
f60922d125
commit
83f26abaa0
|
|
@ -1,4 +1,5 @@
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
use std::fmt::Display;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::{io::ErrorKind, process};
|
use std::{io::ErrorKind, process};
|
||||||
|
|
@ -175,36 +176,65 @@ fn run_command(command: Command, ctx: impl term::Context) -> Result<(), anyhow::
|
||||||
Command::Unseed(args) => unseed::run(args, ctx),
|
Command::Unseed(args) => unseed::run(args, ctx),
|
||||||
Command::Watch(args) => watch::run(args, ctx),
|
Command::Watch(args) => watch::run(args, ctx),
|
||||||
Command::Version { json } => write_version(json),
|
Command::Version { json } => write_version(json),
|
||||||
Command::External(mut args) => {
|
Command::External(args) => ExternalCommand::new(args).run(),
|
||||||
let exe = args.remove(0);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This command is deprecated and delegates to `git diff`.
|
struct ExternalCommand {
|
||||||
// Even before it was deprecated, it was not printed by
|
command: OsString,
|
||||||
// `rad -h`.
|
args: Vec<OsString>,
|
||||||
//
|
}
|
||||||
// Since it is external, `--help` will delegate to `git diff --help`.
|
|
||||||
if exe == "diff" {
|
|
||||||
return diff::run(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
let exe = format!("{NAME}-{exe:?}");
|
impl ExternalCommand {
|
||||||
let status = process::Command::new(&exe).args(&args).status();
|
fn new(mut args: Vec<OsString>) -> Self {
|
||||||
|
let command = args.remove(0);
|
||||||
|
Self { command, args }
|
||||||
|
}
|
||||||
|
|
||||||
match status {
|
fn is_diff(&self) -> bool {
|
||||||
Ok(status) => {
|
self.command == "diff"
|
||||||
if !status.success() {
|
}
|
||||||
return Err(anyhow!("`{exe}` exited with an error."));
|
|
||||||
}
|
fn exe(&self) -> OsString {
|
||||||
Ok(())
|
let mut exe = OsString::from(NAME);
|
||||||
|
exe.push("-");
|
||||||
|
exe.push(self.command.clone());
|
||||||
|
exe
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_exe(&self) -> impl Display {
|
||||||
|
match self.exe().into_string() {
|
||||||
|
Ok(exe) => exe,
|
||||||
|
Err(exe) => format!("{exe:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(self) -> anyhow::Result<()> {
|
||||||
|
// This command is deprecated and delegates to `git diff`.
|
||||||
|
// Even before it was deprecated, it was not printed by
|
||||||
|
// `rad -h`.
|
||||||
|
//
|
||||||
|
// Since it is external, `--help` will delegate to `git diff --help`.
|
||||||
|
if self.is_diff() {
|
||||||
|
return diff::run(self.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
let status = process::Command::new(self.exe()).args(&self.args).status();
|
||||||
|
match status {
|
||||||
|
Ok(status) => {
|
||||||
|
if !status.success() {
|
||||||
|
return Err(anyhow!("`{}` exited with an error.", self.display_exe()));
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Ok(())
|
||||||
if let ErrorKind::NotFound = err.kind() {
|
}
|
||||||
Err(anyhow!(
|
Err(err) => {
|
||||||
"`{exe}` is not a command. See `rad --help` for a list of commands.",
|
if let ErrorKind::NotFound = err.kind() {
|
||||||
))
|
Err(anyhow!(
|
||||||
} else {
|
"`{}` is not a known command. See `rad --help` for a list of commands.",
|
||||||
Err(err.into())
|
self.display_exe(),
|
||||||
}
|
))
|
||||||
|
} else {
|
||||||
|
Err(err.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue