1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 11:07:44 +00:00

Merge pull request #3369 from cakebaker/ticket_3302

df: show error if same type is included & excluded
This commit is contained in:
Sylvestre Ledru 2022-04-06 09:08:38 +02:00 committed by GitHub
commit bc7c9c1659
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 18 deletions

View file

@ -111,6 +111,8 @@ enum OptionsError {
/// An error getting the columns to display in the output table. /// An error getting the columns to display in the output table.
ColumnError(ColumnError), ColumnError(ColumnError),
FilesystemTypeBothSelectedAndExcluded(Vec<String>),
} }
impl fmt::Display for OptionsError { impl fmt::Display for OptionsError {
@ -126,6 +128,16 @@ impl fmt::Display for OptionsError {
"option --output: field {} used more than once", "option --output: field {} used more than once",
s.quote() s.quote()
), ),
Self::FilesystemTypeBothSelectedAndExcluded(types) => {
for t in types {
eprintln!(
"{}: file system type {} both selected and excluded",
uucore::util_name(),
t.quote()
);
}
Ok(())
}
} }
} }
} }
@ -133,18 +145,39 @@ impl fmt::Display for OptionsError {
impl Options { impl Options {
/// Convert command-line arguments into [`Options`]. /// Convert command-line arguments into [`Options`].
fn from(matches: &ArgMatches) -> Result<Self, OptionsError> { fn from(matches: &ArgMatches) -> Result<Self, OptionsError> {
let include = matches.values_of_lossy(OPT_TYPE);
let exclude = matches.values_of_lossy(OPT_EXCLUDE_TYPE);
if let (Some(include), Some(exclude)) = (&include, &exclude) {
if let Some(types) = Self::get_intersected_types(include, exclude) {
return Err(OptionsError::FilesystemTypeBothSelectedAndExcluded(types));
}
}
Ok(Self { Ok(Self {
show_local_fs: matches.is_present(OPT_LOCAL), show_local_fs: matches.is_present(OPT_LOCAL),
show_all_fs: matches.is_present(OPT_ALL), show_all_fs: matches.is_present(OPT_ALL),
show_listed_fs: false, show_listed_fs: false,
block_size: block_size_from_matches(matches) block_size: block_size_from_matches(matches)
.map_err(|_| OptionsError::InvalidBlockSize)?, .map_err(|_| OptionsError::InvalidBlockSize)?,
include: matches.values_of_lossy(OPT_TYPE), include,
exclude: matches.values_of_lossy(OPT_EXCLUDE_TYPE), exclude,
show_total: matches.is_present(OPT_TOTAL), show_total: matches.is_present(OPT_TOTAL),
columns: Column::from_matches(matches).map_err(OptionsError::ColumnError)?, columns: Column::from_matches(matches).map_err(OptionsError::ColumnError)?,
}) })
} }
fn get_intersected_types(include: &[String], exclude: &[String]) -> Option<Vec<String>> {
let mut intersected_types = Vec::new();
for t in include {
if exclude.contains(t) {
intersected_types.push(t.clone());
}
}
(!intersected_types.is_empty()).then(|| intersected_types)
}
} }
/// Whether to display the mount info given the inclusion settings. /// Whether to display the mount info given the inclusion settings.
@ -708,22 +741,6 @@ mod tests {
let m = mount_info("ext4", "/mnt/foo", false, false); let m = mount_info("ext4", "/mnt/foo", false, false);
assert!(is_included(&m, &opt)); assert!(is_included(&m, &opt));
} }
#[test]
fn test_include_and_exclude_match_both() {
// TODO The same filesystem type in both `include` and
// `exclude` should cause an error, but currently does
// not.
let include = Some(vec![String::from("ext4")]);
let exclude = Some(vec![String::from("ext4")]);
let opt = Options {
include,
exclude,
..Default::default()
};
let m = mount_info("ext4", "/mnt/foo", false, false);
assert!(!is_included(&m, &opt));
}
} }
mod filter_mount_list { mod filter_mount_list {

View file

@ -95,6 +95,21 @@ fn test_exclude_type_option() {
new_ucmd!().args(&["-x", "ext4", "-x", "ext3"]).succeeds(); new_ucmd!().args(&["-x", "ext4", "-x", "ext3"]).succeeds();
} }
#[test]
fn test_include_exclude_same_type() {
new_ucmd!()
.args(&["-t", "ext4", "-x", "ext4"])
.fails()
.stderr_is("df: file system type 'ext4' both selected and excluded");
new_ucmd!()
.args(&["-t", "ext4", "-x", "ext4", "-t", "ext3", "-x", "ext3"])
.fails()
.stderr_is(
"df: file system type 'ext4' both selected and excluded\n\
df: file system type 'ext3' both selected and excluded",
);
}
#[test] #[test]
fn test_total() { fn test_total() {
// Example output: // Example output: