Skip to main content

winbrew/
main.rs

1use std::process::ExitCode;
2
3/// The real CLI. Living in its own `#[cfg(windows)]` module means every item
4/// inside inherits the platform gate for free instead of repeating
5/// `#[cfg(windows)]` on each import, the allocator, and every function.
6#[cfg(windows)]
7mod platform {
8    use std::process::ExitCode;
9
10    use clap::Parser;
11    use mimalloc::MiMalloc;
12    use winbrew_cli::{cli::Cli, commands::error::CommandError, run_app};
13
14    #[global_allocator]
15    static GLOBAL: MiMalloc = MiMalloc;
16
17    pub fn main() -> ExitCode {
18        let cli = Cli::parse();
19        let verbose = cli.verbose;
20
21        let Err(err) = run_app(cli.command, verbose) else {
22            return ExitCode::SUCCESS;
23        };
24
25        let Some(cmd_err) = err.downcast_ref::<CommandError>() else {
26            eprintln!("\nUNEXPECTED: {err:#}");
27            return ExitCode::from(1);
28        };
29
30        if let CommandError::Fatal(message) = cmd_err {
31            eprintln!("\nFATAL: {message}");
32        }
33
34        // `err.chain()` yields `err` itself first, then each `source()` in
35        // turn, so skip(1) is everything cmd_err was ultimately caused by.
36        // Peek first so a bare "Caused by:" header never prints alone.
37        let mut causes = err.chain().skip(1).peekable();
38        if verbose > 0 && causes.peek().is_some() {
39            eprintln!("Caused by:");
40            for cause in causes {
41                eprintln!("  - {cause}");
42            }
43        }
44
45        ExitCode::from(cmd_err)
46    }
47}
48
49/// winbrew manages Windows package installs and has no meaningful behavior
50/// on other platforms. This stub exists only so the workspace (and every
51/// other, genuinely cross-platform crate in it) can be built and tested on
52/// non-Windows hosts; it intentionally does not pretend to succeed.
53#[cfg(not(windows))]
54mod platform {
55    use std::process::ExitCode;
56
57    pub fn main() -> ExitCode {
58        eprintln!("winbrew is a Windows package manager and does not run on this platform.");
59        ExitCode::FAILURE
60    }
61}
62
63fn main() -> ExitCode {
64    platform::main()
65}