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"] diff --git a/Cargo.lock b/Cargo.lock index f8a9a4d41..cb169c6f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2286,7 +2286,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..b5b7cafa3 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}; @@ -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) + } } } @@ -189,7 +162,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,18 +172,41 @@ 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 { - 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 +216,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 +283,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..5bd478fd9 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}; @@ -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; @@ -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(), @@ -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(), @@ -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") ); } 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/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 102eadbe4..e145a3933 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -19,6 +19,11 @@ use std::fmt::Display; use std::iter; use std::path::{is_separator, Path, PathBuf, MAIN_SEPARATOR}; +#[cfg(unix)] +use std::fs; +#[cfg(unix)] +use std::os::unix::prelude::PermissionsExt; + use rand::Rng; use tempfile::Builder; @@ -267,7 +272,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..]; @@ -342,6 +351,11 @@ 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))?; + } + // Get just the last component of the path to the created // temporary file or directory. let filename = path.file_name(); 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) { 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) { diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 15a6b932f..86c4ba4db 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -7,6 +7,9 @@ use uucore::display::Quotable; 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"; @@ -501,6 +504,18 @@ fn test_respect_template_directory() { 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); +} + /// Test that a template with a path separator is invalid. #[test] fn test_template_path_separator() { @@ -527,3 +542,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"); +} 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.