git_override/
run.rs

1use crate::{find_upstream_git, scan_path, Options};
2use std::path::{Path, PathBuf};
3use std::process::Command;
4
5/// This is the main entry point for the [crate] binary called `git`.
6pub fn run() -> anyhow::Result<()> {
7    let options = Options::parse();
8    let upgit = find_upstream_git()?;
9
10    let exepath = if options.upstream {
11        upgit.clone()
12    } else {
13        find_override_path(options.args.iter())?.unwrap_or_else(|| upgit.clone())
14    };
15
16    let status = Command::new(exepath)
17        .env("GIT_OVERRIDE_UPSTREAM", &upgit)
18        .args(&options.args)
19        .status()?;
20
21    handle_exit_status(&upgit, status)
22}
23
24fn find_override_path<'a, I>(mut args: I) -> anyhow::Result<Option<PathBuf>>
25where
26    I: Iterator<Item = &'a String>,
27{
28    if let Some(subcmd) = args.find(|a| !a.starts_with('-')) {
29        let candidate = format!("git-{}", subcmd);
30        Ok(scan_path(candidate)?.into_iter().next())
31    } else {
32        Ok(None)
33    }
34}
35
36fn handle_exit_status(upgit: &Path, status: std::process::ExitStatus) -> anyhow::Result<()> {
37    if status.success() {
38        Ok(())
39    } else {
40        let code = status.code().ok_or_else(|| {
41            errormsg!(
42                "No exit status code from executing upstream git {:?}",
43                upgit,
44            )
45        })?;
46        std::process::exit(code);
47    }
48}