From dff6268d664f1511088394c32d424a12959c8747 Mon Sep 17 00:00:00 2001 From: Wind Date: Wed, 11 Dec 2024 01:22:56 +0800 Subject: [PATCH] du: add `-l/--long` flag, remove `-a/--all` flag (#14407) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Closes: #14387 ~To make it happen, just need to added `-l` flag to `du`, and pass it to `DirBuilder`, `DirInfo`, `FileInfo` Then tweak `impl From for Value` and `impl From for Value` impl.~ --- Edit: this PR is going to: 1. Exclude directories and files columns by default 2. Added `-l/--long` flag to output directories and files columns 3. When running `du`, it will output the files as well. Previously it doesn't output the size of file. To make it happen, just need to added `-r` flag to `du`, and pass it to `DirBuilder`, `DirInfo`, `FileInfo` Then tweak `impl From for Value` and `impl From for Value` impl. And rename some variables. # User-Facing Changes `du` is no longer output `directories` and `file` columns by default, added `-r` flag will show `directories` column, `-f` flag will show `files` column. ```nushell > du nushell ╭───┬────────────────────────────────────┬──────────┬──────────╮ │ # │ path │ apparent │ physical │ ├───┼────────────────────────────────────┼──────────┼──────────┤ │ 0 │ /home/windsoilder/projects/nushell │ 34.6 GiB │ 34.7 GiB │ ├───┼────────────────────────────────────┼──────────┼──────────┤ │ # │ path │ apparent │ physical │ ╰───┴────────────────────────────────────┴──────────┴──────────╯ > du nushell --recursive --files # It outputs two more columns, `directories` and `files`, but the output is too long to paste here. ``` # Tests + Formatting Added 1 test # After Submitting NaN --- crates/nu-command/src/filesystem/du.rs | 29 ++++---- crates/nu-command/src/platform/dir_info.rs | 83 +++++++++++++++------- crates/nu-command/tests/commands/du.rs | 14 ++++ 3 files changed, 84 insertions(+), 42 deletions(-) diff --git a/crates/nu-command/src/filesystem/du.rs b/crates/nu-command/src/filesystem/du.rs index 0981d2c0ee..15dc0d78d6 100644 --- a/crates/nu-command/src/filesystem/du.rs +++ b/crates/nu-command/src/filesystem/du.rs @@ -12,8 +12,8 @@ pub struct Du; #[derive(Deserialize, Clone, Debug)] pub struct DuArgs { path: Option>, - all: bool, deref: bool, + long: bool, exclude: Option>, #[serde(rename = "max-depth")] max_depth: Option>, @@ -49,6 +49,11 @@ impl Command for Du { "Dereference symlinks to their targets for size", Some('r'), ) + .switch( + "long", + "Get underlying directories and files for each entry", + Some('l'), + ) .named( "exclude", SyntaxShape::GlobPattern, @@ -94,8 +99,8 @@ impl Command for Du { }); } } - let all = call.has_flag(engine_state, stack, "all")?; let deref = call.has_flag(engine_state, stack, "deref")?; + let long = call.has_flag(engine_state, stack, "long")?; let exclude = call.get_flag(engine_state, stack, "exclude")?; #[allow(deprecated)] let current_dir = current_dir(engine_state, stack)?; @@ -111,8 +116,8 @@ impl Command for Du { None => { let args = DuArgs { path: None, - all, deref, + long, exclude, max_depth, min_size, @@ -127,8 +132,8 @@ impl Command for Du { for p in paths { let args = DuArgs { path: Some(p), - all, deref, + long, exclude: exclude.clone(), max_depth, min_size, @@ -174,7 +179,6 @@ fn du_for_one_pattern( }) })?; - let include_files = args.all; let mut paths = match args.path { Some(p) => nu_engine::glob_from(&p, current_dir, span, None), // The * pattern should never fail. @@ -188,17 +192,10 @@ fn du_for_one_pattern( None, ), } - .map(|f| f.1)? - .filter(move |p| { - if include_files { - true - } else { - matches!(p, Ok(f) if f.is_dir()) - } - }); + .map(|f| f.1)?; - let all = args.all; let deref = args.deref; + let long = args.long; let max_depth = args.max_depth.map(|f| f.item as u64); let min_size = args.min_size.map(|f| f.item as u64); @@ -207,7 +204,7 @@ fn du_for_one_pattern( min: min_size, deref, exclude, - all, + long, }; let mut output: Vec = vec![]; @@ -216,7 +213,7 @@ fn du_for_one_pattern( Ok(a) => { if a.is_dir() { output.push(DirInfo::new(a, ¶ms, max_depth, span, signals)?.into()); - } else if let Ok(v) = FileInfo::new(a, deref, span) { + } else if let Ok(v) = FileInfo::new(a, deref, span, params.long) { output.push(v.into()); } } diff --git a/crates/nu-command/src/platform/dir_info.rs b/crates/nu-command/src/platform/dir_info.rs index 10ce4f5420..9b8ea1929e 100644 --- a/crates/nu-command/src/platform/dir_info.rs +++ b/crates/nu-command/src/platform/dir_info.rs @@ -9,7 +9,7 @@ pub struct DirBuilder { pub min: Option, pub deref: bool, pub exclude: Option, - pub all: bool, + pub long: bool, } impl DirBuilder { @@ -18,14 +18,14 @@ impl DirBuilder { min: Option, deref: bool, exclude: Option, - all: bool, + long: bool, ) -> DirBuilder { DirBuilder { tag, min, deref, exclude, - all, + long, } } } @@ -39,6 +39,7 @@ pub struct DirInfo { blocks: u64, path: PathBuf, tag: Span, + long: bool, } #[derive(Debug, Clone)] @@ -47,10 +48,16 @@ pub struct FileInfo { size: u64, blocks: Option, tag: Span, + long: bool, } impl FileInfo { - pub fn new(path: impl Into, deref: bool, tag: Span) -> Result { + pub fn new( + path: impl Into, + deref: bool, + tag: Span, + long: bool, + ) -> Result { let path = path.into(); let m = if deref { std::fs::metadata(&path) @@ -67,6 +74,7 @@ impl FileInfo { blocks: block_size, size: d.len(), tag, + long, }) } Err(e) => Err(e.into()), @@ -92,6 +100,7 @@ impl DirInfo { blocks: 0, tag: params.tag, path, + long: params.long, }; match std::fs::metadata(&s.path) { @@ -154,13 +163,13 @@ impl DirInfo { .as_ref() .map_or(true, |x| !x.matches_path(&f)); if include { - match FileInfo::new(f, params.deref, self.tag) { + match FileInfo::new(f, params.deref, self.tag, self.long) { Ok(file) => { let inc = params.min.map_or(true, |s| file.size >= s); if inc { self.size += file.size; self.blocks += file.blocks.unwrap_or(0); - if params.all { + if params.long { self.files.push(file); } } @@ -197,16 +206,27 @@ impl From for Value { // }) // } - Value::record( - record! { - "path" => Value::string(d.path.display().to_string(), d.tag), - "apparent" => Value::filesize(d.size as i64, d.tag), - "physical" => Value::filesize(d.blocks as i64, d.tag), - "directories" => value_from_vec(d.dirs, d.tag), - "files" => value_from_vec(d.files, d.tag) - }, - d.tag, - ) + if d.long { + Value::record( + record! { + "path" => Value::string(d.path.display().to_string(), d.tag), + "apparent" => Value::filesize(d.size as i64, d.tag), + "physical" => Value::filesize(d.blocks as i64, d.tag), + "directories" => value_from_vec(d.dirs, d.tag), + "files" => value_from_vec(d.files, d.tag) + }, + d.tag, + ) + } else { + Value::record( + record! { + "path" => Value::string(d.path.display().to_string(), d.tag), + "apparent" => Value::filesize(d.size as i64, d.tag), + "physical" => Value::filesize(d.blocks as i64, d.tag), + }, + d.tag, + ) + } } } @@ -215,16 +235,27 @@ impl From for Value { // cols.push("errors".into()); // vals.push(Value::nothing(Span::unknown())); - Value::record( - record! { - "path" => Value::string(f.path.display().to_string(), f.tag), - "apparent" => Value::filesize(f.size as i64, f.tag), - "physical" => Value::filesize(f.blocks.unwrap_or(0) as i64, f.tag), - "directories" => Value::nothing(Span::unknown()), - "files" => Value::nothing(Span::unknown()), - }, - f.tag, - ) + if f.long { + Value::record( + record! { + "path" => Value::string(f.path.display().to_string(), f.tag), + "apparent" => Value::filesize(f.size as i64, f.tag), + "physical" => Value::filesize(f.blocks.unwrap_or(0) as i64, f.tag), + "directories" => Value::nothing(Span::unknown()), + "files" => Value::nothing(Span::unknown()), + }, + f.tag, + ) + } else { + Value::record( + record! { + "path" => Value::string(f.path.display().to_string(), f.tag), + "apparent" => Value::filesize(f.size as i64, f.tag), + "physical" => Value::filesize(f.blocks.unwrap_or(0) as i64, f.tag), + }, + f.tag, + ) + } } } diff --git a/crates/nu-command/tests/commands/du.rs b/crates/nu-command/tests/commands/du.rs index 1e22d54f2f..c88eb546be 100644 --- a/crates/nu-command/tests/commands/du.rs +++ b/crates/nu-command/tests/commands/du.rs @@ -100,3 +100,17 @@ fn du_with_multiple_path() { let actual = nu!(cwd: "tests/fixtures", "du ...[] | length"); assert_eq!(actual.out, "0"); } + +#[test] +fn test_du_output_columns() { + let actual = nu!( + cwd: "tests/fixtures/formats", + "du -m 1 | columns | str join ','" + ); + assert_eq!(actual.out, "path,apparent,physical"); + let actual = nu!( + cwd: "tests/fixtures/formats", + "du -m 1 -l | columns | str join ','" + ); + assert_eq!(actual.out, "path,apparent,physical,directories,files"); +}