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:
Corvus Corax 2020-02-10 14:32:18 -06:00 committed by GitHub
parent 29ccb9f5cd
commit 6a371802b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 20 deletions

10
Cargo.lock generated
View file

@ -931,6 +931,15 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" 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]] [[package]]
name = "fixedbitset" name = "fixedbitset"
version = "0.1.9" version = "0.1.9"
@ -2201,6 +2210,7 @@ dependencies = [
"derive-new", "derive-new",
"dirs 2.0.2", "dirs 2.0.2",
"dunce", "dunce",
"filesize",
"futures 0.3.3", "futures 0.3.3",
"futures-util", "futures-util",
"futures_codec", "futures_codec",

View file

@ -133,6 +133,7 @@ onig_sys = {version = "=69.1.0", optional = true }
crossterm = {version = "0.16.0", optional = true} crossterm = {version = "0.16.0", optional = true}
url = {version = "2.1.1", optional = true} url = {version = "2.1.1", optional = true}
semver = {version = "0.9.0", optional = true} semver = {version = "0.9.0", optional = true}
filesize = "0.1.0"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
users = "0.9" users = "0.9"

View file

@ -1,5 +1,8 @@
extern crate filesize;
use crate::commands::command::RunnablePerItemContext; use crate::commands::command::RunnablePerItemContext;
use crate::prelude::*; use crate::prelude::*;
use filesize::file_real_size_fast;
use glob::*; use glob::*;
use indexmap::map::IndexMap; use indexmap::map::IndexMap;
use nu_errors::ShellError; use nu_errors::ShellError;
@ -165,32 +168,38 @@ struct DirInfo {
files: Vec<FileInfo>, files: Vec<FileInfo>,
errors: Vec<ShellError>, errors: Vec<ShellError>,
size: u64, size: u64,
name: String, blocks: u64,
path: PathBuf,
tag: Tag, tag: Tag,
} }
struct FileInfo { struct FileInfo {
name: String, path: PathBuf,
size: u64, size: u64,
blocks: Option<u64>,
tag: Tag, tag: Tag,
} }
impl FileInfo { impl FileInfo {
fn new(path: impl Into<PathBuf>, deref: bool, tag: Tag) -> Result<Self, ShellError> { fn new(path: impl Into<PathBuf>, deref: bool, tag: Tag) -> Result<Self, ShellError> {
let path = path.into(); let path = path.into();
let name = path.to_string_lossy().to_string();
let m = if deref { let m = if deref {
std::fs::metadata(path) std::fs::metadata(&path)
} else { } else {
std::fs::symlink_metadata(path) std::fs::symlink_metadata(&path)
}; };
match m { match m {
Ok(d) => Ok(FileInfo { Ok(d) => {
name, let block_size = file_real_size_fast(&path, &d).ok();
Ok(FileInfo {
path,
blocks: block_size,
size: d.len(), size: d.len(),
tag, tag,
}), })
}
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
} }
@ -205,11 +214,12 @@ impl DirInfo {
errors: Vec::new(), errors: Vec::new(),
files: Vec::new(), files: Vec::new(),
size: 0, size: 0,
blocks: 0,
tag: params.tag.clone(), 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) => { Ok(d) => {
for f in d { for f in d {
match f { match f {
@ -247,6 +257,7 @@ impl DirInfo {
let d = DirInfo::new(path, &params, depth); let d = DirInfo::new(path, &params, depth);
self.size += d.size; self.size += d.size;
self.blocks += d.blocks;
self.dirs.push(d); self.dirs.push(d);
self self
} }
@ -260,6 +271,7 @@ impl DirInfo {
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);
if params.all { if params.all {
self.files.push(file); self.files.push(file);
} }
@ -286,12 +298,16 @@ impl From<DirInfo> for Value {
fn from(d: DirInfo) -> Self { fn from(d: DirInfo) -> Self {
let mut r: IndexMap<String, Value> = IndexMap::new(); let mut r: IndexMap<String, Value> = IndexMap::new();
r.insert( r.insert(
"size".to_string(), "path".to_string(),
UntaggedValue::bytes(d.size).into_untagged_value(), UntaggedValue::path(d.path).retag(d.tag.clone()),
); );
r.insert( r.insert(
"name".to_string(), "apparent".to_string(),
UntaggedValue::string(d.name).into_untagged_value(), 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() { if !d.files.is_empty() {
let v = Value { let v = Value {
@ -341,13 +357,18 @@ impl From<FileInfo> for Value {
fn from(f: FileInfo) -> Self { fn from(f: FileInfo) -> Self {
let mut r: IndexMap<String, Value> = IndexMap::new(); let mut r: IndexMap<String, Value> = IndexMap::new();
r.insert( r.insert(
"size".to_string(), "path".to_string(),
UntaggedValue::bytes(f.size).into_untagged_value(), UntaggedValue::path(f.path).retag(f.tag.clone()),
); );
r.insert( r.insert(
"name".to_string(), "apparent".to_string(),
UntaggedValue::string(f.name).into_untagged_value(), 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 {
value: UntaggedValue::row(r), value: UntaggedValue::row(r),
tag: f.tag, tag: f.tag,