diff --git a/Cargo.lock b/Cargo.lock index 1a387ffb9..f42949d02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -604,9 +604,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fd7173631a4e9e2ca8b32ae2fad58aab9843ea5aaf56642661937d87e28a3e" +checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17" dependencies = [ "bitflags", "crossterm_winapi", @@ -1165,14 +1165,15 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.14" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" dependencies = [ "libc", "log", "miow", "ntapi", + "wasi 0.11.0+wasi-snapshot-preview1", "winapi 0.3.9", ] @@ -1682,6 +1683,19 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "remove_dir_all" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882f368737489ea543bc5c340e6f3d34a28c39980bd9a979e47322b26f60ac40" +dependencies = [ + "libc", + "log", + "num_cpus", + "rayon", + "winapi 0.3.9", +] + [[package]] name = "retain_mut" version = "0.1.2" @@ -1810,9 +1824,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" dependencies = [ "libc", "mio 0.7.14", @@ -1920,7 +1934,7 @@ dependencies = [ "fastrand", "libc", "redox_syscall", - "remove_dir_all", + "remove_dir_all 0.5.3", "winapi 0.3.9", ] @@ -2287,6 +2301,7 @@ version = "0.0.13" dependencies = [ "clap 3.1.8", "number_prefix", + "unicode-width", "uucore", ] @@ -2754,7 +2769,7 @@ name = "uu_rm" version = "0.0.13" dependencies = [ "clap 3.1.8", - "remove_dir_all", + "remove_dir_all 0.7.0", "uucore", "walkdir", "winapi 0.3.9", diff --git a/README.md b/README.md index f6df9fdcf..2dfffa017 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,6 @@ Both can also be generated locally, the instructions for that can be found in th uutils follows Rust's release channels and is tested against stable, beta and nightly. The current oldest supported version of the Rust compiler is `1.56`. -On both Windows and Redox, only the nightly version is tested currently. - ## Building There are currently two methods to build the uutils binaries: either Cargo diff --git a/deny.toml b/deny.toml index dea3503de..8b3057870 100644 --- a/deny.toml +++ b/deny.toml @@ -61,6 +61,8 @@ highlight = "all" # introduces it. # spell-checker: disable skip = [ + # getrandom + { name = "wasi", version="0.10.2+wasi-snapshot-preview1" }, # blake2d_simd { name = "arrayvec", version = "=0.7.2" }, # flimit/unix_socket @@ -76,6 +78,8 @@ skip = [ { name = "cpp_common", version = "=0.4.0" }, # quickcheck { name = "env_logger", version = "=0.8.4" }, + # tempfile + { name = "remove_dir_all", version = "=0.5.3" }, # cpp_* { name = "memchr", version = "=1.0.2" }, { name = "quote", version = "=0.3.15" }, diff --git a/src/uu/df/Cargo.toml b/src/uu/df/Cargo.toml index c6a1c570b..1020b71bb 100644 --- a/src/uu/df/Cargo.toml +++ b/src/uu/df/Cargo.toml @@ -18,6 +18,7 @@ path = "src/df.rs" clap = { version = "3.1", features = ["wrap_help", "cargo"] } number_prefix = "0.4" uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["libc", "fsext"] } +unicode-width = "0.1.9" [[bin]] name = "df" diff --git a/src/uu/df/src/df.rs b/src/uu/df/src/df.rs index ce6804770..b4f3457c4 100644 --- a/src/uu/df/src/df.rs +++ b/src/uu/df/src/df.rs @@ -287,6 +287,7 @@ fn get_all_filesystems(opt: &Options) -> Vec { mounts .into_iter() .filter_map(|m| Filesystem::new(m, None)) + .filter(|fs| opt.show_all_fs || fs.usage.blocks > 0) .collect() } @@ -362,7 +363,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let filesystems = get_all_filesystems(&opt); if filesystems.is_empty() { - return Err(USimpleError::new(1, "No file systems processed")); + return Err(USimpleError::new(1, "no file systems processed")); } filesystems diff --git a/src/uu/df/src/table.rs b/src/uu/df/src/table.rs index 698da2bdb..abac3b549 100644 --- a/src/uu/df/src/table.rs +++ b/src/uu/df/src/table.rs @@ -8,6 +8,7 @@ //! A table ([`Table`]) comprises a header row ([`Header`]) and a //! collection of data rows ([`Row`]), one per filesystem. use number_prefix::NumberPrefix; +use unicode_width::UnicodeWidthStr; use crate::columns::{Alignment, Column}; use crate::filesystem::Filesystem; @@ -362,8 +363,8 @@ impl Table { total += row; for (i, value) in values.iter().enumerate() { - if value.len() > widths[i] { - widths[i] = value.len(); + if UnicodeWidthStr::width(value.as_str()) > widths[i] { + widths[i] = UnicodeWidthStr::width(value.as_str()); } } @@ -400,12 +401,21 @@ impl fmt::Display for Table { while let Some(row) = row_iter.next() { let mut col_iter = row.iter().enumerate().peekable(); while let Some((i, elem)) = col_iter.next() { + let is_last_col = col_iter.peek().is_none(); + match self.alignments[i] { - Alignment::Left => write!(f, "{: { + if is_last_col { + // no trailing spaces in last column + write!(f, "{}", elem)?; + } else { + write!(f, "{: write!(f, "{:>width$}", elem, width = self.widths[i])?, } - if col_iter.peek().is_some() { + if !is_last_col { // column separator write!(f, " ")?; } diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index 630f3a294..77d221e39 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -17,7 +17,7 @@ path = "src/rm.rs" [dependencies] clap = { version = "3.1", features = ["wrap_help", "cargo"] } walkdir = "2.2" -remove_dir_all = "0.5.1" +remove_dir_all = "0.7.0" uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] } [target.'cfg(windows)'.dependencies] diff --git a/tests/by-util/test_df.rs b/tests/by-util/test_df.rs index 223dc4efc..3de3c677b 100644 --- a/tests/by-util/test_df.rs +++ b/tests/by-util/test_df.rs @@ -1,4 +1,6 @@ // spell-checker:ignore udev pcent iuse itotal iused ipcent +use std::collections::HashSet; + use crate::common::util::*; #[test] @@ -165,6 +167,7 @@ fn test_output_mp_repeat() { assert_eq!(3, output1.len()); assert_eq!(output1[1], output1[2]); } + #[test] fn test_output_conflict_options() { for option in ["-i", "-T", "-P"] { @@ -204,6 +207,27 @@ fn test_exclude_type_option() { new_ucmd!().args(&["-x", "ext4", "-x", "ext3"]).succeeds(); } +#[test] +fn test_exclude_all_types() { + let fs_types = new_ucmd!() + .arg("--output=fstype") + .succeeds() + .stdout_move_str(); + let fs_types: HashSet<_> = fs_types.lines().skip(1).collect(); + + let mut args = Vec::new(); + + for fs_type in fs_types { + args.push("-x"); + args.push(fs_type.trim_end()); + } + + new_ucmd!() + .args(&args) + .fails() + .stderr_contains("no file systems processed"); +} + #[test] fn test_include_exclude_same_type() { new_ucmd!() @@ -349,7 +373,7 @@ fn test_output_selects_columns() { .args(&["--output=source"]) .succeeds() .stdout_move_str(); - assert_eq!(output.lines().next().unwrap().trim_end(), "Filesystem"); + assert_eq!(output.lines().next().unwrap(), "Filesystem"); let output = new_ucmd!() .args(&["--output=source,target"]) @@ -408,7 +432,7 @@ fn test_output_file_all_filesystems() { let mut lines = output.lines(); assert_eq!(lines.next().unwrap(), "File"); for line in lines { - assert_eq!(line, "- "); + assert_eq!(line, "-"); } } @@ -427,7 +451,21 @@ fn test_output_file_specific_files() { .succeeds() .stdout_move_str(); let actual: Vec<&str> = output.lines().collect(); - assert_eq!(actual, vec!["File", "a ", "b ", "c "]); + assert_eq!(actual, vec!["File", "a", "b", "c"]); +} + +#[test] +fn test_file_column_width_if_filename_contains_unicode_chars() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("äöü.txt"); + + let output = ucmd + .args(&["--output=file,target", "äöü.txt"]) + .succeeds() + .stdout_move_str(); + let actual = output.lines().next().unwrap(); + // expected width: 7 chars (length of äöü.txt) + 1 char (column separator) + assert_eq!(actual, "File Mounted on"); } #[test] @@ -448,5 +486,5 @@ fn test_nonexistent_file() { .args(&["--output=file", "does-not-exist", "."]) .fails() .stderr_is("df: does-not-exist: No such file or directory\n") - .stdout_is("File\n. \n"); + .stdout_is("File\n.\n"); }