added a total-size flag, that calculates the total size of directories recursively

This commit is contained in:
Philipp Mildenberger 2019-06-16 20:48:35 +02:00 committed by Abin Simon
parent 3facd44840
commit 744efce1b8
5 changed files with 80 additions and 1 deletions

View file

@ -124,6 +124,12 @@ pub fn build() -> App<'static, 'static> {
.number_of_values(1) .number_of_values(1)
.help("How to display size"), .help("How to display size"),
) )
.arg(
Arg::with_name("total-size")
.long("total-size")
.multiple(true)
.help("Display the total size of directories"),
)
.arg( .arg(
Arg::with_name("date") Arg::with_name("date")
.long("date") .long("date")

View file

@ -116,6 +116,11 @@ impl Core {
} }
}; };
} }
if self.flags.total_size {
for meta in &mut meta_list.iter_mut() {
meta.calculate_total_size();
}
}
meta_list meta_list
} }

View file

@ -17,6 +17,7 @@ pub struct Flags {
pub recursion_depth: usize, pub recursion_depth: usize,
pub blocks: Vec<Block>, pub blocks: Vec<Block>,
pub no_symlink: bool, pub no_symlink: bool,
pub total_size: bool,
} }
impl Flags { impl Flags {
@ -91,6 +92,7 @@ impl Flags {
None => usize::max_value(), None => usize::max_value(),
}; };
let no_symlink = matches.is_present("no-symlink"); let no_symlink = matches.is_present("no-symlink");
let total_size = matches.is_present("total-size");
Ok(Self { Ok(Self {
display, display,
@ -125,6 +127,7 @@ impl Flags {
DirOrderFlag::from(dir_order_inputs[dir_order_inputs.len() - 1]) DirOrderFlag::from(dir_order_inputs[dir_order_inputs.len() - 1])
}, },
no_symlink, no_symlink,
total_size,
}) })
} }
} }
@ -154,6 +157,7 @@ impl Default for Flags {
Block::Name, Block::Name,
], ],
no_symlink: false, no_symlink: false,
total_size: false,
} }
} }
} }

View file

@ -101,7 +101,7 @@ impl Meta {
} }
} }
let mut entry_meta = match Self::from_path(&path.to_path_buf()) { let mut entry_meta = match Self::from_path(&path) {
Ok(res) => res, Ok(res) => res,
Err(err) => { Err(err) => {
eprintln!("cannot access '{}': {}", path.display(), err); eprintln!("cannot access '{}': {}", path.display(), err);
@ -123,6 +123,66 @@ impl Meta {
Ok(Some(content)) Ok(Some(content))
} }
pub fn calculate_total_size(&mut self) {
if let FileType::Directory{ uid: _ } = self.file_type {
if let Some(metas) = &mut self.content {
let mut size_accumulated = self.size.get_bytes();
for x in &mut metas.iter_mut() {
x.calculate_total_size();
size_accumulated += x.size.get_bytes();
}
self.size = Size::new(size_accumulated);
} else { // possibility that 'depth' limited the recursion in 'recurse_into'
self.size = Size::new(Meta::calculate_total_file_size(&self.path));
}
}
}
fn calculate_total_file_size(path: &PathBuf) -> u64 {
let metadata = if read_link(&path).is_ok() {
// If the file is a link, retrieve the metadata without following
// the link.
path.symlink_metadata()
} else {
path.metadata()
};
let metadata = match metadata {
Ok(meta) => meta,
Err(err) => {
eprintln!("cannot access '{}': {}", path.display(), err);
return 0;
}
};
let file_type = metadata.file_type();
if file_type.is_file() {
metadata.len()
} else if file_type.is_dir() {
let mut size = metadata.len();
let entries = match path.read_dir() {
Ok(entries) => entries,
Err(err) => {
eprintln!("cannot access '{}': {}", path.display(), err);
return size;
}
};
for entry in entries {
let path = match entry {
Ok(entry) => entry.path(),
Err(err) => {
eprintln!("cannot access '{}': {}", path.display(), err);
continue;
}
};
size += Meta::calculate_total_file_size(&path);
}
size
}
else {
0
}
}
pub fn from_path(path: &PathBuf) -> Result<Self, std::io::Error> { pub fn from_path(path: &PathBuf) -> Result<Self, std::io::Error> {
let metadata = if read_link(path).is_ok() { let metadata = if read_link(path).is_ok() {
// If the file is a link, retrieve the metadata without following // If the file is a link, retrieve the metadata without following

View file

@ -25,6 +25,10 @@ impl<'a> From<&'a Metadata> for Size {
} }
impl Size { impl Size {
pub fn new(bytes: u64) -> Self {
Self { bytes: bytes }
}
pub fn get_bytes(&self) -> u64 { pub fn get_bytes(&self) -> u64 {
self.bytes self.bytes
} }