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"
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",

View file

@ -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"

View file

@ -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, &params, 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,