Skip to content

Commit e3b7f75

Browse files
committed
Add a cargo-bootimage executable (equivalent to bootimage build)
1 parent acfc0b2 commit e3b7f75

File tree

3 files changed

+55
-38
lines changed

3 files changed

+55
-38
lines changed

src/args.rs

+44-36
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1-
use crate::{config::Config, Command};
1+
use crate::{config::Config, Command, ErrorString};
22
use std::path::{Path, PathBuf};
33
use std::{env, mem};
44

5-
pub(crate) fn parse_args() -> Command {
6-
let mut args = env::args().skip(1);
5+
pub(crate) fn parse_args() -> Result<Command, ErrorString> {
6+
let mut args = env::args();
7+
let executable_name = args.next().ok_or("no first argument (executable name)")?;
78
let first = args.next();
89
match first.as_ref().map(|s| s.as_str()) {
910
Some("build") => parse_build_args(args),
10-
Some("run") => match parse_build_args(args) {
11+
Some("bootimage") if executable_name.ends_with("cargo-bootimage") => parse_build_args(args)
12+
.map(|cmd| match cmd {
13+
Command::BuildHelp => Command::CargoBootimageHelp,
14+
cmd => cmd,
15+
}),
16+
Some("run") => parse_build_args(args).map(|cmd| match cmd {
1117
Command::Build(args) => Command::Run(args),
1218
Command::BuildHelp => Command::RunHelp,
1319
cmd => cmd,
14-
},
15-
Some("test") => match parse_build_args(args) {
20+
}),
21+
Some("test") => parse_build_args(args).map(|cmd| match cmd {
1622
Command::Build(args) => {
1723
assert_eq!(
1824
args.bin_name, None,
@@ -22,15 +28,15 @@ pub(crate) fn parse_args() -> Command {
2228
}
2329
Command::BuildHelp => Command::TestHelp,
2430
cmd => cmd,
25-
},
31+
}),
2632
Some("runner") => parse_runner_args(args),
27-
Some("--help") | Some("-h") => Command::Help,
28-
Some("--version") => Command::Version,
29-
_ => Command::NoSubcommand,
33+
Some("--help") | Some("-h") => Ok(Command::Help),
34+
Some("--version") => Ok(Command::Version),
35+
_ => Ok(Command::NoSubcommand),
3036
}
3137
}
3238

33-
fn parse_build_args<A>(args: A) -> Command
39+
fn parse_build_args<A>(args: A) -> Result<Command, ErrorString>
3440
where
3541
A: Iterator<Item = String>,
3642
{
@@ -42,12 +48,12 @@ where
4248
let mut run_args = Vec::new();
4349
let mut run_args_started = false;
4450
{
45-
fn set<T>(arg: &mut Option<T>, value: Option<T>) {
51+
fn set<T>(arg: &mut Option<T>, value: Option<T>) -> Result<(), ErrorString> {
4652
let previous = mem::replace(arg, value);
47-
assert!(
48-
previous.is_none(),
49-
"multiple arguments of same type provided"
50-
)
53+
if previous.is_some() {
54+
Err("multiple arguments of same type provided")?
55+
}
56+
Ok(())
5157
};
5258

5359
let mut arg_iter = args.into_iter();
@@ -58,14 +64,14 @@ where
5864
}
5965
match arg.as_ref() {
6066
"--help" | "-h" => {
61-
return Command::BuildHelp;
67+
return Ok(Command::BuildHelp);
6268
}
6369
"--version" => {
64-
return Command::Version;
70+
return Ok(Command::Version);
6571
}
6672
"--bin" => {
6773
let next = arg_iter.next();
68-
set(&mut bin_name, next.clone());
74+
set(&mut bin_name, next.clone())?;
6975
cargo_args.push(arg);
7076
if let Some(next) = next {
7177
cargo_args.push(next);
@@ -75,12 +81,12 @@ where
7581
set(
7682
&mut bin_name,
7783
Some(String::from(arg.trim_start_matches("--bin="))),
78-
);
84+
)?;
7985
cargo_args.push(arg);
8086
}
8187
"--target" => {
8288
let next = arg_iter.next();
83-
set(&mut target, next.clone());
89+
set(&mut target, next.clone())?;
8490
cargo_args.push(arg);
8591
if let Some(next) = next {
8692
cargo_args.push(next);
@@ -90,7 +96,7 @@ where
9096
set(
9197
&mut target,
9298
Some(String::from(arg.trim_start_matches("--target="))),
93-
);
99+
)?;
94100
cargo_args.push(arg);
95101
}
96102
"--manifest-path" => {
@@ -102,7 +108,7 @@ where
102108
.canonicalize()
103109
.expect("--manifest-path invalid")
104110
}),
105-
);
111+
)?;
106112
cargo_args.push(arg);
107113
if let Some(next) = next {
108114
cargo_args.push(next);
@@ -112,11 +118,11 @@ where
112118
let path = Path::new(arg.trim_start_matches("--manifest-path="))
113119
.canonicalize()
114120
.expect("--manifest-path invalid");
115-
set(&mut manifest_path, Some(path));
121+
set(&mut manifest_path, Some(path))?;
116122
cargo_args.push(arg);
117123
}
118124
"--release" => {
119-
set(&mut release, Some(true));
125+
set(&mut release, Some(true))?;
120126
cargo_args.push(arg);
121127
}
122128
"--" => {
@@ -129,14 +135,14 @@ where
129135
}
130136
}
131137

132-
Command::Build(Args {
138+
Ok(Command::Build(Args {
133139
cargo_args,
134140
run_args,
135141
bin_name,
136142
target,
137143
manifest_path,
138144
release: release.unwrap_or(false),
139-
})
145+
}))
140146
}
141147

142148
#[derive(Debug, Clone)]
@@ -196,42 +202,44 @@ impl Args {
196202
}
197203
}
198204

199-
fn parse_runner_args<A>(args: A) -> Command
205+
fn parse_runner_args<A>(args: A) -> Result<Command, ErrorString>
200206
where
201207
A: Iterator<Item = String>,
202208
{
203209
let mut arg_iter = args.into_iter().fuse();
204210
let executable = PathBuf::from(
205211
arg_iter
206212
.next()
207-
.expect("excepted path to kernel executable as first argument"),
213+
.ok_or("excepted path to kernel executable as first argument")?,
208214
)
209215
.canonicalize()
210-
.expect("Failed to canonicalize executable path");
216+
.map_err(|err| format!("Failed to canonicalize executable path: {}", err))?;
211217
let mut run_command = None;
212218

213219
loop {
214220
match arg_iter.next().as_ref().map(|s| s.as_str()) {
215221
Some("--command") => {
216222
let old = mem::replace(&mut run_command, Some(arg_iter.collect()));
217-
assert!(old.is_none(), "multiple `--command` arguments");
223+
if !old.is_none() {
224+
Err("multiple `--command` arguments")?;
225+
}
218226
break;
219227
}
220228
Some("--help") | Some("-h") => {
221-
return Command::RunnerHelp;
229+
return Ok(Command::RunnerHelp);
222230
}
223231
Some("--version") => {
224-
return Command::Version;
232+
return Ok(Command::Version);
225233
}
226234
None => break,
227-
Some(arg) => panic!("unexpected argument `{}`", arg),
235+
Some(arg) => Err(format!("unexpected argument `{}`", arg))?,
228236
}
229237
}
230238

231-
Command::Runner(RunnerArgs {
239+
Ok(Command::Runner(RunnerArgs {
232240
executable,
233241
run_command,
234-
})
242+
}))
235243
}
236244

237245
#[derive(Debug, Clone)]

src/bin/cargo-bootimage.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use std::process;
2+
3+
pub fn main() {
4+
if let Err(err) = bootimage::run() {
5+
eprintln!("Error: {}", err.message);
6+
process::exit(err.exit_code);
7+
}
8+
}

src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ enum Command {
1919
BuildHelp,
2020
RunHelp,
2121
TestHelp,
22+
CargoBootimageHelp,
2223
RunnerHelp,
2324
Version,
2425
}
2526

2627
pub fn run() -> Result<(), ErrorString> {
27-
let command = args::parse_args();
28+
let command = args::parse_args()?;
2829
match command {
2930
Command::Build(args) => subcommand::build::build(args),
3031
Command::Run(args) => subcommand::run::run(args),
@@ -35,8 +36,8 @@ pub fn run() -> Result<(), ErrorString> {
3536
Command::BuildHelp => Ok(help::build_help()),
3637
Command::RunHelp => Ok(help::run_help()),
3738
Command::TestHelp => Ok(help::test_help()),
38-
Command::RunnerHelp => unimplemented!(),
3939
Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))),
40+
Command::RunnerHelp | Command::CargoBootimageHelp => unimplemented!(),
4041
}
4142
}
4243

0 commit comments

Comments
 (0)