pub mod agent;
pub(crate) mod cli;
pub(crate) mod commands;
pub mod config;
pub mod copy;
pub mod cx;
pub mod error;
pub mod gh;
pub mod git;
pub mod hooks;
pub mod keys;
pub mod model;
pub mod output;
pub mod query;
pub mod slug;
pub mod template;
pub mod time;
pub mod tui;
pub mod util;
pub mod version;
pub(crate) mod worktree_service;
#[cfg(test)]
mod testutil;
pub use cx::{Cx, Env, Stream};
pub use error::{Error, Result};
pub fn run(args: Vec<String>, cx: &mut Cx) -> u8 {
let result = cli::dispatch(args, cx);
finish(result, &mut cx.err)
}
fn finish(result: Result<u8>, err: &mut Stream) -> u8 {
match result {
Ok(code) => code,
Err(e) => {
let _ = err.line(&format!("error: {e}"));
e.exit_code()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::testutil::test_cx;
#[test]
fn finish_passes_through_success_code() {
let mut t = test_cx(&[], "/tmp");
assert_eq!(finish(Ok(0), &mut t.cx.err), 0);
assert_eq!(finish(Ok(1), &mut t.cx.err), 1);
assert!(t.err.contents().is_empty());
}
#[test]
fn finish_reports_error_to_stderr_and_maps_code() {
let mut t = test_cx(&[], "/tmp");
let code = finish(Err(Error::usage("bad flag")), &mut t.cx.err);
assert_eq!(code, 2);
assert_eq!(t.err.contents(), "error: bad flag\n");
assert!(t.out.contents().is_empty());
}
#[test]
fn run_help_exits_zero_via_clap() {
let mut t = test_cx(&[], "/tmp");
assert_eq!(run(vec!["--help".to_string()], &mut t.cx), 0);
assert!(t.out.contents().contains("Usage"));
}
#[test]
fn run_maps_command_error_to_exit_code() {
let mut t = test_cx(&[], "/tmp");
assert_eq!(run(vec![], &mut t.cx), 1);
assert!(t.err.contents().contains("not in a git repository"));
}
}