1mod 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
16pub 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 ¤t_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(¤t_dir),
54 },
55 )?;
56 let artifact = build::run(&BuildRequest {
57 selection: &selection,
58 current_dir: ¤t_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}