mirror of
https://github.com/nushell/nushell
synced 2025-01-26 11:55:20 +00:00
Display either dir metadata size or dir apparent size in ls
(#1696)
* Show dir size in ls command * Add the option to show the apparent directory size via `ls --du`
This commit is contained in:
parent
0779a46179
commit
8d69c77989
4 changed files with 58 additions and 6 deletions
|
@ -143,7 +143,7 @@ fn du(args: DuArgs, ctx: RunnableContext) -> Result<OutputStream, ShellError> {
|
||||||
Ok(stream.to_output_stream())
|
Ok(stream.to_output_stream())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DirBuilder {
|
pub struct DirBuilder {
|
||||||
tag: Tag,
|
tag: Tag,
|
||||||
min: Option<u64>,
|
min: Option<u64>,
|
||||||
deref: bool,
|
deref: bool,
|
||||||
|
@ -151,7 +151,25 @@ struct DirBuilder {
|
||||||
all: bool,
|
all: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DirInfo {
|
impl DirBuilder {
|
||||||
|
pub fn new(
|
||||||
|
tag: Tag,
|
||||||
|
min: Option<u64>,
|
||||||
|
deref: bool,
|
||||||
|
exclude: Option<Pattern>,
|
||||||
|
all: bool,
|
||||||
|
) -> DirBuilder {
|
||||||
|
DirBuilder {
|
||||||
|
tag,
|
||||||
|
min,
|
||||||
|
deref,
|
||||||
|
exclude,
|
||||||
|
all,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DirInfo {
|
||||||
dirs: Vec<DirInfo>,
|
dirs: Vec<DirInfo>,
|
||||||
files: Vec<FileInfo>,
|
files: Vec<FileInfo>,
|
||||||
errors: Vec<ShellError>,
|
errors: Vec<ShellError>,
|
||||||
|
@ -194,7 +212,7 @@ impl FileInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DirInfo {
|
impl DirInfo {
|
||||||
fn new(path: impl Into<PathBuf>, params: &DirBuilder, depth: Option<u64>) -> Self {
|
pub fn new(path: impl Into<PathBuf>, params: &DirBuilder, depth: Option<u64>) -> Self {
|
||||||
let path = path.into();
|
let path = path.into();
|
||||||
|
|
||||||
let mut s = Self {
|
let mut s = Self {
|
||||||
|
@ -274,6 +292,10 @@ impl DirInfo {
|
||||||
self.errors.push(e);
|
self.errors.push(e);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> u64 {
|
||||||
|
self.size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glob_err_into(e: GlobError) -> ShellError {
|
fn glob_err_into(e: GlobError) -> ShellError {
|
||||||
|
|
|
@ -16,6 +16,8 @@ pub struct LsArgs {
|
||||||
pub short_names: bool,
|
pub short_names: bool,
|
||||||
#[serde(rename = "with-symlink-targets")]
|
#[serde(rename = "with-symlink-targets")]
|
||||||
pub with_symlink_targets: bool,
|
pub with_symlink_targets: bool,
|
||||||
|
#[serde(rename = "du")]
|
||||||
|
pub du: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WholeStreamCommand for Ls {
|
impl WholeStreamCommand for Ls {
|
||||||
|
@ -46,6 +48,11 @@ impl WholeStreamCommand for Ls {
|
||||||
"display the paths to the target files that symlinks point to",
|
"display the paths to the target files that symlinks point to",
|
||||||
Some('w'),
|
Some('w'),
|
||||||
)
|
)
|
||||||
|
.switch(
|
||||||
|
"du",
|
||||||
|
"display the apparent directory size in place of the directory metadata size",
|
||||||
|
Some('d'),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::commands::du::{DirBuilder, DirInfo};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{TaggedDictBuilder, UntaggedValue, Value};
|
use nu_protocol::{TaggedDictBuilder, UntaggedValue, Value};
|
||||||
|
@ -38,6 +39,7 @@ pub(crate) fn dir_entry_dict(
|
||||||
full: bool,
|
full: bool,
|
||||||
short_name: bool,
|
short_name: bool,
|
||||||
with_symlink_targets: bool,
|
with_symlink_targets: bool,
|
||||||
|
du: bool,
|
||||||
) -> Result<Value, ShellError> {
|
) -> Result<Value, ShellError> {
|
||||||
let tag = tag.into();
|
let tag = tag.into();
|
||||||
let mut dict = TaggedDictBuilder::new(&tag);
|
let mut dict = TaggedDictBuilder::new(&tag);
|
||||||
|
@ -125,8 +127,27 @@ pub(crate) fn dir_entry_dict(
|
||||||
let mut size_untagged_value: UntaggedValue = UntaggedValue::nothing();
|
let mut size_untagged_value: UntaggedValue = UntaggedValue::nothing();
|
||||||
|
|
||||||
if let Some(md) = metadata {
|
if let Some(md) = metadata {
|
||||||
if md.is_file() {
|
if md.is_dir() {
|
||||||
size_untagged_value = UntaggedValue::bytes(md.len() as u64);
|
let dir_size: u64 = if du {
|
||||||
|
let params = DirBuilder::new(
|
||||||
|
Tag {
|
||||||
|
anchor: None,
|
||||||
|
span: Span::new(0, 2),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
DirInfo::new(filename, ¶ms, None).get_size()
|
||||||
|
} else {
|
||||||
|
md.len()
|
||||||
|
};
|
||||||
|
|
||||||
|
size_untagged_value = UntaggedValue::bytes(dir_size);
|
||||||
|
} else if md.is_file() {
|
||||||
|
size_untagged_value = UntaggedValue::bytes(md.len());
|
||||||
} else if md.file_type().is_symlink() {
|
} else if md.file_type().is_symlink() {
|
||||||
if let Ok(symlink_md) = filename.symlink_metadata() {
|
if let Ok(symlink_md) = filename.symlink_metadata() {
|
||||||
size_untagged_value = UntaggedValue::bytes(symlink_md.len() as u64);
|
size_untagged_value = UntaggedValue::bytes(symlink_md.len() as u64);
|
||||||
|
|
|
@ -107,6 +107,7 @@ impl Shell for FilesystemShell {
|
||||||
full,
|
full,
|
||||||
short_names,
|
short_names,
|
||||||
with_symlink_targets,
|
with_symlink_targets,
|
||||||
|
du,
|
||||||
}: LsArgs,
|
}: LsArgs,
|
||||||
context: &RunnableContext,
|
context: &RunnableContext,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
|
@ -170,7 +171,8 @@ impl Shell for FilesystemShell {
|
||||||
name_tag.clone(),
|
name_tag.clone(),
|
||||||
full,
|
full,
|
||||||
short_names,
|
short_names,
|
||||||
with_symlink_targets
|
with_symlink_targets,
|
||||||
|
du,
|
||||||
)
|
)
|
||||||
.map(|entry| ReturnSuccess::Value(entry.into()))?;
|
.map(|entry| ReturnSuccess::Value(entry.into()))?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue