aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crates/atuin/src/command/external.rs72
-rw-r--r--crates/atuin/src/command/mod.rs6
2 files changed, 78 insertions, 0 deletions
diff --git a/crates/atuin/src/command/external.rs b/crates/atuin/src/command/external.rs
new file mode 100644
index 00000000..03deacbf
--- /dev/null
+++ b/crates/atuin/src/command/external.rs
@@ -0,0 +1,72 @@
+use std::fmt::Write as _;
+use std::process::Command;
+use std::{io, process};
+
+use clap::CommandFactory;
+use clap::builder::{StyledStr, Styles};
+use eyre::Result;
+
+use crate::Atuin;
+
+pub fn run(args: &[String]) -> Result<()> {
+ let subcommand = &args[0];
+ let bin = format!("atuin-{subcommand}");
+ let mut cmd = Command::new(&bin);
+ cmd.args(&args[1..]);
+
+ let spawn_result = match cmd.spawn() {
+ Ok(child) => Ok(child),
+ Err(e) => match e.kind() {
+ io::ErrorKind::NotFound => {
+ let output = render_not_found(subcommand, &bin);
+ Err(output)
+ }
+ _ => Err(e.to_string().into()),
+ },
+ };
+
+ match spawn_result {
+ Ok(mut child) => {
+ let status = child.wait()?;
+ if status.success() {
+ Ok(())
+ } else {
+ process::exit(status.code().unwrap_or(1));
+ }
+ }
+ Err(e) => {
+ eprintln!("{}", e.ansi());
+ process::exit(1);
+ }
+ }
+}
+
+fn render_not_found(subcommand: &str, bin: &str) -> StyledStr {
+ let mut output = StyledStr::new();
+ let styles = Styles::styled();
+ let mut atuin_cmd = Atuin::command();
+ let usage = atuin_cmd.render_usage();
+
+ let error = styles.get_error();
+ let invalid = styles.get_invalid();
+ let literal = styles.get_literal();
+
+ let _ = write!(output, "{error}error:{error:#} ");
+ let _ = write!(
+ output,
+ "unrecognized subcommand '{invalid}{subcommand}{invalid:#}' "
+ );
+ let _ = write!(
+ output,
+ "and no executable named '{invalid}{bin}{invalid:#}' found in your PATH"
+ );
+ let _ = write!(output, "\n\n");
+ let _ = write!(output, "{usage}");
+ let _ = write!(output, "\n\n");
+ let _ = write!(
+ output,
+ "For more information, try '{literal}--help{literal:#}'."
+ );
+
+ output
+}
diff --git a/crates/atuin/src/command/mod.rs b/crates/atuin/src/command/mod.rs
index 09df430e..95813193 100644
--- a/crates/atuin/src/command/mod.rs
+++ b/crates/atuin/src/command/mod.rs
@@ -14,6 +14,8 @@ mod contributors;
mod gen_completions;
+mod external;
+
#[derive(Subcommand)]
#[command(infer_subcommands = true)]
pub enum AtuinCmd {
@@ -33,6 +35,9 @@ pub enum AtuinCmd {
/// Generate shell completions
GenCompletions(gen_completions::Cmd),
+
+ #[command(external_subcommand)]
+ External(Vec<String>),
}
impl AtuinCmd {
@@ -60,6 +65,7 @@ impl AtuinCmd {
Ok(())
}
Self::GenCompletions(gen_completions) => gen_completions.run(),
+ Self::External(args) => external::run(&args),
}
}
}