Skip to content

Commit 2f0ed95

Browse files
authored
du: Flags 'm', 'k', 'm' should be POSIX style overriden (#10664)
* du: Flags 'm', 'k', 'm' should be POSIX style overriden * du: overwriting b flag doesnt deactivate --apparent-size
1 parent da1d3a1 commit 2f0ed95

2 files changed

Lines changed: 129 additions & 6 deletions

File tree

src/uu/du/src/du.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,40 @@ fn read_files_from(file_name: &OsStr) -> Result<Vec<PathBuf>, std::io::Error> {
963963
Ok(paths)
964964
}
965965

966+
fn get_block_size_arg_index_if_present(matches: &ArgMatches, flag: &str) -> Option<usize> {
967+
if matches.get_flag(flag) {
968+
// Indices of returns index even if flag is not present, thats why we need to if guard it
969+
matches
970+
.indices_of(flag)
971+
.and_then(|mut indices| indices.next_back())
972+
} else {
973+
None
974+
}
975+
}
976+
977+
fn handle_block_size_arg_override(matches: &ArgMatches) -> Option<SizeFormat> {
978+
let candidates = [
979+
(
980+
SizeFormat::BlockSize(1),
981+
get_block_size_arg_index_if_present(matches, options::BYTES),
982+
),
983+
(
984+
SizeFormat::BlockSize(1024),
985+
get_block_size_arg_index_if_present(matches, options::BLOCK_SIZE_1K),
986+
),
987+
(
988+
SizeFormat::BlockSize(1024 * 1024),
989+
get_block_size_arg_index_if_present(matches, options::BLOCK_SIZE_1M),
990+
),
991+
];
992+
993+
candidates
994+
.into_iter()
995+
.filter(|(_, idx)| idx.is_some())
996+
.max_by_key(|&(_, idx)| idx.unwrap_or(0))
997+
.map(|(size_format, _)| size_format)
998+
}
999+
9661000
#[uucore::main]
9671001
#[allow(clippy::cognitive_complexity)]
9681002
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
@@ -1018,12 +1052,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
10181052
SizeFormat::HumanBinary
10191053
} else if matches.get_flag(options::SI) {
10201054
SizeFormat::HumanDecimal
1021-
} else if matches.get_flag(options::BYTES) {
1022-
SizeFormat::BlockSize(1)
1023-
} else if matches.get_flag(options::BLOCK_SIZE_1K) {
1024-
SizeFormat::BlockSize(1024)
1025-
} else if matches.get_flag(options::BLOCK_SIZE_1M) {
1026-
SizeFormat::BlockSize(1024 * 1024)
1055+
} else if let Some(size_format) = handle_block_size_arg_override(&matches) {
1056+
size_format
10271057
} else {
10281058
let block_size_str = matches.get_one::<String>(options::BLOCK_SIZE);
10291059
let block_size = read_block_size(block_size_str.map(AsRef::as_ref))?;

tests/by-util/test_du.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2058,3 +2058,96 @@ fn test_du_symlinks_multiple_links_in_args() {
20582058
result.stdout_contains("dir1/file");
20592059
result.stdout_does_not_contain("dir1/link");
20602060
}
2061+
2062+
#[test]
2063+
fn test_block_size_args_override() {
2064+
let ts = TestScenario::new(util_name!());
2065+
let at = &ts.fixtures;
2066+
let dir = "override_args_dir";
2067+
2068+
at.mkdir(dir);
2069+
let fpath = at.plus(format!("{dir}/file"));
2070+
std::fs::File::create(fpath)
2071+
.expect("cannot create test file")
2072+
.set_len(100_000_000)
2073+
.expect("cannot set file size");
2074+
2075+
let fpath2 = at.plus(format!("{dir}/file_2"));
2076+
std::fs::File::create(fpath2)
2077+
.expect("cannot create test file")
2078+
.set_len(100_000_000)
2079+
.expect("cannot set file size");
2080+
2081+
let test_cases = [
2082+
(["-sk", "-m"], "-sm"),
2083+
(["-sk", "-b"], "-sb"),
2084+
(["-sm", "-k"], "-sk"),
2085+
];
2086+
2087+
for (idx, (overwriting_args, expected)) in test_cases.into_iter().enumerate() {
2088+
let overridden_args = ts
2089+
.ucmd()
2090+
.arg(dir)
2091+
.args(&overwriting_args)
2092+
.succeeds()
2093+
.stdout_move_str();
2094+
2095+
let single_args = ts
2096+
.ucmd()
2097+
.arg(dir)
2098+
.arg(expected)
2099+
.succeeds()
2100+
.stdout_move_str();
2101+
2102+
assert_eq!(
2103+
overridden_args, single_args,
2104+
"The last argument of m, k and b should overwrite. Run: {idx}"
2105+
);
2106+
}
2107+
}
2108+
2109+
#[test]
2110+
fn test_block_override_b_still_has_apparent_size() {
2111+
let ts = TestScenario::new(util_name!());
2112+
let at = &ts.fixtures;
2113+
let dir = "override_args_dir";
2114+
2115+
at.mkdir(dir);
2116+
let fpath = at.plus(format!("{dir}/file"));
2117+
std::fs::File::create(fpath)
2118+
.expect("cannot create test file")
2119+
.set_len(100_000_000)
2120+
.expect("cannot set file size");
2121+
2122+
let fpath2 = at.plus(format!("{dir}/file_2"));
2123+
std::fs::File::create(fpath2)
2124+
.expect("cannot create test file")
2125+
.set_len(100_000_000)
2126+
.expect("cannot set file size");
2127+
2128+
let test_cases = [
2129+
(["-sb", "-m"], ["-sm", "--apparent-size"]),
2130+
(["-sb", "-k"], ["-sk", "--apparent-size"]),
2131+
];
2132+
2133+
for (idx, (overwriting_args, expected)) in test_cases.into_iter().enumerate() {
2134+
let overridden_args = ts
2135+
.ucmd()
2136+
.arg(dir)
2137+
.args(&overwriting_args)
2138+
.succeeds()
2139+
.stdout_move_str();
2140+
2141+
let single_args = ts
2142+
.ucmd()
2143+
.arg(dir)
2144+
.args(&expected)
2145+
.succeeds()
2146+
.stdout_move_str();
2147+
2148+
assert_eq!(
2149+
overridden_args, single_args,
2150+
"Overwriting the b flag should still leave --apparent-size active. Run: {idx}"
2151+
);
2152+
}
2153+
}

0 commit comments

Comments
 (0)