diff --git a/src/cli/link.rs b/src/cli/link.rs index 9e55503..aa05edf 100644 --- a/src/cli/link.rs +++ b/src/cli/link.rs @@ -45,7 +45,7 @@ pub enum Link { #[arg(long)] porcelain: bool, - /// Exit with 1 when anything is outside the store, for scripts + /// Exit with 4 when anything is outside the store, for scripts #[arg(long)] exit_code: bool, diff --git a/src/commands/link/check.rs b/src/commands/link/check.rs index 868b7d9..d3c3791 100644 --- a/src/commands/link/check.rs +++ b/src/commands/link/check.rs @@ -1,6 +1,5 @@ use fs_err::{read_dir, read_link}; use std::path::{Path, PathBuf}; -use std::process::ExitCode; use anyhow::{Result, anyhow}; @@ -9,14 +8,14 @@ use crate::cmd::{Cmd, LsFiles}; use crate::ctx::Ctx; use crate::output::{line, text}; +// whether anything is outside the store, which main turns into an exit code pub fn check( ctx: &Ctx, paths: &[PathBuf], porcelain: bool, null: bool, - exit_code: bool, store: Option<&Path>, -) -> Result { +) -> Result { let repo = Repo::discover(ctx, store)?; let pathspecs = relative_pathspecs(&repo, paths)?; @@ -43,19 +42,12 @@ pub fn check( print_listing(&repo, &exposed); } - // git's --exit-code convention: nothing to report is 0, anything is 1 - if exit_code && !exposed.is_empty() { - return Ok(ExitCode::FAILURE); - } - - Ok(ExitCode::SUCCESS) + Ok(!exposed.is_empty()) } fn print_porcelain(exposed: &[Exposed], null: bool) { let end = if null { '\0' } else { '\n' }; - // a filename can hold an arrow but not a NUL, so -z separates the two paths - // with one the way `git status -z` does for a rename. the two character code - // stays where it is: it cannot be mistaken for part of a path + // a filename can hold an arrow but not a NUL, as `git status -z` also assumes let between = if null { "\0" } else { " -> " }; for item in exposed { diff --git a/src/main.rs b/src/main.rs index 9a289c5..1ab7e53 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,9 @@ use clap::Parser; use crate::ctx::Ctx; use crate::output::note; +// 0 ran with nothing to report, 1 could not finish, 2 bad arguments, 4 found something +const FINDINGS: u8 = 4; + fn main() -> ExitCode { let args = cli::Ahab::parse(); @@ -87,14 +90,15 @@ fn run(ctx: &Ctx, command: cli::Commands) -> Result { null, exit_code, store, - } => commands::link::check( - ctx, - &paths, - porcelain, - null, - exit_code, - store.root.as_deref(), - ), + } => { + let exposed = + commands::link::check(ctx, &paths, porcelain, null, store.root.as_deref())?; + + match exit_code && exposed { + true => Ok(ExitCode::from(FINDINGS)), + false => Ok(done), + } + } }, cli::Commands::Status { store } => { commands::status::status(ctx, store.root.as_deref())?;