mirror of
https://github.com/nushell/nushell
synced 2024-12-25 12:33:17 +00:00
du: add -l/--long
flag, remove -a/--all
flag (#14407)
# 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<DirInfo> for Value` and `impl From<FileInfo> 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<DirInfo> for Value` and `impl From<FileInfo> 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
This commit is contained in:
parent
8f9aa1a250
commit
dff6268d66
3 changed files with 84 additions and 42 deletions
|
@ -12,8 +12,8 @@ pub struct Du;
|
||||||
#[derive(Deserialize, Clone, Debug)]
|
#[derive(Deserialize, Clone, Debug)]
|
||||||
pub struct DuArgs {
|
pub struct DuArgs {
|
||||||
path: Option<Spanned<NuGlob>>,
|
path: Option<Spanned<NuGlob>>,
|
||||||
all: bool,
|
|
||||||
deref: bool,
|
deref: bool,
|
||||||
|
long: bool,
|
||||||
exclude: Option<Spanned<NuGlob>>,
|
exclude: Option<Spanned<NuGlob>>,
|
||||||
#[serde(rename = "max-depth")]
|
#[serde(rename = "max-depth")]
|
||||||
max_depth: Option<Spanned<i64>>,
|
max_depth: Option<Spanned<i64>>,
|
||||||
|
@ -49,6 +49,11 @@ impl Command for Du {
|
||||||
"Dereference symlinks to their targets for size",
|
"Dereference symlinks to their targets for size",
|
||||||
Some('r'),
|
Some('r'),
|
||||||
)
|
)
|
||||||
|
.switch(
|
||||||
|
"long",
|
||||||
|
"Get underlying directories and files for each entry",
|
||||||
|
Some('l'),
|
||||||
|
)
|
||||||
.named(
|
.named(
|
||||||
"exclude",
|
"exclude",
|
||||||
SyntaxShape::GlobPattern,
|
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 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")?;
|
let exclude = call.get_flag(engine_state, stack, "exclude")?;
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let current_dir = current_dir(engine_state, stack)?;
|
let current_dir = current_dir(engine_state, stack)?;
|
||||||
|
@ -111,8 +116,8 @@ impl Command for Du {
|
||||||
None => {
|
None => {
|
||||||
let args = DuArgs {
|
let args = DuArgs {
|
||||||
path: None,
|
path: None,
|
||||||
all,
|
|
||||||
deref,
|
deref,
|
||||||
|
long,
|
||||||
exclude,
|
exclude,
|
||||||
max_depth,
|
max_depth,
|
||||||
min_size,
|
min_size,
|
||||||
|
@ -127,8 +132,8 @@ impl Command for Du {
|
||||||
for p in paths {
|
for p in paths {
|
||||||
let args = DuArgs {
|
let args = DuArgs {
|
||||||
path: Some(p),
|
path: Some(p),
|
||||||
all,
|
|
||||||
deref,
|
deref,
|
||||||
|
long,
|
||||||
exclude: exclude.clone(),
|
exclude: exclude.clone(),
|
||||||
max_depth,
|
max_depth,
|
||||||
min_size,
|
min_size,
|
||||||
|
@ -174,7 +179,6 @@ fn du_for_one_pattern(
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let include_files = args.all;
|
|
||||||
let mut paths = match args.path {
|
let mut paths = match args.path {
|
||||||
Some(p) => nu_engine::glob_from(&p, current_dir, span, None),
|
Some(p) => nu_engine::glob_from(&p, current_dir, span, None),
|
||||||
// The * pattern should never fail.
|
// The * pattern should never fail.
|
||||||
|
@ -188,17 +192,10 @@ fn du_for_one_pattern(
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
.map(|f| f.1)?
|
.map(|f| f.1)?;
|
||||||
.filter(move |p| {
|
|
||||||
if include_files {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
matches!(p, Ok(f) if f.is_dir())
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let all = args.all;
|
|
||||||
let deref = args.deref;
|
let deref = args.deref;
|
||||||
|
let long = args.long;
|
||||||
let max_depth = args.max_depth.map(|f| f.item as u64);
|
let max_depth = args.max_depth.map(|f| f.item as u64);
|
||||||
let min_size = args.min_size.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,
|
min: min_size,
|
||||||
deref,
|
deref,
|
||||||
exclude,
|
exclude,
|
||||||
all,
|
long,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut output: Vec<Value> = vec![];
|
let mut output: Vec<Value> = vec![];
|
||||||
|
@ -216,7 +213,7 @@ fn du_for_one_pattern(
|
||||||
Ok(a) => {
|
Ok(a) => {
|
||||||
if a.is_dir() {
|
if a.is_dir() {
|
||||||
output.push(DirInfo::new(a, ¶ms, max_depth, span, signals)?.into());
|
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());
|
output.push(v.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub struct DirBuilder {
|
||||||
pub min: Option<u64>,
|
pub min: Option<u64>,
|
||||||
pub deref: bool,
|
pub deref: bool,
|
||||||
pub exclude: Option<Pattern>,
|
pub exclude: Option<Pattern>,
|
||||||
pub all: bool,
|
pub long: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DirBuilder {
|
impl DirBuilder {
|
||||||
|
@ -18,14 +18,14 @@ impl DirBuilder {
|
||||||
min: Option<u64>,
|
min: Option<u64>,
|
||||||
deref: bool,
|
deref: bool,
|
||||||
exclude: Option<Pattern>,
|
exclude: Option<Pattern>,
|
||||||
all: bool,
|
long: bool,
|
||||||
) -> DirBuilder {
|
) -> DirBuilder {
|
||||||
DirBuilder {
|
DirBuilder {
|
||||||
tag,
|
tag,
|
||||||
min,
|
min,
|
||||||
deref,
|
deref,
|
||||||
exclude,
|
exclude,
|
||||||
all,
|
long,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ pub struct DirInfo {
|
||||||
blocks: u64,
|
blocks: u64,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
tag: Span,
|
tag: Span,
|
||||||
|
long: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -47,10 +48,16 @@ pub struct FileInfo {
|
||||||
size: u64,
|
size: u64,
|
||||||
blocks: Option<u64>,
|
blocks: Option<u64>,
|
||||||
tag: Span,
|
tag: Span,
|
||||||
|
long: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileInfo {
|
impl FileInfo {
|
||||||
pub fn new(path: impl Into<PathBuf>, deref: bool, tag: Span) -> Result<Self, ShellError> {
|
pub fn new(
|
||||||
|
path: impl Into<PathBuf>,
|
||||||
|
deref: bool,
|
||||||
|
tag: Span,
|
||||||
|
long: bool,
|
||||||
|
) -> Result<Self, ShellError> {
|
||||||
let path = path.into();
|
let path = path.into();
|
||||||
let m = if deref {
|
let m = if deref {
|
||||||
std::fs::metadata(&path)
|
std::fs::metadata(&path)
|
||||||
|
@ -67,6 +74,7 @@ impl FileInfo {
|
||||||
blocks: block_size,
|
blocks: block_size,
|
||||||
size: d.len(),
|
size: d.len(),
|
||||||
tag,
|
tag,
|
||||||
|
long,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
|
@ -92,6 +100,7 @@ impl DirInfo {
|
||||||
blocks: 0,
|
blocks: 0,
|
||||||
tag: params.tag,
|
tag: params.tag,
|
||||||
path,
|
path,
|
||||||
|
long: params.long,
|
||||||
};
|
};
|
||||||
|
|
||||||
match std::fs::metadata(&s.path) {
|
match std::fs::metadata(&s.path) {
|
||||||
|
@ -154,13 +163,13 @@ impl DirInfo {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(true, |x| !x.matches_path(&f));
|
.map_or(true, |x| !x.matches_path(&f));
|
||||||
if include {
|
if include {
|
||||||
match FileInfo::new(f, params.deref, self.tag) {
|
match FileInfo::new(f, params.deref, self.tag, self.long) {
|
||||||
Ok(file) => {
|
Ok(file) => {
|
||||||
let inc = params.min.map_or(true, |s| file.size >= s);
|
let inc = params.min.map_or(true, |s| file.size >= s);
|
||||||
if inc {
|
if inc {
|
||||||
self.size += file.size;
|
self.size += file.size;
|
||||||
self.blocks += file.blocks.unwrap_or(0);
|
self.blocks += file.blocks.unwrap_or(0);
|
||||||
if params.all {
|
if params.long {
|
||||||
self.files.push(file);
|
self.files.push(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,16 +206,27 @@ impl From<DirInfo> for Value {
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
Value::record(
|
if d.long {
|
||||||
record! {
|
Value::record(
|
||||||
"path" => Value::string(d.path.display().to_string(), d.tag),
|
record! {
|
||||||
"apparent" => Value::filesize(d.size as i64, d.tag),
|
"path" => Value::string(d.path.display().to_string(), d.tag),
|
||||||
"physical" => Value::filesize(d.blocks as i64, d.tag),
|
"apparent" => Value::filesize(d.size as i64, d.tag),
|
||||||
"directories" => value_from_vec(d.dirs, d.tag),
|
"physical" => Value::filesize(d.blocks as i64, d.tag),
|
||||||
"files" => value_from_vec(d.files, d.tag)
|
"directories" => value_from_vec(d.dirs, d.tag),
|
||||||
},
|
"files" => value_from_vec(d.files, d.tag)
|
||||||
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<FileInfo> for Value {
|
||||||
// cols.push("errors".into());
|
// cols.push("errors".into());
|
||||||
// vals.push(Value::nothing(Span::unknown()));
|
// vals.push(Value::nothing(Span::unknown()));
|
||||||
|
|
||||||
Value::record(
|
if f.long {
|
||||||
record! {
|
Value::record(
|
||||||
"path" => Value::string(f.path.display().to_string(), f.tag),
|
record! {
|
||||||
"apparent" => Value::filesize(f.size as i64, f.tag),
|
"path" => Value::string(f.path.display().to_string(), f.tag),
|
||||||
"physical" => Value::filesize(f.blocks.unwrap_or(0) as i64, f.tag),
|
"apparent" => Value::filesize(f.size as i64, f.tag),
|
||||||
"directories" => Value::nothing(Span::unknown()),
|
"physical" => Value::filesize(f.blocks.unwrap_or(0) as i64, f.tag),
|
||||||
"files" => Value::nothing(Span::unknown()),
|
"directories" => Value::nothing(Span::unknown()),
|
||||||
},
|
"files" => Value::nothing(Span::unknown()),
|
||||||
f.tag,
|
},
|
||||||
)
|
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,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,3 +100,17 @@ fn du_with_multiple_path() {
|
||||||
let actual = nu!(cwd: "tests/fixtures", "du ...[] | length");
|
let actual = nu!(cwd: "tests/fixtures", "du ...[] | length");
|
||||||
assert_eq!(actual.out, "0");
|
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");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue