Skip to main content

chaud_cli/
lib.rs

1/*!
2# `chaud-cli` (**library**)
3
4Implementation detail of [Chaud 🔥](https://docs.rs/chaud).
5
6**Do not use this crate directly!**
7
8This crate implements shared functionality for the Chaud CLI Tools.
9*/
10#![allow(
11    clippy::missing_errors_doc,
12    reason = "less restrictions on build-time tools"
13)]
14
15use anyhow::{Result, bail, ensure};
16use core::fmt;
17use std::env;
18use std::process::Command;
19use std::sync::LazyLock;
20
21pub fn actual_args() -> Result<Vec<String>> {
22    let mut args = vec![];
23    for arg in env::args_os().skip(1) {
24        let arg = match arg.into_string() {
25            Ok(arg) => arg,
26            Err(arg) => bail!("Non UTF-8 argument: {arg:?}"),
27        };
28        args.push(arg);
29    }
30    Ok(args)
31}
32
33pub fn link_args() -> Result<&'static [&'static str]> {
34    // See docs.rs/chaud#how-it-works.
35    if cfg!(target_os = "macos") {
36        Ok(&["-Zpre-link-args=-Wl,-all_load"])
37    } else if cfg!(unix) {
38        Ok(&[
39            "-Zpre-link-args=-Wl,--whole-archive",
40            "-Clink-args=-Wl,--allow-multiple-definition",
41            "-Clink-args=-Wl,--export-dynamic",
42        ])
43    } else {
44        bail!("Hot-reloading not supported on the current platform");
45    }
46}
47
48pub fn run(mut cmd: Command) -> Result<()> {
49    verbose!("Executing: {cmd:?}");
50
51    let status = match cmd.status() {
52        Ok(s) => s,
53        Err(e) => bail!("Failed to spawn ({e}): {cmd:?}"),
54    };
55    ensure!(status.success(), "Failed to run ({status}): {cmd:?}");
56    Ok(())
57}
58
59pub fn verbose(x: impl fmt::Display) {
60    static VERBOSE: LazyLock<bool> = LazyLock::new(|| env::var_os("CHAUD_CLI_VERBOSE").is_some());
61
62    if *VERBOSE {
63        eprintln!("{x}");
64    }
65}
66
67#[macro_export]
68macro_rules! verbose {
69    ($($t:tt)*) => { $crate::verbose(format_args!($($t)*)); }
70}