From 87c2122e76b97df0439cbf291acfe623481f8083 Mon Sep 17 00:00:00 2001 From: 353fc443 <353fc443@pm.me> Date: Mon, 2 May 2022 07:20:29 +0000 Subject: [PATCH 1/8] mktemp: change directory permission after creation --- src/uu/mktemp/src/mktemp.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 54283b9af..eb14d765f 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -13,11 +13,12 @@ use uucore::display::{println_verbatim, Quotable}; use uucore::error::{FromIo, UError, UResult}; use uucore::format_usage; -use std::env; use std::error::Error; use std::fmt::Display; use std::iter; +use std::os::unix::prelude::PermissionsExt; use std::path::{is_separator, Path, PathBuf}; +use std::{env, fs}; use rand::Rng; use tempfile::Builder; @@ -272,5 +273,8 @@ fn exec(dir: &Path, prefix: &str, rand: usize, suffix: &str, make_dir: bool) -> .map_err(|e| MkTempError::PersistError(e.file.path().to_path_buf()))? .1 }; + if make_dir { + fs::set_permissions(&path, fs::Permissions::from_mode(0o700))?; + } println_verbatim(path).map_err_context(|| "failed to print directory name".to_owned()) } From 2383950403b3f28fd6155cc3e7684f07df6fee2c Mon Sep 17 00:00:00 2001 From: 353fc443 <353fc443@pm.me> Date: Mon, 16 May 2022 18:05:59 +0000 Subject: [PATCH 2/8] mktemp: Added tests for checking directory permissions --- src/uu/mktemp/src/mktemp.rs | 1 + tests/by-util/test_mktemp.rs | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 0a81c3ea0..ed761a932 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -311,6 +311,7 @@ fn exec(dir: &Path, prefix: &str, rand: usize, suffix: &str, make_dir: bool) -> .1 }; + #[cfg(not(windows))] if make_dir { fs::set_permissions(&path, fs::Permissions::from_mode(0o700))?; } diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index c28efc37b..c8a3bfb39 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -5,6 +5,9 @@ use crate::common::util::*; use std::path::PathBuf; use tempfile::tempdir; +#[cfg(unix)] +use std::os::unix::fs::PermissionsExt; + static TEST_TEMPLATE1: &str = "tempXXXXXX"; static TEST_TEMPLATE2: &str = "temp"; static TEST_TEMPLATE3: &str = "tempX"; @@ -482,3 +485,15 @@ fn test_respect_template_directory() { assert_matches_template!(template, filename); assert!(at.file_exists(filename)); } + +#[cfg(unix)] +#[test] +fn test_directory_permissions() { + let (at, mut ucmd) = at_and_ucmd!(); + let result = ucmd.args(&["-d", "XXX"]).succeeds(); + let dirname = result.no_stderr().stdout_str().trim_end(); + assert_matches_template!("XXX", dirname); + let metadata = at.metadata(dirname); + assert!(metadata.is_dir()); + assert_eq!(metadata.permissions().mode(), 0o40700); +} From 35fb4e6ea14bbc4b14692635c03f13bb2457a84a Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Sat, 21 May 2022 21:58:38 -0400 Subject: [PATCH 3/8] mktemp: include suffix in error message Include the suffix in the error message produced by `mktemp` when there are too few Xs in the template. Before this commit, $ mktemp --suffix=X aXX mktemp: too few X's in template 'aXX' After this commit, $ mktemp --suffix=X aXX mktemp: too few X's in template 'aXXX' This matches the behavior of GNU `mktemp`. --- src/uu/mktemp/src/mktemp.rs | 6 +++++- tests/by-util/test_mktemp.rs | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 102eadbe4..89fe21a64 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -267,7 +267,11 @@ fn parse_template<'a>( let rand = right - left; if rand < 3 { - return Err(MkTempError::TooFewXs(temp.into())); + let s = match suffix { + None => temp.into(), + Some(s) => format!("{}{}", temp, s), + }; + return Err(MkTempError::TooFewXs(s)); } let mut suf = &temp[right..]; diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 15a6b932f..7c097b425 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -527,3 +527,19 @@ fn test_suffix_path_separator() { .fails() .stderr_only("mktemp: invalid suffix '\\b', contains directory separator\n"); } + +#[test] +fn test_too_few_xs_suffix() { + new_ucmd!() + .args(&["--suffix=X", "aXX"]) + .fails() + .stderr_only("mktemp: too few X's in template 'aXXX'\n"); +} + +#[test] +fn test_too_few_xs_suffix_directory() { + new_ucmd!() + .args(&["-d", "--suffix=X", "aXX"]) + .fails() + .stderr_only("mktemp: too few X's in template 'aXXX'\n"); +} From ea284ce55eea6fa80606d71f2678539c2995503e Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 8 May 2022 17:09:05 +0200 Subject: [PATCH 4/8] df: read block size from env vars --- src/uu/df/src/blocks.rs | 24 ++++++++-- src/uu/df/src/df.rs | 4 +- tests/by-util/test_df.rs | 99 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 5 deletions(-) diff --git a/src/uu/df/src/blocks.rs b/src/uu/df/src/blocks.rs index 88190b5c1..88bead559 100644 --- a/src/uu/df/src/blocks.rs +++ b/src/uu/df/src/blocks.rs @@ -3,7 +3,7 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. //! Types for representing and displaying block sizes. -use crate::OPT_BLOCKSIZE; +use crate::{OPT_BLOCKSIZE, OPT_PORTABILITY}; use clap::ArgMatches; use std::{env, fmt}; @@ -189,7 +189,7 @@ impl Default for BlockSize { } } -pub(crate) fn block_size_from_matches(matches: &ArgMatches) -> Result { +pub(crate) fn read_block_size(matches: &ArgMatches) -> Result { if matches.is_present(OPT_BLOCKSIZE) { let s = matches.value_of(OPT_BLOCKSIZE).unwrap(); let bytes = parse_size(s)?; @@ -199,11 +199,29 @@ pub(crate) fn block_size_from_matches(matches: &ArgMatches) -> Result Option { + for env_var in ["DF_BLOCK_SIZE", "BLOCK_SIZE", "BLOCKSIZE"] { + if let Ok(env_size) = env::var(env_var) { + if let Ok(size) = parse_size(&env_size) { + return Some(size); + } else { + return None; + } + } + } + + None +} + impl fmt::Display for BlockSize { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { diff --git a/src/uu/df/src/df.rs b/src/uu/df/src/df.rs index 7c95e6938..ceddcb7fd 100644 --- a/src/uu/df/src/df.rs +++ b/src/uu/df/src/df.rs @@ -25,7 +25,7 @@ use std::error::Error; use std::fmt; use std::path::Path; -use crate::blocks::{block_size_from_matches, BlockSize}; +use crate::blocks::{read_block_size, BlockSize}; use crate::columns::{Column, ColumnError}; use crate::filesystem::Filesystem; use crate::table::Table; @@ -178,7 +178,7 @@ impl Options { Ok(Self { show_local_fs: matches.is_present(OPT_LOCAL), show_all_fs: matches.is_present(OPT_ALL), - block_size: block_size_from_matches(matches).map_err(|e| match e { + block_size: read_block_size(matches).map_err(|e| match e { ParseSizeError::InvalidSuffix(s) => OptionsError::InvalidSuffix(s), ParseSizeError::SizeTooBig(_) => OptionsError::BlockSizeTooLarge( matches.value_of(OPT_BLOCKSIZE).unwrap().to_string(), diff --git a/tests/by-util/test_df.rs b/tests/by-util/test_df.rs index 6f8de3bfa..6272d1082 100644 --- a/tests/by-util/test_df.rs +++ b/tests/by-util/test_df.rs @@ -532,6 +532,105 @@ fn test_block_size_in_posix_portability_mode() { assert_eq!(get_header("1MB"), "1000000-blocks"); } +#[test] +fn test_block_size_from_env() { + fn get_header(env_var: &str, env_value: &str) -> String { + let output = new_ucmd!() + .arg("--output=size") + .env(env_var, env_value) + .succeeds() + .stdout_move_str(); + output.lines().next().unwrap().to_string() + } + + assert_eq!(get_header("DF_BLOCK_SIZE", "111"), "111B-blocks"); + assert_eq!(get_header("BLOCK_SIZE", "222"), "222B-blocks"); + assert_eq!(get_header("BLOCKSIZE", "333"), "333B-blocks"); +} + +#[test] +fn test_block_size_from_env_precedences() { + fn get_header(one: (&str, &str), two: (&str, &str)) -> String { + let (k1, v1) = one; + let (k2, v2) = two; + let output = new_ucmd!() + .arg("--output=size") + .env(k1, v1) + .env(k2, v2) + .succeeds() + .stdout_move_str(); + output.lines().next().unwrap().to_string() + } + + let df_block_size = ("DF_BLOCK_SIZE", "111"); + let block_size = ("BLOCK_SIZE", "222"); + let blocksize = ("BLOCKSIZE", "333"); + + assert_eq!(get_header(df_block_size, block_size), "111B-blocks"); + assert_eq!(get_header(df_block_size, blocksize), "111B-blocks"); + assert_eq!(get_header(block_size, blocksize), "222B-blocks"); +} + +#[test] +fn test_precedence_of_block_size_arg_over_env() { + let output = new_ucmd!() + .args(&["-B", "999", "--output=size"]) + .env("DF_BLOCK_SIZE", "111") + .succeeds() + .stdout_move_str(); + let header = output.lines().next().unwrap().to_string(); + + assert_eq!(header, "999B-blocks"); +} + +#[test] +fn test_invalid_block_size_from_env() { + let default_block_size_header = "1K-blocks"; + + let output = new_ucmd!() + .arg("--output=size") + .env("DF_BLOCK_SIZE", "invalid") + .succeeds() + .stdout_move_str(); + let header = output.lines().next().unwrap().to_string(); + + assert_eq!(header, default_block_size_header); + + let output = new_ucmd!() + .arg("--output=size") + .env("DF_BLOCK_SIZE", "invalid") + .env("BLOCK_SIZE", "222") + .succeeds() + .stdout_move_str(); + let header = output.lines().next().unwrap().to_string(); + + assert_eq!(header, default_block_size_header); +} + +#[test] +fn test_ignore_block_size_from_env_in_posix_portability_mode() { + let default_block_size_header = "1024-blocks"; + + let output = new_ucmd!() + .arg("-P") + .env("DF_BLOCK_SIZE", "111") + .env("BLOCK_SIZE", "222") + .env("BLOCKSIZE", "333") + .succeeds() + .stdout_move_str(); + let header = output + .lines() + .next() + .unwrap() + .to_string() + .split_whitespace() + .nth(1) + .unwrap() + .to_string(); + + assert_eq!(header, default_block_size_header); +} + #[test] fn test_too_large_block_size() { fn run_command(size: &str) { From c90a1c759a0bfd27c62a77d96a55ba9f4cf075a0 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 22 May 2022 16:54:51 +0200 Subject: [PATCH 5/8] df: fix rounding behavior in humanreadable mode Fixes #3422 --- Cargo.lock | 1 - src/uu/df/Cargo.toml | 1 - src/uu/df/src/blocks.rs | 229 +++++++++++++++++++--------------------- src/uu/df/src/df.rs | 14 +-- src/uu/df/src/table.rs | 59 +++-------- 5 files changed, 133 insertions(+), 171 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 40fdcfd2a..7253d58a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2219,7 +2219,6 @@ name = "uu_df" version = "0.0.14" dependencies = [ "clap 3.1.18", - "number_prefix", "unicode-width", "uucore", ] diff --git a/src/uu/df/Cargo.toml b/src/uu/df/Cargo.toml index 8e4fc9698..ccbdc803b 100644 --- a/src/uu/df/Cargo.toml +++ b/src/uu/df/Cargo.toml @@ -16,7 +16,6 @@ path = "src/df.rs" [dependencies] 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" diff --git a/src/uu/df/src/blocks.rs b/src/uu/df/src/blocks.rs index 88190b5c1..2593c13dd 100644 --- a/src/uu/df/src/blocks.rs +++ b/src/uu/df/src/blocks.rs @@ -26,9 +26,7 @@ const IEC_BASES: [u128; 10] = [ 1_237_940_039_285_380_274_899_124_224, ]; -/// Suffixes for the first nine multi-byte unit suffixes. -const SUFFIXES: [char; 9] = ['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; - +/// The first ten powers of 1000. const SI_BASES: [u128; 10] = [ 1, 1_000, @@ -42,93 +40,68 @@ const SI_BASES: [u128; 10] = [ 1_000_000_000_000_000_000_000_000_000, ]; -// we use "kB" instead of "KB" because of GNU df -const SI_SUFFIXES: [&str; 9] = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; - -/// Convert a multiple of 1024 into a string like "12K" or "34M". -/// -/// # Examples -/// -/// Powers of 1024 become "1K", "1M", "1G", etc. -/// -/// ```rust,ignore -/// assert_eq!(to_magnitude_and_suffix_1024(1024).unwrap(), "1K"); -/// assert_eq!(to_magnitude_and_suffix_1024(1024 * 1024).unwrap(), "1M"); -/// assert_eq!(to_magnitude_and_suffix_1024(1024 * 1024 * 1024).unwrap(), "1G"); -/// ``` -/// -/// Multiples of those powers affect the magnitude part of the -/// returned string: -/// -/// ```rust,ignore -/// assert_eq!(to_magnitude_and_suffix_1024(123 * 1024).unwrap(), "123K"); -/// assert_eq!(to_magnitude_and_suffix_1024(456 * 1024 * 1024).unwrap(), "456M"); -/// assert_eq!(to_magnitude_and_suffix_1024(789 * 1024 * 1024 * 1024).unwrap(), "789G"); -/// ``` -fn to_magnitude_and_suffix_1024(n: u128) -> Result { - // Find the smallest power of 1024 that is larger than `n`. That - // number indicates which units and suffix to use. - for i in 0..IEC_BASES.len() - 1 { - if n < IEC_BASES[i + 1] { - return Ok(format!("{}{}", n / IEC_BASES[i], SUFFIXES[i])); - } - } - Err(()) +/// A SuffixType determines whether the suffixes are 1000 or 1024 based, and whether they are +/// intended for HumanReadable mode or not. +#[derive(Clone, Copy)] +pub(crate) enum SuffixType { + Iec, + Si, + HumanReadable(HumanReadable), } -/// Convert a number into a string like "12kB" or "34MB". -/// -/// Powers of 1000 become "1kB", "1MB", "1GB", etc. -/// -/// The returned string has a maximum length of 5 chars, for example: "1.1kB", "999kB", "1MB". -fn to_magnitude_and_suffix_not_powers_of_1024(n: u128) -> Result { - let mut i = 0; - - while SI_BASES[i + 1] - SI_BASES[i] < n && i < SI_SUFFIXES.len() { - i += 1; +impl SuffixType { + /// The first ten powers of 1024 and 1000, respectively. + fn bases(&self) -> [u128; 10] { + match self { + Self::Iec | Self::HumanReadable(HumanReadable::Binary) => IEC_BASES, + Self::Si | Self::HumanReadable(HumanReadable::Decimal) => SI_BASES, + } } - let quot = n / SI_BASES[i]; - let rem = n % SI_BASES[i]; - let suffix = SI_SUFFIXES[i]; - - if rem == 0 { - Ok(format!("{}{}", quot, suffix)) - } else { - let tenths_place = rem / (SI_BASES[i] / 10); - - if rem % (SI_BASES[i] / 10) == 0 { - Ok(format!("{}.{}{}", quot, tenths_place, suffix)) - } else if tenths_place + 1 == 10 || quot >= 10 { - Ok(format!("{}{}", quot + 1, suffix)) - } else { - Ok(format!("{}.{}{}", quot, tenths_place + 1, suffix)) + /// Suffixes for the first nine multi-byte unit suffixes. + fn suffixes(&self) -> [&'static str; 9] { + match self { + // we use "kB" instead of "KB", same as GNU df + Self::Si => ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], + Self::Iec => ["B", "K", "M", "G", "T", "P", "E", "Z", "Y"], + Self::HumanReadable(HumanReadable::Binary) => { + ["", "K", "M", "G", "T", "P", "E", "Z", "Y"] + } + Self::HumanReadable(HumanReadable::Decimal) => { + ["", "k", "M", "G", "T", "P", "E", "Z", "Y"] + } } } } /// Convert a number into a magnitude and a multi-byte unit suffix. /// -/// # Errors -/// -/// If the number is too large to represent. -fn to_magnitude_and_suffix(n: u128) -> Result { - if n % 1024 == 0 && n % 1000 != 0 { - to_magnitude_and_suffix_1024(n) - } else { - to_magnitude_and_suffix_not_powers_of_1024(n) +/// The returned string has a maximum length of 5 chars, for example: "1.1kB", "999kB", "1MB". +pub(crate) fn to_magnitude_and_suffix(n: u128, suffix_type: SuffixType) -> String { + let bases = suffix_type.bases(); + let suffixes = suffix_type.suffixes(); + let mut i = 0; + + while bases[i + 1] - bases[i] < n && i < suffixes.len() { + i += 1; } -} -/// A mode to use in condensing the display of a large number of bytes. -pub(crate) enum SizeFormat { - HumanReadable(HumanReadable), - StaticBlockSize, -} + let quot = n / bases[i]; + let rem = n % bases[i]; + let suffix = suffixes[i]; -impl Default for SizeFormat { - fn default() -> Self { - Self::StaticBlockSize + if rem == 0 { + format!("{}{}", quot, suffix) + } else { + let tenths_place = rem / (bases[i] / 10); + + if rem % (bases[i] / 10) == 0 { + format!("{}.{}{}", quot, tenths_place, suffix) + } else if tenths_place + 1 == 10 || quot >= 10 { + format!("{}{}", quot + 1, suffix) + } else { + format!("{}.{}{}", quot, tenths_place + 1, suffix) + } } } @@ -207,10 +180,15 @@ pub(crate) fn block_size_from_matches(matches: &ArgMatches) -> Result fmt::Result { match self { - Self::Bytes(n) => match to_magnitude_and_suffix(*n as u128) { - Ok(s) => write!(f, "{}", s), - Err(_) => Err(fmt::Error), - }, + Self::Bytes(n) => { + let s = if n % 1024 == 0 && n % 1000 != 0 { + to_magnitude_and_suffix(*n as u128, SuffixType::Iec) + } else { + to_magnitude_and_suffix(*n as u128, SuffixType::Si) + }; + + write!(f, "{}", s) + } } } } @@ -220,56 +198,64 @@ mod tests { use std::env; - use crate::blocks::{to_magnitude_and_suffix, BlockSize}; + use crate::blocks::{to_magnitude_and_suffix, BlockSize, SuffixType}; #[test] fn test_to_magnitude_and_suffix_powers_of_1024() { - assert_eq!(to_magnitude_and_suffix(1024).unwrap(), "1K"); - assert_eq!(to_magnitude_and_suffix(2048).unwrap(), "2K"); - assert_eq!(to_magnitude_and_suffix(4096).unwrap(), "4K"); - assert_eq!(to_magnitude_and_suffix(1024 * 1024).unwrap(), "1M"); - assert_eq!(to_magnitude_and_suffix(2 * 1024 * 1024).unwrap(), "2M"); - assert_eq!(to_magnitude_and_suffix(1024 * 1024 * 1024).unwrap(), "1G"); + assert_eq!(to_magnitude_and_suffix(1024, SuffixType::Iec), "1K"); + assert_eq!(to_magnitude_and_suffix(2048, SuffixType::Iec), "2K"); + assert_eq!(to_magnitude_and_suffix(4096, SuffixType::Iec), "4K"); + assert_eq!(to_magnitude_and_suffix(1024 * 1024, SuffixType::Iec), "1M"); assert_eq!( - to_magnitude_and_suffix(34 * 1024 * 1024 * 1024).unwrap(), + to_magnitude_and_suffix(2 * 1024 * 1024, SuffixType::Iec), + "2M" + ); + assert_eq!( + to_magnitude_and_suffix(1024 * 1024 * 1024, SuffixType::Iec), + "1G" + ); + assert_eq!( + to_magnitude_and_suffix(34 * 1024 * 1024 * 1024, SuffixType::Iec), "34G" ); } #[test] fn test_to_magnitude_and_suffix_not_powers_of_1024() { - assert_eq!(to_magnitude_and_suffix(1).unwrap(), "1B"); - assert_eq!(to_magnitude_and_suffix(999).unwrap(), "999B"); + assert_eq!(to_magnitude_and_suffix(1, SuffixType::Si), "1B"); + assert_eq!(to_magnitude_and_suffix(999, SuffixType::Si), "999B"); - assert_eq!(to_magnitude_and_suffix(1000).unwrap(), "1kB"); - assert_eq!(to_magnitude_and_suffix(1001).unwrap(), "1.1kB"); - assert_eq!(to_magnitude_and_suffix(1023).unwrap(), "1.1kB"); - assert_eq!(to_magnitude_and_suffix(1025).unwrap(), "1.1kB"); - assert_eq!(to_magnitude_and_suffix(10_001).unwrap(), "11kB"); - assert_eq!(to_magnitude_and_suffix(999_000).unwrap(), "999kB"); + assert_eq!(to_magnitude_and_suffix(1000, SuffixType::Si), "1kB"); + assert_eq!(to_magnitude_and_suffix(1001, SuffixType::Si), "1.1kB"); + assert_eq!(to_magnitude_and_suffix(1023, SuffixType::Si), "1.1kB"); + assert_eq!(to_magnitude_and_suffix(1025, SuffixType::Si), "1.1kB"); + assert_eq!(to_magnitude_and_suffix(10_001, SuffixType::Si), "11kB"); + assert_eq!(to_magnitude_and_suffix(999_000, SuffixType::Si), "999kB"); - assert_eq!(to_magnitude_and_suffix(999_001).unwrap(), "1MB"); - assert_eq!(to_magnitude_and_suffix(999_999).unwrap(), "1MB"); - assert_eq!(to_magnitude_and_suffix(1_000_000).unwrap(), "1MB"); - assert_eq!(to_magnitude_and_suffix(1_000_001).unwrap(), "1.1MB"); - assert_eq!(to_magnitude_and_suffix(1_100_000).unwrap(), "1.1MB"); - assert_eq!(to_magnitude_and_suffix(1_100_001).unwrap(), "1.2MB"); - assert_eq!(to_magnitude_and_suffix(1_900_000).unwrap(), "1.9MB"); - assert_eq!(to_magnitude_and_suffix(1_900_001).unwrap(), "2MB"); - assert_eq!(to_magnitude_and_suffix(9_900_000).unwrap(), "9.9MB"); - assert_eq!(to_magnitude_and_suffix(9_900_001).unwrap(), "10MB"); - assert_eq!(to_magnitude_and_suffix(999_000_000).unwrap(), "999MB"); + assert_eq!(to_magnitude_and_suffix(999_001, SuffixType::Si), "1MB"); + assert_eq!(to_magnitude_and_suffix(999_999, SuffixType::Si), "1MB"); + assert_eq!(to_magnitude_and_suffix(1_000_000, SuffixType::Si), "1MB"); + assert_eq!(to_magnitude_and_suffix(1_000_001, SuffixType::Si), "1.1MB"); + assert_eq!(to_magnitude_and_suffix(1_100_000, SuffixType::Si), "1.1MB"); + assert_eq!(to_magnitude_and_suffix(1_100_001, SuffixType::Si), "1.2MB"); + assert_eq!(to_magnitude_and_suffix(1_900_000, SuffixType::Si), "1.9MB"); + assert_eq!(to_magnitude_and_suffix(1_900_001, SuffixType::Si), "2MB"); + assert_eq!(to_magnitude_and_suffix(9_900_000, SuffixType::Si), "9.9MB"); + assert_eq!(to_magnitude_and_suffix(9_900_001, SuffixType::Si), "10MB"); + assert_eq!( + to_magnitude_and_suffix(999_000_000, SuffixType::Si), + "999MB" + ); - assert_eq!(to_magnitude_and_suffix(999_000_001).unwrap(), "1GB"); - assert_eq!(to_magnitude_and_suffix(1_000_000_000).unwrap(), "1GB"); - assert_eq!(to_magnitude_and_suffix(1_000_000_001).unwrap(), "1.1GB"); - } - - #[test] - fn test_to_magnitude_and_suffix_multiples_of_1000_and_1024() { - assert_eq!(to_magnitude_and_suffix(128_000).unwrap(), "128kB"); - assert_eq!(to_magnitude_and_suffix(1000 * 1024).unwrap(), "1.1MB"); - assert_eq!(to_magnitude_and_suffix(1_000_000_000_000).unwrap(), "1TB"); + assert_eq!(to_magnitude_and_suffix(999_000_001, SuffixType::Si), "1GB"); + assert_eq!( + to_magnitude_and_suffix(1_000_000_000, SuffixType::Si), + "1GB" + ); + assert_eq!( + to_magnitude_and_suffix(1_000_000_001, SuffixType::Si), + "1.1GB" + ); } #[test] @@ -279,6 +265,13 @@ mod tests { assert_eq!(format!("{}", BlockSize::Bytes(3 * 1024 * 1024)), "3M"); } + #[test] + fn test_block_size_display_multiples_of_1000_and_1024() { + assert_eq!(format!("{}", BlockSize::Bytes(128_000)), "128kB"); + assert_eq!(format!("{}", BlockSize::Bytes(1000 * 1024)), "1.1MB"); + assert_eq!(format!("{}", BlockSize::Bytes(1_000_000_000_000)), "1TB"); + } + #[test] fn test_default_block_size() { assert_eq!(BlockSize::Bytes(1024), BlockSize::default()); diff --git a/src/uu/df/src/df.rs b/src/uu/df/src/df.rs index 7c95e6938..6e8482ffe 100644 --- a/src/uu/df/src/df.rs +++ b/src/uu/df/src/df.rs @@ -11,7 +11,7 @@ mod columns; mod filesystem; mod table; -use blocks::{HumanReadable, SizeFormat}; +use blocks::HumanReadable; use table::HeaderMode; use uucore::display::Quotable; use uucore::error::{UError, UResult, USimpleError}; @@ -71,7 +71,7 @@ static OUTPUT_FIELD_LIST: [&str; 12] = [ struct Options { show_local_fs: bool, show_all_fs: bool, - size_format: SizeFormat, + human_readable: Option, block_size: BlockSize, header_mode: HeaderMode, @@ -100,7 +100,7 @@ impl Default for Options { show_local_fs: Default::default(), show_all_fs: Default::default(), block_size: Default::default(), - size_format: Default::default(), + human_readable: Default::default(), header_mode: Default::default(), include: Default::default(), exclude: Default::default(), @@ -200,13 +200,13 @@ impl Options { HeaderMode::Default } }, - size_format: { + human_readable: { if matches.is_present(OPT_HUMAN_READABLE_BINARY) { - SizeFormat::HumanReadable(HumanReadable::Binary) + Some(HumanReadable::Binary) } else if matches.is_present(OPT_HUMAN_READABLE_DECIMAL) { - SizeFormat::HumanReadable(HumanReadable::Decimal) + Some(HumanReadable::Decimal) } else { - SizeFormat::StaticBlockSize + None } }, include, diff --git a/src/uu/df/src/table.rs b/src/uu/df/src/table.rs index fac2ca663..22d3a4437 100644 --- a/src/uu/df/src/table.rs +++ b/src/uu/df/src/table.rs @@ -7,10 +7,9 @@ //! //! 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::blocks::{HumanReadable, SizeFormat}; +use crate::blocks::{to_magnitude_and_suffix, SuffixType}; use crate::columns::{Alignment, Column}; use crate::filesystem::Filesystem; use crate::{BlockSize, Options}; @@ -213,28 +212,15 @@ impl<'a> RowFormatter<'a> { Self { row, options } } - /// Get a human readable string giving the scaled version of the input number. - fn scaled_human_readable(&self, size: u64, human_readable: HumanReadable) -> String { - let number_prefix = match human_readable { - HumanReadable::Decimal => NumberPrefix::decimal(size as f64), - HumanReadable::Binary => NumberPrefix::binary(size as f64), - }; - match number_prefix { - NumberPrefix::Standalone(bytes) => bytes.to_string(), - NumberPrefix::Prefixed(prefix, bytes) => format!("{:.1}{}", bytes, prefix.symbol()), - } - } - /// Get a string giving the scaled version of the input number. /// /// The scaling factor is defined in the `options` field. fn scaled_bytes(&self, size: u64) -> String { - match self.options.size_format { - SizeFormat::HumanReadable(h) => self.scaled_human_readable(size, h), - SizeFormat::StaticBlockSize => { - let BlockSize::Bytes(d) = self.options.block_size; - (size as f64 / d as f64).ceil().to_string() - } + if let Some(h) = self.options.human_readable { + to_magnitude_and_suffix(size.into(), SuffixType::HumanReadable(h)) + } else { + let BlockSize::Bytes(d) = self.options.block_size; + (size as f64 / d as f64).ceil().to_string() } } @@ -242,9 +228,10 @@ impl<'a> RowFormatter<'a> { /// /// The scaling factor is defined in the `options` field. fn scaled_inodes(&self, size: u64) -> String { - match self.options.size_format { - SizeFormat::HumanReadable(h) => self.scaled_human_readable(size, h), - SizeFormat::StaticBlockSize => size.to_string(), + if let Some(h) = self.options.human_readable { + to_magnitude_and_suffix(size.into(), SuffixType::HumanReadable(h)) + } else { + size.to_string() } } @@ -450,7 +437,7 @@ impl fmt::Display for Table { #[cfg(test)] mod tests { - use crate::blocks::{HumanReadable, SizeFormat}; + use crate::blocks::HumanReadable; use crate::columns::Column; use crate::table::{Header, HeaderMode, Row, RowFormatter}; use crate::{BlockSize, Options}; @@ -715,7 +702,7 @@ mod tests { #[test] fn test_row_formatter_with_human_readable_si() { let options = Options { - size_format: SizeFormat::HumanReadable(HumanReadable::Decimal), + human_readable: Some(HumanReadable::Decimal), columns: COLUMNS_WITH_FS_TYPE.to_vec(), ..Default::default() }; @@ -734,22 +721,14 @@ mod tests { let fmt = RowFormatter::new(&row, &options); assert_eq!( fmt.get_values(), - vec!( - "my_device", - "my_type", - "4.0k", - "1.0k", - "3.0k", - "25%", - "my_mount" - ) + vec!("my_device", "my_type", "4k", "1k", "3k", "25%", "my_mount") ); } #[test] fn test_row_formatter_with_human_readable_binary() { let options = Options { - size_format: SizeFormat::HumanReadable(HumanReadable::Binary), + human_readable: Some(HumanReadable::Binary), columns: COLUMNS_WITH_FS_TYPE.to_vec(), ..Default::default() }; @@ -768,15 +747,7 @@ mod tests { let fmt = RowFormatter::new(&row, &options); assert_eq!( fmt.get_values(), - vec!( - "my_device", - "my_type", - "4.0Ki", - "1.0Ki", - "3.0Ki", - "25%", - "my_mount" - ) + vec!("my_device", "my_type", "4K", "1K", "3K", "25%", "my_mount") ); } From ba746250fb370f3007339d76967c67fe6cd2beee Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 24 May 2022 08:30:55 +0200 Subject: [PATCH 6/8] dircolors: update internal db --- src/uu/dircolors/README.md | 17 ++++++ src/uu/dircolors/src/colors.rs | 68 +++++++++++++++------- src/uu/dircolors/src/dircolors.rs | 4 +- tests/fixtures/dircolors/bash_def.expected | 2 +- tests/fixtures/dircolors/csh_def.expected | 2 +- tests/fixtures/dircolors/internal.expected | 64 ++++++++++++++------ 6 files changed, 115 insertions(+), 42 deletions(-) create mode 100644 src/uu/dircolors/README.md diff --git a/src/uu/dircolors/README.md b/src/uu/dircolors/README.md new file mode 100644 index 000000000..915520d25 --- /dev/null +++ b/src/uu/dircolors/README.md @@ -0,0 +1,17 @@ +## How to update the internal database + +Create the test fixtures by writing the output of the GNU dircolors commands to the fixtures folder: + +``` +$ dircolors --print-database > /PATH_TO_COREUTILS/tests/fixtures/dircolors/internal.expected +$ dircolors -b > /PATH_TO_COREUTILS/tests/fixtures/dircolors/bash_def.expected +$ dircolors -c > /PATH_TO_COREUTILS/tests/fixtures/dircolors/csh_def.expected +``` + +Run the tests: + +``` +$ cargo test --features "dircolors" --no-default-features +``` + +Edit `/PATH_TO_COREUTILS/src/uu/dircolors/src/colors.rs` until the tests pass. diff --git a/src/uu/dircolors/src/colors.rs b/src/uu/dircolors/src/colors.rs index e313078ab..d864a23b3 100644 --- a/src/uu/dircolors/src/colors.rs +++ b/src/uu/dircolors/src/colors.rs @@ -1,46 +1,45 @@ -// spell-checker:ignore (ToDO) EIGHTBIT ETERM MULTIHARDLINK cpio dtterm jfbterm konsole kterm mlterm rmvb rxvt stat'able svgz tmux webm xspf +// spell-checker:ignore (ToDO) EIGHTBIT ETERM MULTIHARDLINK cpio dtterm jfbterm konsole kterm mlterm rmvb rxvt stat'able svgz tmux webm xspf COLORTERM tzst avif tzst mjpg mjpeg webp dpkg rpmnew rpmorig rpmsave pub const INTERNAL_DB: &str = r#"# Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. -# Copyright (C) 1996-2016 Free Software Foundation, Inc. +# Copyright (C) 1996-2022 Free Software Foundation, Inc. # Copying and distribution of this file, with or without modification, # are permitted provided the copyright notice and this notice are preserved. # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the # slackware version of dircolors) are recognized but ignored. -# Below are TERM entries, which can be a glob patterns, to match -# against the TERM environment variable to determine if it is colorizable. +# Global config options can be specified before TERM or COLORTERM entries +# Below are TERM or COLORTERM entries, which can be glob patterns, which +# restrict following config to systems with matching environment variables. +COLORTERM ?* TERM Eterm TERM ansi -TERM color-xterm +TERM *color* TERM con[0-9]*x[0-9]* TERM cons25 TERM console TERM cygwin +TERM *direct* TERM dtterm -TERM eterm-color TERM gnome -TERM gnome-256color TERM hurd TERM jfbterm TERM konsole TERM kterm TERM linux TERM linux-c -TERM mach-color -TERM mach-gnu-color TERM mlterm TERM putty -TERM putty-256color TERM rxvt* TERM screen* TERM st -TERM st-256color TERM terminator TERM tmux* TERM vt100 TERM xterm* -# Below are the color init strings for the basic file types. A color init -# string consists of one or more of the following numeric codes: +# Below are the color init strings for the basic file types. +# One can use codes for 256 or more colors supported by modern terminals. +# The default color codes use the capabilities of an 8 color terminal +# with some additional attributes as per the following codes: # Attribute codes: # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed # Text color codes: @@ -63,14 +62,14 @@ ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... MISSING 00 # ... and the files they point to SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) -CAPABILITY 30;41 # file with capability +CAPABILITY 00 # file with capability (very expensive to lookup) STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: EXEC 01;32 # List any file extensions like '.gz' or '.tar' that you would like ls -# to colorize below. Put the extension, a space, and the color init string. +# to color below. Put the extension, a space, and the color init string. # (and any comments you want to add after a '#') # If you use DOS-style suffixes, you may want to uncomment the following: #.cmd 01;32 # executables (bright green) @@ -78,7 +77,7 @@ EXEC 01;32 #.com 01;32 #.btm 01;32 #.bat 01;32 -# Or if you want to colorize scripts even if they do not have the +# Or if you want to color scripts even if they do not have the # executable bit actually set. #.sh 01;32 #.csh 01;32 @@ -98,13 +97,14 @@ EXEC 01;32 .t7z 01;31 .zip 01;31 .z 01;31 -.Z 01;31 .dz 01;31 .gz 01;31 .lrz 01;31 .lz 01;31 .lzo 01;31 .xz 01;31 +.zst 01;31 +.tzst 01;31 .bz2 01;31 .bz 01;31 .tbz 01;31 @@ -124,9 +124,16 @@ EXEC 01;32 .7z 01;31 .rz 01;31 .cab 01;31 +.wim 01;31 +.swm 01;31 +.dwm 01;31 +.esd 01;31 # image formats +.avif 01;35 .jpg 01;35 .jpeg 01;35 +.mjpg 01;35 +.mjpeg 01;35 .gif 01;35 .bmp 01;35 .pbm 01;35 @@ -148,6 +155,7 @@ EXEC 01;32 .m2v 01;35 .mkv 01;35 .webm 01;35 +.webp 01;35 .ogm 01;35 .mp4 01;35 .m4v 01;35 @@ -170,7 +178,7 @@ EXEC 01;32 .yuv 01;35 .cgm 01;35 .emf 01;35 -# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +# https://wiki.xiph.org/MIME_Types_and_File_Extensions .ogv 01;35 .ogx 01;35 # audio formats @@ -186,8 +194,28 @@ EXEC 01;32 .ogg 00;36 .ra 00;36 .wav 00;36 -# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +# https://wiki.xiph.org/MIME_Types_and_File_Extensions .oga 00;36 .opus 00;36 .spx 00;36 -.xspf 00;36"#; +.xspf 00;36 +# backup files +*~ 00;90 +*# 00;90 +.bak 00;90 +.old 00;90 +.orig 00;90 +.part 00;90 +.rej 00;90 +.swp 00;90 +.tmp 00;90 +.dpkg-dist 00;90 +.dpkg-old 00;90 +.ucf-dist 00;90 +.ucf-new 00;90 +.ucf-old 00;90 +.rpmnew 00;90 +.rpmorig 00;90 +.rpmsave 00;90 +# Subsequent TERM or COLORTERM entries, can be used to add / override +# config specific to those matching environment variables."#; diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 78cf8d802..cc3a9baa6 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -6,7 +6,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (ToDO) clrtoeol dircolors eightbit endcode fnmatch leftcode multihardlink rightcode setenv sgid suid +// spell-checker:ignore (ToDO) clrtoeol dircolors eightbit endcode fnmatch leftcode multihardlink rightcode setenv sgid suid colorterm use std::borrow::Borrow; use std::env; @@ -329,7 +329,7 @@ where } let lower = key.to_lowercase(); - if lower == "term" { + if lower == "term" || lower == "colorterm" { if term.fnmatch(val) { state = ParseState::Matched; } else if state != ParseState::Matched { diff --git a/tests/fixtures/dircolors/bash_def.expected b/tests/fixtures/dircolors/bash_def.expected index d0bd0d33b..463f70703 100644 --- a/tests/fixtures/dircolors/bash_def.expected +++ b/tests/fixtures/dircolors/bash_def.expected @@ -1,2 +1,2 @@ -LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:'; +LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=00:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.avif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:*~=00;90:*#=00;90:*.bak=00;90:*.old=00;90:*.orig=00;90:*.part=00;90:*.rej=00;90:*.swp=00;90:*.tmp=00;90:*.dpkg-dist=00;90:*.dpkg-old=00;90:*.ucf-dist=00;90:*.ucf-new=00;90:*.ucf-old=00;90:*.rpmnew=00;90:*.rpmorig=00;90:*.rpmsave=00;90:'; export LS_COLORS diff --git a/tests/fixtures/dircolors/csh_def.expected b/tests/fixtures/dircolors/csh_def.expected index 2d1e1d374..0d5da0767 100644 --- a/tests/fixtures/dircolors/csh_def.expected +++ b/tests/fixtures/dircolors/csh_def.expected @@ -1 +1 @@ -setenv LS_COLORS 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:' +setenv LS_COLORS 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=00:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.avif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:*~=00;90:*#=00;90:*.bak=00;90:*.old=00;90:*.orig=00;90:*.part=00;90:*.rej=00;90:*.swp=00;90:*.tmp=00;90:*.dpkg-dist=00;90:*.dpkg-old=00;90:*.ucf-dist=00;90:*.ucf-new=00;90:*.ucf-old=00;90:*.rpmnew=00;90:*.rpmorig=00;90:*.rpmsave=00;90:' diff --git a/tests/fixtures/dircolors/internal.expected b/tests/fixtures/dircolors/internal.expected index 8566587f4..7bc91ef47 100644 --- a/tests/fixtures/dircolors/internal.expected +++ b/tests/fixtures/dircolors/internal.expected @@ -1,44 +1,43 @@ # Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. -# Copyright (C) 1996-2016 Free Software Foundation, Inc. +# Copyright (C) 1996-2022 Free Software Foundation, Inc. # Copying and distribution of this file, with or without modification, # are permitted provided the copyright notice and this notice are preserved. # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the # slackware version of dircolors) are recognized but ignored. -# Below are TERM entries, which can be a glob patterns, to match -# against the TERM environment variable to determine if it is colorizable. +# Global config options can be specified before TERM or COLORTERM entries +# Below are TERM or COLORTERM entries, which can be glob patterns, which +# restrict following config to systems with matching environment variables. +COLORTERM ?* TERM Eterm TERM ansi -TERM color-xterm +TERM *color* TERM con[0-9]*x[0-9]* TERM cons25 TERM console TERM cygwin +TERM *direct* TERM dtterm -TERM eterm-color TERM gnome -TERM gnome-256color TERM hurd TERM jfbterm TERM konsole TERM kterm TERM linux TERM linux-c -TERM mach-color -TERM mach-gnu-color TERM mlterm TERM putty -TERM putty-256color TERM rxvt* TERM screen* TERM st -TERM st-256color TERM terminator TERM tmux* TERM vt100 TERM xterm* -# Below are the color init strings for the basic file types. A color init -# string consists of one or more of the following numeric codes: +# Below are the color init strings for the basic file types. +# One can use codes for 256 or more colors supported by modern terminals. +# The default color codes use the capabilities of an 8 color terminal +# with some additional attributes as per the following codes: # Attribute codes: # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed # Text color codes: @@ -61,14 +60,14 @@ ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... MISSING 00 # ... and the files they point to SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) -CAPABILITY 30;41 # file with capability +CAPABILITY 00 # file with capability (very expensive to lookup) STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: EXEC 01;32 # List any file extensions like '.gz' or '.tar' that you would like ls -# to colorize below. Put the extension, a space, and the color init string. +# to color below. Put the extension, a space, and the color init string. # (and any comments you want to add after a '#') # If you use DOS-style suffixes, you may want to uncomment the following: #.cmd 01;32 # executables (bright green) @@ -76,7 +75,7 @@ EXEC 01;32 #.com 01;32 #.btm 01;32 #.bat 01;32 -# Or if you want to colorize scripts even if they do not have the +# Or if you want to color scripts even if they do not have the # executable bit actually set. #.sh 01;32 #.csh 01;32 @@ -96,13 +95,14 @@ EXEC 01;32 .t7z 01;31 .zip 01;31 .z 01;31 -.Z 01;31 .dz 01;31 .gz 01;31 .lrz 01;31 .lz 01;31 .lzo 01;31 .xz 01;31 +.zst 01;31 +.tzst 01;31 .bz2 01;31 .bz 01;31 .tbz 01;31 @@ -122,9 +122,16 @@ EXEC 01;32 .7z 01;31 .rz 01;31 .cab 01;31 +.wim 01;31 +.swm 01;31 +.dwm 01;31 +.esd 01;31 # image formats +.avif 01;35 .jpg 01;35 .jpeg 01;35 +.mjpg 01;35 +.mjpeg 01;35 .gif 01;35 .bmp 01;35 .pbm 01;35 @@ -146,6 +153,7 @@ EXEC 01;32 .m2v 01;35 .mkv 01;35 .webm 01;35 +.webp 01;35 .ogm 01;35 .mp4 01;35 .m4v 01;35 @@ -168,7 +176,7 @@ EXEC 01;32 .yuv 01;35 .cgm 01;35 .emf 01;35 -# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +# https://wiki.xiph.org/MIME_Types_and_File_Extensions .ogv 01;35 .ogx 01;35 # audio formats @@ -184,8 +192,28 @@ EXEC 01;32 .ogg 00;36 .ra 00;36 .wav 00;36 -# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +# https://wiki.xiph.org/MIME_Types_and_File_Extensions .oga 00;36 .opus 00;36 .spx 00;36 .xspf 00;36 +# backup files +*~ 00;90 +*# 00;90 +.bak 00;90 +.old 00;90 +.orig 00;90 +.part 00;90 +.rej 00;90 +.swp 00;90 +.tmp 00;90 +.dpkg-dist 00;90 +.dpkg-old 00;90 +.ucf-dist 00;90 +.ucf-new 00;90 +.ucf-old 00;90 +.rpmnew 00;90 +.rpmorig 00;90 +.rpmsave 00;90 +# Subsequent TERM or COLORTERM entries, can be used to add / override +# config specific to those matching environment variables. From 74a5938acf4ed096c8c05a75bfd5c6b41765095d Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 24 May 2022 15:32:01 +0200 Subject: [PATCH 7/8] dircolors: test for correct error for -bp and -cp --- tests/by-util/test_dircolors.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_dircolors.rs b/tests/by-util/test_dircolors.rs index fac4161f3..edbc83bbb 100644 --- a/tests/by-util/test_dircolors.rs +++ b/tests/by-util/test_dircolors.rs @@ -87,7 +87,14 @@ fn test_no_env() { #[test] fn test_exclusive_option() { - new_ucmd!().arg("-cp").fails(); + new_ucmd!() + .arg("-bp") + .fails() + .stderr_contains("mutually exclusive"); + new_ucmd!() + .arg("-cp") + .fails() + .stderr_contains("mutually exclusive"); } fn test_helper(file_name: &str, term: &str) { From c810a5e05107bbb8fb757e9df991cd41a7675e86 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 23 May 2022 15:22:08 +0200 Subject: [PATCH 8/8] be consistent in the rustflag declaration --- .cargo/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cargo/config b/.cargo/config index 26008597f..35da7a485 100644 --- a/.cargo/config +++ b/.cargo/config @@ -14,7 +14,7 @@ rustflags = [ # See https://github.com/time-rs/time/issues/293#issuecomment-1005002386. The # unsoundness here is not in the `time` library, but in the Rust stdlib, and as # such it needs to be fixed there. -rustflags = "--cfg unsound_local_offset" +rustflags = ["--cfg", "unsound_local_offset"] [target.'cfg(target_os = "linux")'] rustflags = ["--cfg", "unsound_local_offset"]