Skip to main content

npmgen_cli/
lib.rs

1//! CLI driver shared by the `npmgen` and `cargo-npmgen` binaries.
2
3mod cli;
4
5use std::ffi::OsString;
6
7use clap::Parser;
8use tracing_subscriber::EnvFilter;
9
10use cli::Cli;
11
12/// Parse arguments and run a generation. Both binaries delegate here, so
13/// `npmgen …`, `cargo-npmgen …`, and `cargo npmgen …` behave identically.
14pub fn main() {
15    init_tracing();
16    let cli = Cli::parse_from(strip_cargo_subcommand(std::env::args_os()));
17    if let Err(error) = cli.into_generator().run() {
18        tracing::error!(%error, "npmgen failed");
19        std::process::exit(1);
20    }
21}
22
23fn init_tracing() {
24    tracing_subscriber::fmt()
25        .with_env_filter(
26            EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
27        )
28        .with_target(false)
29        .init();
30}
31
32/// When invoked as `cargo npmgen`, cargo runs `cargo-npmgen npmgen …`; drop the
33/// injected subcommand so the same parser serves every invocation.
34fn strip_cargo_subcommand(args: impl Iterator<Item = OsString>) -> Vec<OsString> {
35    let mut args: Vec<OsString> = args.collect();
36    if args.get(1).and_then(|arg| arg.to_str()) == Some("npmgen") {
37        args.remove(1);
38    }
39    args
40}
41
42#[cfg(test)]
43mod tests {
44    use super::strip_cargo_subcommand;
45    use std::ffi::OsString;
46
47    fn argv(parts: &[&str]) -> Vec<OsString> {
48        parts.iter().map(OsString::from).collect()
49    }
50
51    #[test]
52    fn drops_cargo_injected_subcommand() {
53        let stripped =
54            strip_cargo_subcommand(argv(&["cargo-npmgen", "npmgen", "--out", "x"]).into_iter());
55        assert_eq!(stripped, argv(&["cargo-npmgen", "--out", "x"]));
56    }
57
58    #[test]
59    fn leaves_direct_invocations_untouched() {
60        let standalone = strip_cargo_subcommand(argv(&["npmgen", "--out", "x"]).into_iter());
61        assert_eq!(standalone, argv(&["npmgen", "--out", "x"]));
62
63        let direct = strip_cargo_subcommand(argv(&["cargo-npmgen", "--out", "x"]).into_iter());
64        assert_eq!(direct, argv(&["cargo-npmgen", "--out", "x"]));
65    }
66}