Skip to main content

cargo_elfpak/
lib.rs

1//! Cargo project adapter for `elfpak`.
2
3mod build;
4mod cli;
5mod metadata;
6
7use crate::{
8    build::BuildRequest,
9    cli::{CargoCommand, Cli, Command},
10    metadata::SelectionContext,
11};
12use anyhow::Result;
13use clap::Parser;
14use std::{ffi::OsString, path::PathBuf};
15
16/// Run the Cargo subcommand and return a process exit code.
17pub fn run() -> std::process::ExitCode {
18    let mut args: Vec<OsString> = std::env::args_os().collect();
19    if args.get(1).is_none_or(|argument| argument != "elfpak") {
20        args.insert(1, OsString::from("elfpak"));
21    }
22    let cli = match Cli::try_parse_from(args) {
23        Ok(cli) => cli,
24        Err(error) => error.exit(),
25    };
26
27    match try_run(cli) {
28        Ok(status) => status,
29        Err(error) => {
30            eprintln!("error:\n  {error:#}");
31            std::process::ExitCode::FAILURE
32        }
33    }
34}
35
36fn try_run(cli: Cli) -> Result<std::process::ExitCode> {
37    let CargoCommand::Elfpak(elfpak) = cli.command;
38    let Command::Bundle(args) = elfpak.command;
39    let current_dir = std::env::current_dir()?;
40    let metadata = metadata::load(
41        &current_dir,
42        args.manifest_path.as_deref(),
43        args.locked,
44        args.offline,
45        args.frozen,
46    )?;
47    let selection = metadata::select(
48        &metadata,
49        &SelectionContext {
50            package: args.package,
51            binary: args.bin,
52            manifest_path: args.manifest_path.clone(),
53            current_dir: PathBuf::from(&current_dir),
54        },
55    )?;
56    let artifact = build::run(&BuildRequest {
57        selection: &selection,
58        current_dir: &current_dir,
59        manifest_path: args.manifest_path.as_deref(),
60        release: args.release,
61        profile: args.profile.as_deref(),
62        target: args.target.as_deref(),
63        target_dir: args.target_dir.as_deref(),
64        features: &args.features,
65        all_features: args.all_features,
66        no_default_features: args.no_default_features,
67        locked: args.locked,
68        offline: args.offline,
69        frozen: args.frozen,
70        quiet: cli.quiet,
71    })?;
72
73    if !cli.quiet {
74        let state = if artifact.fresh { "fresh" } else { "built" };
75        println!("{state} Cargo binary: {}", artifact.executable.display());
76    }
77    Ok(elfpak::run_bundle(
78        args.bundle,
79        artifact.executable,
80        cli.quiet,
81        cli.verbose,
82    ))
83}