forked from extern/nushell
Add block size to du (#1341)
* Add block size to du * Change blocks to physical size * Use path instead of strings for file/directory names * Why don't I just use paths instead of strings anyway? * shorten physical size and apparent size to physical and apparent resp.
This commit is contained in:
parent
29ccb9f5cd
commit
6a371802b4
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -931,6 +931,15 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||
|
||||
[[package]]
|
||||
name = "filesize"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a941e39ae509cebcd46c6734c20553a9a209b92cea5fc54618fe778fea61701"
|
||||
dependencies = [
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.1.9"
|
||||
@ -2201,6 +2210,7 @@ dependencies = [
|
||||
"derive-new",
|
||||
"dirs 2.0.2",
|
||||
"dunce",
|
||||
"filesize",
|
||||
"futures 0.3.3",
|
||||
"futures-util",
|
||||
"futures_codec",
|
||||
|
@ -133,6 +133,7 @@ onig_sys = {version = "=69.1.0", optional = true }
|
||||
crossterm = {version = "0.16.0", optional = true}
|
||||
url = {version = "2.1.1", optional = true}
|
||||
semver = {version = "0.9.0", optional = true}
|
||||
filesize = "0.1.0"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
users = "0.9"
|
||||
|
@ -1,5 +1,8 @@
|
||||
extern crate filesize;
|
||||
|
||||
use crate::commands::command::RunnablePerItemContext;
|
||||
use crate::prelude::*;
|
||||
use filesize::file_real_size_fast;
|
||||
use glob::*;
|
||||
use indexmap::map::IndexMap;
|
||||
use nu_errors::ShellError;
|
||||
@ -165,32 +168,38 @@ struct DirInfo {
|
||||
files: Vec<FileInfo>,
|
||||
errors: Vec<ShellError>,
|
||||
size: u64,
|
||||
name: String,
|
||||
blocks: u64,
|
||||
path: PathBuf,
|
||||
tag: Tag,
|
||||
}
|
||||
|
||||
struct FileInfo {
|
||||
name: String,
|
||||
path: PathBuf,
|
||||
size: u64,
|
||||
blocks: Option<u64>,
|
||||
tag: Tag,
|
||||
}
|
||||
|
||||
impl FileInfo {
|
||||
fn new(path: impl Into<PathBuf>, deref: bool, tag: Tag) -> Result<Self, ShellError> {
|
||||
let path = path.into();
|
||||
let name = path.to_string_lossy().to_string();
|
||||
let m = if deref {
|
||||
std::fs::metadata(path)
|
||||
std::fs::metadata(&path)
|
||||
} else {
|
||||
std::fs::symlink_metadata(path)
|
||||
std::fs::symlink_metadata(&path)
|
||||
};
|
||||
|
||||
match m {
|
||||
Ok(d) => Ok(FileInfo {
|
||||
name,
|
||||
size: d.len(),
|
||||
tag,
|
||||
}),
|
||||
Ok(d) => {
|
||||
let block_size = file_real_size_fast(&path, &d).ok();
|
||||
|
||||
Ok(FileInfo {
|
||||
path,
|
||||
blocks: block_size,
|
||||
size: d.len(),
|
||||
tag,
|
||||
})
|
||||
}
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
@ -205,11 +214,12 @@ impl DirInfo {
|
||||
errors: Vec::new(),
|
||||
files: Vec::new(),
|
||||
size: 0,
|
||||
blocks: 0,
|
||||
tag: params.tag.clone(),
|
||||
name: path.to_string_lossy().to_string(),
|
||||
path,
|
||||
};
|
||||
|
||||
match std::fs::read_dir(path) {
|
||||
match std::fs::read_dir(&s.path) {
|
||||
Ok(d) => {
|
||||
for f in d {
|
||||
match f {
|
||||
@ -247,6 +257,7 @@ impl DirInfo {
|
||||
|
||||
let d = DirInfo::new(path, ¶ms, depth);
|
||||
self.size += d.size;
|
||||
self.blocks += d.blocks;
|
||||
self.dirs.push(d);
|
||||
self
|
||||
}
|
||||
@ -260,6 +271,7 @@ impl DirInfo {
|
||||
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 {
|
||||
self.files.push(file);
|
||||
}
|
||||
@ -286,12 +298,16 @@ impl From<DirInfo> for Value {
|
||||
fn from(d: DirInfo) -> Self {
|
||||
let mut r: IndexMap<String, Value> = IndexMap::new();
|
||||
r.insert(
|
||||
"size".to_string(),
|
||||
UntaggedValue::bytes(d.size).into_untagged_value(),
|
||||
"path".to_string(),
|
||||
UntaggedValue::path(d.path).retag(d.tag.clone()),
|
||||
);
|
||||
r.insert(
|
||||
"name".to_string(),
|
||||
UntaggedValue::string(d.name).into_untagged_value(),
|
||||
"apparent".to_string(),
|
||||
UntaggedValue::bytes(d.size).retag(d.tag.clone()),
|
||||
);
|
||||
r.insert(
|
||||
"physical".to_string(),
|
||||
UntaggedValue::bytes(d.blocks).retag(d.tag.clone()),
|
||||
);
|
||||
if !d.files.is_empty() {
|
||||
let v = Value {
|
||||
@ -341,13 +357,18 @@ impl From<FileInfo> for Value {
|
||||
fn from(f: FileInfo) -> Self {
|
||||
let mut r: IndexMap<String, Value> = IndexMap::new();
|
||||
r.insert(
|
||||
"size".to_string(),
|
||||
UntaggedValue::bytes(f.size).into_untagged_value(),
|
||||
"path".to_string(),
|
||||
UntaggedValue::path(f.path).retag(f.tag.clone()),
|
||||
);
|
||||
r.insert(
|
||||
"name".to_string(),
|
||||
UntaggedValue::string(f.name).into_untagged_value(),
|
||||
"apparent".to_string(),
|
||||
UntaggedValue::bytes(f.size).retag(f.tag.clone()),
|
||||
);
|
||||
let b = match f.blocks {
|
||||
Some(k) => UntaggedValue::bytes(k).retag(f.tag.clone()),
|
||||
None => UntaggedValue::nothing().retag(f.tag.clone()),
|
||||
};
|
||||
r.insert("physical".to_string(), b);
|
||||
Value {
|
||||
value: UntaggedValue::row(r),
|
||||
tag: f.tag,
|
||||
|
Loading…
Reference in New Issue
Block a user