Merge branch 'uutils:main' into shuf-gnu-test

This commit is contained in:
DevSabb 2022-03-28 12:56:38 -04:00 committed by GitHub
commit 36ec76e1fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 96 additions and 7 deletions

View file

@ -243,7 +243,10 @@ fn get_all_filesystems(opt: &Options) -> Vec<Filesystem> {
// Convert each `MountInfo` into a `Filesystem`, which contains
// both the mount information and usage information.
mounts.into_iter().filter_map(Filesystem::new).collect()
mounts
.into_iter()
.filter_map(|m| Filesystem::new(m, None))
.collect()
}
/// For each path, get the filesystem that contains that path.
@ -385,7 +388,10 @@ pub fn uu_app<'a>() -> Command<'a> {
Arg::new(OPT_OUTPUT)
.long("output")
.takes_value(true)
.min_values(0)
.require_equals(true)
.use_value_delimiter(true)
.multiple_occurrences(true)
.possible_values(OUTPUT_FIELD_LIST)
.default_missing_values(&OUTPUT_FIELD_LIST)
.default_values(&["source", "size", "used", "avail", "pcent", "target"])

View file

@ -23,6 +23,13 @@ use uucore::fsext::{FsUsage, MountInfo};
/// space available on the filesystem and the amount of space used.
#[derive(Debug, Clone)]
pub(crate) struct Filesystem {
/// The file given on the command line if any.
///
/// When invoking `df` with a positional argument, it displays
/// usage information for the filesystem that contains the given
/// file. If given, this field contains that filename.
pub file: Option<String>,
/// Information about the mounted device, mount directory, and related options.
pub mount_info: MountInfo,
@ -66,7 +73,7 @@ where
impl Filesystem {
// TODO: resolve uuid in `mount_info.dev_name` if exists
pub(crate) fn new(mount_info: MountInfo) -> Option<Self> {
pub(crate) fn new(mount_info: MountInfo, file: Option<String>) -> Option<Self> {
let _stat_path = if !mount_info.mount_dir.is_empty() {
mount_info.mount_dir.clone()
} else {
@ -84,7 +91,11 @@ impl Filesystem {
let usage = FsUsage::new(statfs(_stat_path).ok()?);
#[cfg(windows)]
let usage = FsUsage::new(Path::new(&_stat_path));
Some(Self { mount_info, usage })
Some(Self {
mount_info,
usage,
file,
})
}
/// Find and create the filesystem that best matches a given path.
@ -107,11 +118,12 @@ impl Filesystem {
where
P: AsRef<Path>,
{
let file = path.as_ref().display().to_string();
let canonicalize = true;
let mount_info = mount_info_from_path(mounts, path, canonicalize)?;
// TODO Make it so that we do not need to clone the `mount_info`.
let mount_info = (*mount_info).clone();
Self::new(mount_info)
Self::new(mount_info, Some(file))
}
}

View file

@ -24,6 +24,9 @@ use std::ops::AddAssign;
/// A row comprises several pieces of information, including the
/// filesystem device, the mountpoint, the number of bytes used, etc.
pub(crate) struct Row {
/// The filename given on the command-line, if given.
file: Option<String>,
/// Name of the device on which the filesystem lives.
fs_device: String,
@ -73,6 +76,7 @@ pub(crate) struct Row {
impl Row {
pub(crate) fn new(source: &str) -> Self {
Self {
file: None,
fs_device: source.into(),
fs_type: "-".into(),
fs_mount: "-".into(),
@ -101,6 +105,7 @@ impl AddAssign for Row {
let inodes = self.inodes + rhs.inodes;
let inodes_used = self.inodes_used + rhs.inodes_used;
*self = Self {
file: None,
fs_device: "total".into(),
fs_type: "-".into(),
fs_mount: "-".into(),
@ -145,6 +150,7 @@ impl From<Filesystem> for Row {
..
} = fs.usage;
Self {
file: fs.file,
fs_device: dev_name,
fs_type,
fs_mount: mount_dir,
@ -246,8 +252,9 @@ impl fmt::Display for DisplayRow<'_> {
Column::Ipcent => {
write!(f, "{0: >5} ", DisplayRow::percentage(self.row.inodes_usage))?;
}
// TODO Implement this.
Column::File => {}
Column::File => {
write!(f, "{0: <16}", self.row.file.as_ref().unwrap_or(&"-".into()))?;
}
Column::Fstype => write!(f, "{0: <5} ", self.row.fs_type)?,
#[cfg(target_os = "macos")]
Column::Capacity => write!(
@ -406,6 +413,7 @@ mod tests {
..Default::default()
};
let row = Row {
file: Some("/path/to/file".to_string()),
fs_device: "my_device".to_string(),
fs_type: "my_type".to_string(),
fs_mount: "my_mount".to_string(),
@ -437,6 +445,7 @@ mod tests {
..Default::default()
};
let row = Row {
file: Some("/path/to/file".to_string()),
fs_device: "my_device".to_string(),
fs_type: "my_type".to_string(),
fs_mount: "my_mount".to_string(),
@ -468,6 +477,7 @@ mod tests {
..Default::default()
};
let row = Row {
file: Some("/path/to/file".to_string()),
fs_device: "my_device".to_string(),
fs_type: "my_type".to_string(),
fs_mount: "my_mount".to_string(),
@ -499,6 +509,7 @@ mod tests {
..Default::default()
};
let row = Row {
file: Some("/path/to/file".to_string()),
fs_device: "my_device".to_string(),
fs_type: "my_type".to_string(),
fs_mount: "my_mount".to_string(),
@ -530,6 +541,7 @@ mod tests {
..Default::default()
};
let row = Row {
file: Some("/path/to/file".to_string()),
fs_device: "my_device".to_string(),
fs_type: "my_type".to_string(),
fs_mount: "my_mount".to_string(),
@ -560,6 +572,7 @@ mod tests {
..Default::default()
};
let row = Row {
file: Some("/path/to/file".to_string()),
fs_device: "my_device".to_string(),
fs_type: "my_type".to_string(),
fs_mount: "my_mount".to_string(),

View file

@ -80,6 +80,11 @@ fn test_output_option() {
new_ucmd!().arg("--output=invalid_option").fails();
}
#[test]
fn test_output_option_without_equals_sign() {
new_ucmd!().arg("--output").arg(".").succeeds();
}
#[test]
fn test_type_option() {
new_ucmd!().args(&["-t", "ext4", "-t", "ext3"]).succeeds();
@ -222,4 +227,57 @@ fn test_output_selects_columns() {
);
}
// ToDO: more tests...
#[test]
fn test_output_multiple_occurrences() {
let output = new_ucmd!()
.args(&["--output=source", "--output=target"])
.succeeds()
.stdout_move_str();
assert_eq!(
output.lines().next().unwrap(),
"Filesystem Mounted on "
);
}
// TODO Fix the spacing.
#[test]
fn test_output_file_all_filesystems() {
// When run with no positional arguments, `df` lets "-" represent
// the "File" entry for each row.
let output = new_ucmd!()
.arg("--output=file")
.succeeds()
.stdout_move_str();
let mut lines = output.lines();
assert_eq!(lines.next().unwrap(), "File ");
for line in lines {
assert_eq!(line, "- ");
}
}
// TODO Fix the spacing.
#[test]
fn test_output_file_specific_files() {
// Create three files.
let (at, mut ucmd) = at_and_ucmd!();
at.touch("a");
at.touch("b");
at.touch("c");
// When run with positional arguments, the filesystems should
// appear in the "File" column.
let output = ucmd
.args(&["--output=file", "a", "b", "c"])
.succeeds()
.stdout_move_str();
let actual: Vec<&str> = output.lines().collect();
assert_eq!(
actual,
vec![
"File ",
"a ",
"b ",
"c "
]
);
}