From a9b40f8313aa5194ae226a7ce1da696fd0e21d84 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 8 May 2022 17:09:05 +0200 Subject: [PATCH] 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 594c18acc05..19254ce9f29 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 a11dcf7a0e3..0c3b42fbc7a 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; @@ -173,7 +173,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::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 157818d958c..5c7d3ba6390 100644 --- a/tests/by-util/test_df.rs +++ b/tests/by-util/test_df.rs @@ -508,6 +508,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) {