Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/uu/df/src/df.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ static OPT_HUMAN_READABLE_DECIMAL: &str = "human-readable-decimal";
static OPT_INODES: &str = "inodes";
static OPT_KILO: &str = "kilo";
static OPT_MEGA: &str = "mega";
/// `-B`, `-h`, `-H`, `-k` and `-m` all pick how sizes are shown. Like GNU df,
/// whichever comes last on the command line wins, so each overrides the others.
static SIZE_OPTIONS: [&str; 5] = [
"blocksize",
"human-readable-binary",
"human-readable-decimal",
"kilo",
"mega",
];
static OPT_LOCAL: &str = "local";
static OPT_NO_SYNC: &str = "no-sync";
static OPT_OUTPUT: &str = "output";
Expand Down Expand Up @@ -564,7 +573,7 @@ pub fn uu_app() -> Command {
.short('B')
.long(OPT_BLOCKSIZE_LONG)
.value_name("SIZE")
.overrides_with_all([OPT_KILO, OPT_MEGA, OPT_BLOCKSIZE])
.overrides_with_all(SIZE_OPTIONS)
.help(translate!("df-help-block-size")),
)
.arg(
Expand All @@ -578,15 +587,15 @@ pub fn uu_app() -> Command {
Arg::new(OPT_HUMAN_READABLE_BINARY)
.short('h')
.long("human-readable")
.overrides_with_all([OPT_HUMAN_READABLE_DECIMAL, OPT_HUMAN_READABLE_BINARY])
.overrides_with_all(SIZE_OPTIONS)
.help(translate!("df-help-human-readable"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(OPT_HUMAN_READABLE_DECIMAL)
.short('H')
.long("si")
.overrides_with_all([OPT_HUMAN_READABLE_BINARY, OPT_HUMAN_READABLE_DECIMAL])
.overrides_with_all(SIZE_OPTIONS)
.help(translate!("df-help-si"))
.action(ArgAction::SetTrue),
)
Expand All @@ -602,14 +611,14 @@ pub fn uu_app() -> Command {
Arg::new(OPT_KILO)
.short('k')
.help(translate!("df-help-kilo"))
.overrides_with_all([OPT_BLOCKSIZE, OPT_KILO, OPT_MEGA])
.overrides_with_all(SIZE_OPTIONS)
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(OPT_MEGA)
.short('m')
.help(translate!("df-help-mega"))
.overrides_with_all([OPT_BLOCKSIZE, OPT_KILO, OPT_MEGA])
.overrides_with_all(SIZE_OPTIONS)
.action(ArgAction::SetTrue),
)
.arg(
Expand Down
37 changes: 37 additions & 0 deletions tests/by-util/test_df.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,43 @@ fn test_block_size_1m_option_with_output() {
}
}

#[test]
fn test_last_size_option_wins() {
// GNU df 9.11: -B, -h, -H, -k and -m override each other, the last one wins.
for (args, expected) in [
(&["-h", "-B", "1K"][..], "1K-blocks"),
(&["-B", "1K", "-h"][..], "Size"),
(&["-h", "-k"][..], "1K-blocks"),
(&["-k", "-h"][..], "Size"),
(&["-H", "-k"][..], "1K-blocks"),
(&["-k", "-H"][..], "Size"),
(&["-h", "-m"][..], "1M-blocks"),
(&["-m", "-h"][..], "Size"),
] {
let output = new_ucmd!()
.args(args)
.arg("--output=size")
.succeeds()
.stdout_str_lossy();
let header = output.lines().next().unwrap().trim();

assert_eq!(header, expected, "df {}", args.join(" "));
}
}

#[test]
fn test_block_size_after_human_readable_sets_the_values() {
// The header alone would pass if only the header code followed the order,
// so also check the value is a plain block count, not a human size like "461G".
let output = new_ucmd!()
.args(&["-h", "-B", "1", "--output=size", "."])
.succeeds()
.stdout_str_lossy();
let value = output.lines().nth(1).unwrap().trim();

assert!(value.chars().all(|c| c.is_ascii_digit()), "got {value}");
}

#[test]
fn test_block_size_with_suffix() {
fn get_header(block_size: &str) -> String {
Expand Down
Loading