refactor: return an exit code from main

This commit is contained in:
2026-09-08 09:54:58 +00:00
parent aec7afb274
commit 11ecd0ac89
2 changed files with 54 additions and 27 deletions

View File

@@ -1,9 +1,11 @@
use std::process::ExitCode;
use ahab::{cli, command_builder, scripts}; use ahab::{cli, command_builder, scripts};
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
fn main() -> Result<()> { fn main() -> ExitCode {
let args = cli::Ahab::parse(); let args = cli::Ahab::parse();
command_builder::set_options(command_builder::Options { command_builder::set_options(command_builder::Options {
@@ -11,26 +13,49 @@ fn main() -> Result<()> {
dry_run: args.dry_run, dry_run: args.dry_run,
}); });
match args.command { match run(args.command) {
cli::Commands::Django { command } => match command { Ok(code) => code,
Err(e) => {
eprintln!("Error: {e:#}");
ExitCode::FAILURE
}
}
}
fn run(command: cli::Commands) -> Result<ExitCode> {
let done = ExitCode::SUCCESS;
match command {
cli::Commands::Django { command } => {
match command {
cli::Django::Bash => scripts::django::bash(), cli::Django::Bash => scripts::django::bash(),
cli::Django::Run { rest } => scripts::django::run(&rest), cli::Django::Run { rest } => scripts::django::run(&rest),
cli::Django::MakeCommand { app, name } => scripts::django::make_command(&app, &name), cli::Django::MakeCommand { app, name } => {
scripts::django::make_command(&app, &name)
}
cli::Django::Makemigrations => scripts::django::makemigrations(), cli::Django::Makemigrations => scripts::django::makemigrations(),
cli::Django::Manage { rest } => scripts::django::manage(&rest), cli::Django::Manage { rest } => scripts::django::manage(&rest),
cli::Django::Migrate { rest } => scripts::django::migrate(&rest), cli::Django::Migrate { rest } => scripts::django::migrate(&rest),
cli::Django::Shell => scripts::django::shell(), cli::Django::Shell => scripts::django::shell(),
cli::Django::Test => scripts::django::test(), cli::Django::Test => scripts::django::test(),
}, }?;
cli::Commands::Postgres { command } => match command {
Ok(done)
}
cli::Commands::Postgres { command } => {
match command {
cli::Postgres::Import { path } => scripts::postgres::import(&path), cli::Postgres::Import { path } => scripts::postgres::import(&path),
cli::Postgres::Dump { path, format, gzip } => { cli::Postgres::Dump { path, format, gzip } => {
scripts::postgres::dump(&path, format, gzip) scripts::postgres::dump(&path, format, gzip)
} }
}, }?;
Ok(done)
}
cli::Commands::Link { command } => match command { cli::Commands::Link { command } => match command {
cli::Link::Add { paths, force } => scripts::link::add(&paths, force), cli::Link::Add { paths, force } => scripts::link::add(&paths, force).map(|()| done),
cli::Link::Restore { paths, all } => scripts::link::restore(&paths, all), cli::Link::Restore { paths, all } => scripts::link::restore(&paths, all).map(|()| done),
// the one command with something to say through its exit code
cli::Link::Check { cli::Link::Check {
paths, paths,
porcelain, porcelain,
@@ -38,6 +63,10 @@ fn main() -> Result<()> {
exit_code, exit_code,
} => scripts::link::check(&paths, porcelain, null, exit_code), } => scripts::link::check(&paths, porcelain, null, exit_code),
}, },
cli::Commands::Completions { shell } => scripts::completions::completions(shell), cli::Commands::Completions { shell } => {
scripts::completions::completions(shell)?;
Ok(done)
}
} }
} }

View File

@@ -2,11 +2,10 @@ use std::cell::Cell;
use std::env; use std::env;
use std::ffi::OsString; use std::ffi::OsString;
use std::fs; use std::fs;
use std::io::{self, Write};
use std::os::unix::fs::symlink; use std::os::unix::fs::symlink;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process;
use std::process::Command; use std::process::Command;
use std::process::ExitCode;
use anyhow::{Context, Result, anyhow, bail}; use anyhow::{Context, Result, anyhow, bail};
@@ -179,7 +178,7 @@ fn warn(msg: impl std::fmt::Display) {
} }
// list untracked paths not in the store, i.e. what a sandbox can still read // list untracked paths not in the store, i.e. what a sandbox can still read
pub fn check(paths: &[PathBuf], porcelain: bool, null: bool, exit_code: bool) -> Result<()> { pub fn check(paths: &[PathBuf], porcelain: bool, null: bool, exit_code: bool) -> Result<ExitCode> {
let repo = Repo::discover()?; let repo = Repo::discover()?;
let pathspecs = relative_pathspecs(&repo, paths)?; let pathspecs = relative_pathspecs(&repo, paths)?;
@@ -208,11 +207,10 @@ pub fn check(paths: &[PathBuf], porcelain: bool, null: bool, exit_code: bool) ->
// git's --exit-code convention: nothing to report is 0, anything is 1 // git's --exit-code convention: nothing to report is 0, anything is 1
if exit_code && !exposed.is_empty() { if exit_code && !exposed.is_empty() {
io::stdout().flush().context("writing the listing")?; return Ok(ExitCode::FAILURE);
process::exit(1);
} }
Ok(()) Ok(ExitCode::SUCCESS)
} }
fn print_porcelain(exposed: &[Exposed], null: bool) { fn print_porcelain(exposed: &[Exposed], null: bool) {