Skip to content

Commit 79b6698

Browse files
authored
Merge pull request #208 from keszybz/version-updates
Update to latest clap and other dependencies, rework clap setup
2 parents 99df8fc + 2d4e130 commit 79b6698

File tree

3 files changed

+76
-29
lines changed

3 files changed

+76
-29
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ exclude = ["tests/07a-mount-point-excl", "tests/10-example"]
1414

1515
[dependencies]
1616
anyhow = "1.0.12"
17-
clap = { version = "2.33", default-features = false }
17+
clap = { version = "4.5", default-features = false, features = ["std", "cargo", "help" , "error-context"] }
1818
liboverdrop = "0.1.0"
1919
rust-ini = ">=0.15, <0.18"
2020
log = { version = "0.4", features = ["std"] }
2121
fasteval = { version = "0.2", default-features = false }
22+
indoc = "2.0.5"
2223

2324
[dev-dependencies]
2425
tempfile = "3"

src/main.rs

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod kernlog;
66
mod setup;
77

88
use anyhow::Result;
9-
use clap::{crate_description, crate_name, crate_version, App, Arg};
9+
use indoc::indoc;
1010
use log::{info, LevelFilter};
1111
use std::borrow::Cow;
1212
use std::env;
@@ -22,38 +22,41 @@ enum Opts {
2222
ResetDevice(String),
2323
}
2424

25-
fn get_opts() -> Opts {
26-
let opts = App::new(crate_name!())
27-
.version(crate_version!())
28-
.about(crate_description!())
25+
#[rustfmt::skip]
26+
fn command() -> clap::Command {
27+
clap::command!()
28+
.override_usage(indoc! {"
29+
zram-generator --setup-device <device>
30+
zram-generator --reset-device <device>
31+
zram-generator dir1 [dir2 dir3]
32+
"})
33+
.arg(
34+
clap::arg!(--"setup-device" <device> "Set up a single device")
35+
.conflicts_with("reset-device")
36+
)
2937
.arg(
30-
Arg::from_usage("--setup-device 'Set up a single device'")
31-
.conflicts_with("reset-device"),
38+
clap::arg!(--"reset-device" <device> "Reset (destroy) a device")
3239
)
33-
.arg(Arg::from_usage("--reset-device 'Reset (destroy) a device'"))
34-
.arg(Arg::from_usage(
35-
"<directory|device> 'Target directory for generator or device to operate on'",
36-
))
3740
.arg(
38-
Arg::from_usage(
39-
"[extra-dir] 'Unused target directories to satisfy systemd.generator(5)'",
40-
)
41-
.number_of_values(2)
42-
.conflicts_with_all(&["setup-device", "reset-device"]),
41+
clap::arg!([dir] "Target directory to write output to and two optional\n\
42+
unused directories to satisfy systemd.generator(5)")
43+
.num_args(1..=3)
44+
.conflicts_with_all(["setup-device", "reset-device"])
45+
.required_unless_present_any(["setup-device", "reset-device"])
4346
)
44-
.after_help(&*format!("Uses {}.", setup::SYSTEMD_MAKEFS_COMMAND))
45-
.get_matches();
46-
47-
let val = opts
48-
.value_of("directory|device")
49-
.expect("clap invariant")
50-
.to_string();
51-
if opts.is_present("setup-device") {
52-
Opts::SetupDevice(val)
53-
} else if opts.is_present("reset-device") {
54-
Opts::ResetDevice(val)
47+
.after_help(setup::AFTER_HELP)
48+
}
49+
50+
fn get_opts() -> Opts {
51+
let opts = command().get_matches();
52+
53+
if let Some(val) = opts.get_one::<String>("setup-device") {
54+
Opts::SetupDevice(val.clone())
55+
} else if let Some(val) = opts.get_one::<String>("reset-device") {
56+
Opts::ResetDevice(val.clone())
5557
} else {
56-
Opts::GenerateUnits(val)
58+
let val = opts.get_one::<String>("dir").expect("clap invariant");
59+
Opts::GenerateUnits(val.clone())
5760
}
5861
}
5962

@@ -91,3 +94,41 @@ fn main() -> Result<()> {
9194
}
9295
}
9396
}
97+
98+
#[cfg(test)]
99+
mod tests {
100+
use super::*;
101+
102+
#[test]
103+
fn verify_app() {
104+
command().debug_assert();
105+
}
106+
107+
#[test]
108+
fn parse_setup_device() {
109+
let m = command().get_matches_from(vec!["prog", "--setup-device", "/dev/zram1"]);
110+
assert_eq!(m.get_one::<String>("setup-device").unwrap(), "/dev/zram1");
111+
}
112+
113+
#[test]
114+
fn parse_reset_device() {
115+
let m = command().get_matches_from(vec!["prog", "--reset-device", "/dev/zram1"]);
116+
assert_eq!(m.get_one::<String>("reset-device").unwrap(), "/dev/zram1");
117+
}
118+
119+
#[test]
120+
fn parse_with_dir() {
121+
let m = command().get_matches_from(vec!["prog", "/dir1"]);
122+
assert!(m.get_one::<String>("setup-device").is_none());
123+
assert!(m.get_one::<String>("reset-device").is_none());
124+
assert_eq!(m.get_one::<String>("dir").unwrap(), "/dir1");
125+
}
126+
127+
#[test]
128+
fn parse_with_dirs() {
129+
let m = command().get_matches_from(vec!["prog", "/dir1", "/dir2", "/dir3"]);
130+
assert!(m.get_one::<String>("setup-device").is_none());
131+
assert!(m.get_one::<String>("reset-device").is_none());
132+
assert_eq!(m.get_one::<String>("dir").unwrap(), "/dir1");
133+
}
134+
}

src/setup.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ pub const SYSTEMD_MAKEFS_COMMAND: &str = concat!(
1818
),
1919
"/systemd-makefs"
2020
);
21+
/// A constant string for use in clap --help output.
22+
#[rustfmt::skip]
23+
pub const AFTER_HELP: &str = concat!(
24+
"Uses ", env!("SYSTEMD_UTIL_DIR"), "/systemd-makefs", "."
25+
);
2126

2227
pub fn run_device_setup(device: Option<Device>, device_name: &str) -> Result<()> {
2328
let device = device.ok_or_else(|| anyhow!("Device {} not found", device_name))?;

0 commit comments

Comments
 (0)