diff --git a/src/uu/lsmem/src/lsmem.rs b/src/uu/lsmem/src/lsmem.rs index e97666a..b0892ed 100644 --- a/src/uu/lsmem/src/lsmem.rs +++ b/src/uu/lsmem/src/lsmem.rs @@ -29,6 +29,7 @@ mod options { pub const PAIRS: &str = "pairs"; pub const RAW: &str = "raw"; pub const SPLIT: &str = "split"; + pub const SUMMARY: &str = "summary"; pub const SYSROOT: &str = "sysroot"; } @@ -236,6 +237,27 @@ impl MemoryBlock { } } +#[derive(Clone, Debug, PartialEq)] +enum Summary { + Never, + Always, + Only, +} + +impl ValueEnum for Summary { + fn value_variants<'a>() -> &'a [Self] { + &[Summary::Never, Summary::Always, Summary::Only] + } + + fn to_possible_value(&self) -> Option<PossibleValue> { + match self { + Summary::Never => Some(PossibleValue::new("never").help("never show summary")), + Summary::Always => Some(PossibleValue::new("always").help("always show summary")), + Summary::Only => Some(PossibleValue::new("only").help("show summary only")), + } + } +} + #[derive(Default, Serialize)] struct TableRow { range: String, @@ -750,6 +772,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if opts.json || opts.pairs || opts.raw { opts.want_summary = false; } + if let Some(summary) = matches.get_one::<Summary>(options::SUMMARY) { + match summary { + Summary::Never => opts.want_summary = false, + Summary::Only => opts.want_table = false, + Summary::Always => {} // Default (equivalent to if --summary wasn't provided at all) + } + } if let Some(sysroot) = matches.get_one::<String>(options::SYSROOT) { opts.sysmem = format!( @@ -797,7 +826,7 @@ pub fn uu_app() -> Command { .long("json") .help("use JSON output format") .action(ArgAction::SetTrue) - .conflicts_with_all([options::PAIRS, options::RAW]), + .conflicts_with_all([options::PAIRS, options::RAW, options::SUMMARY]), ) .arg( Arg::new(options::PAIRS) @@ -805,7 +834,7 @@ pub fn uu_app() -> Command { .long("pairs") .help("use key=\"value\" output format") .action(ArgAction::SetTrue) - .conflicts_with_all([options::JSON, options::RAW]), + .conflicts_with_all([options::JSON, options::RAW, options::SUMMARY]), ) .arg( Arg::new(options::ALL) @@ -852,7 +881,7 @@ pub fn uu_app() -> Command { .long("raw") .help("use raw output format") .action(ArgAction::SetTrue) - .conflicts_with_all([options::JSON, options::PAIRS]), + .conflicts_with_all([options::JSON, options::PAIRS, options::SUMMARY]), ) .arg( Arg::new(options::SPLIT) @@ -879,6 +908,19 @@ pub fn uu_app() -> Command { .action(ArgAction::Set) .value_name("dir"), ) + .arg( + Arg::new(options::SUMMARY) + .long("summary") + .help("print summary information") + .ignore_case(true) + .action(ArgAction::Set) + .value_name("when") + .value_delimiter(',') + .value_parser(EnumValueParser::<Summary>::new()) + .conflicts_with_all([options::RAW, options::PAIRS, options::JSON]) + .num_args(0..=1) + .default_missing_value("only"), + ) .after_help(&format!( "Available output columns:\n{}", Column::value_variants() diff --git a/tests/by-util/test_lsmem.rs b/tests/by-util/test_lsmem.rs index a9a6993..39b759b 100644 --- a/tests/by-util/test_lsmem.rs +++ b/tests/by-util/test_lsmem.rs @@ -144,6 +144,41 @@ fn test_split_zones() { sysroot_test_with_args("test_lsmem_split_zones.expected", &["-S", "zones"]); } +#[test] +fn test_summary_always() { + sysroot_test_with_args("test_lsmem_summary_always.expected", &["--summary=always"]); +} + +#[test] +fn test_summary_empty() { + sysroot_test_with_args("test_lsmem_summary_empty.expected", &["--summary"]); +} + +#[test] +fn test_summary_never() { + sysroot_test_with_args("test_lsmem_summary_never.expected", &["--summary=never"]); +} + +#[test] +fn test_summary_only() { + sysroot_test_with_args("test_lsmem_summary_only.expected", &["--summary=only"]); +} + +#[test] +fn test_summary_conflict_json() { + new_ucmd!().arg("--summary").arg("-J").fails().code_is(1); +} + +#[test] +fn test_summary_conflict_pairs() { + new_ucmd!().arg("--summary").arg("-P").fails().code_is(1); +} + +#[test] +fn test_summary_conflict_raw() { + new_ucmd!().arg("--summary").arg("-r").fails().code_is(1); +} + #[test] fn test_table() { sysroot_test_with_args("test_lsmem_table.expected", &[]); diff --git a/tests/fixtures/lsmem/test_lsmem_summary_always.expected b/tests/fixtures/lsmem/test_lsmem_summary_always.expected new file mode 100644 index 0000000..2f1ca26 --- /dev/null +++ b/tests/fixtures/lsmem/test_lsmem_summary_always.expected @@ -0,0 +1,7 @@ +RANGE SIZE STATE REMOVABLE BLOCK +0x0000000000000000-0x0000000037ffffff 896M online yes 0-6 +0x0000000100000000-0x00000004afffffff 14.8G online yes 32-149 + +Memory block size: 128M +Total online memory: 15.6G +Total offline memory: 0B diff --git a/tests/fixtures/lsmem/test_lsmem_summary_empty.expected b/tests/fixtures/lsmem/test_lsmem_summary_empty.expected new file mode 100644 index 0000000..6ce4160 --- /dev/null +++ b/tests/fixtures/lsmem/test_lsmem_summary_empty.expected @@ -0,0 +1,3 @@ +Memory block size: 128M +Total online memory: 15.6G +Total offline memory: 0B diff --git a/tests/fixtures/lsmem/test_lsmem_summary_never.expected b/tests/fixtures/lsmem/test_lsmem_summary_never.expected new file mode 100644 index 0000000..88dc2b9 --- /dev/null +++ b/tests/fixtures/lsmem/test_lsmem_summary_never.expected @@ -0,0 +1,3 @@ +RANGE SIZE STATE REMOVABLE BLOCK +0x0000000000000000-0x0000000037ffffff 896M online yes 0-6 +0x0000000100000000-0x00000004afffffff 14.8G online yes 32-149 diff --git a/tests/fixtures/lsmem/test_lsmem_summary_only.expected b/tests/fixtures/lsmem/test_lsmem_summary_only.expected new file mode 100644 index 0000000..6ce4160 --- /dev/null +++ b/tests/fixtures/lsmem/test_lsmem_summary_only.expected @@ -0,0 +1,3 @@ +Memory block size: 128M +Total online memory: 15.6G +Total offline memory: 0B