mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
Merge pull request #3369 from cakebaker/ticket_3302
df: show error if same type is included & excluded
This commit is contained in:
commit
bc7c9c1659
2 changed files with 50 additions and 18 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue