summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2023-07-03 21:54:21 +0200
committerJustin Wernick <justin@worthe-it.co.za>2023-07-03 21:54:21 +0200
commite18a928db5916fce43c35dff585072dace0da7e0 (patch)
treed33c8d6c08a779b0f28ddff83ce540b3821160e4 /src
parentff05e4ab91b3b84ffb04b3d8089052112e7bd51c (diff)
Added a new "--verbose" option to the list command
Diffstat (limited to 'src')
-rw-r--r--src/git.rs40
-rw-r--r--src/lib.rs23
-rw-r--r--src/parser.rs9
3 files changed, 66 insertions, 6 deletions
diff --git a/src/git.rs b/src/git.rs
index c07615d..d92b5a0 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -109,6 +109,33 @@ pub struct RepoMetadata {
pub description: String,
}
+pub struct VerboseRepoMetadata {
+ pub path: PathBuf,
+ pub description: String,
+ pub size: u64,
+}
+
+fn get_size(path: impl AsRef<Path>) -> Result<u64, ShackleError> {
+ let path_metadata = path.as_ref().symlink_metadata()?;
+
+ if path_metadata.is_dir() {
+ let mut size_in_bytes = path_metadata.len();
+ for entry in path.as_ref().read_dir()? {
+ let entry = entry?;
+ let entry_metadata = entry.metadata()?;
+
+ if entry_metadata.is_dir() {
+ size_in_bytes += get_size(entry.path())?;
+ } else {
+ size_in_bytes += entry_metadata.len();
+ }
+ }
+ Ok(size_in_bytes)
+ } else {
+ Ok(path_metadata.len())
+ }
+}
+
pub fn list() -> Result<Vec<RepoMetadata>, ShackleError> {
fn add_from_dir(
collection_dir: &Path,
@@ -163,6 +190,19 @@ pub fn list() -> Result<Vec<RepoMetadata>, ShackleError> {
Ok(results)
}
+pub fn list_verbose() -> Result<Vec<VerboseRepoMetadata>, ShackleError> {
+ list()?
+ .into_iter()
+ .map(|meta| {
+ get_size(&meta.path).map(|size| VerboseRepoMetadata {
+ path: meta.path,
+ description: meta.description,
+ size,
+ })
+ })
+ .collect()
+}
+
pub fn set_description(directory: &Path, description: &str) -> Result<(), ShackleError> {
if !is_valid_git_repo_path(directory)? {
return Err(ShackleError::InvalidDirectory);
diff --git a/src/lib.rs b/src/lib.rs
index 32d5770..809c62d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,6 +3,7 @@ mod parser;
pub mod user_info;
use comfy_table::Table;
+use humansize::{format_size, BINARY};
use parser::*;
use rustyline::error::ReadlineError;
use std::{io, ops::ControlFlow};
@@ -16,12 +17,24 @@ pub fn run_command(user_input: &str) -> Result<ControlFlow<(), ()>, ShackleError
Ok(ShackleCommand::Exit) => {
return Ok(ControlFlow::Break(()));
}
- Ok(ShackleCommand::List) => {
+ Ok(ShackleCommand::List(ListArgs { verbose })) => {
let mut table = Table::new();
- table.set_header(vec!["path", "description"]);
- let listing = git::list()?;
- for meta in listing {
- table.add_row(vec![meta.path.display().to_string(), meta.description]);
+ if !verbose {
+ table.set_header(vec!["path", "description"]);
+ let listing = git::list()?;
+ for meta in listing {
+ table.add_row(vec![meta.path.display().to_string(), meta.description]);
+ }
+ } else {
+ table.set_header(vec!["path", "description", "size"]);
+ let listing = git::list_verbose()?;
+ for meta in listing {
+ table.add_row(vec![
+ meta.path.display().to_string(),
+ meta.description,
+ format_size(meta.size, BINARY),
+ ]);
+ }
}
println!("{table}");
diff --git a/src/parser.rs b/src/parser.rs
index 30eb1e0..b429572 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -11,7 +11,7 @@ pub enum ShackleCommand {
/// Create a new repository
Init(InitArgs),
/// List all repositories available
- List,
+ List(ListArgs),
/// Sets the description of a repository, as shown in the CLI listing and web interfaces
SetDescription(SetDescriptionArgs),
/// Sets the main branch of the repository
@@ -42,6 +42,13 @@ pub struct InitArgs {
}
#[derive(Parser, Clone, Debug, PartialEq, Eq)]
+pub struct ListArgs {
+ /// List extra metadata, like the repo's size on disk
+ #[arg(short, long)]
+ pub verbose: bool,
+}
+
+#[derive(Parser, Clone, Debug, PartialEq, Eq)]
pub struct SetDescriptionArgs {
/// The full relative path of the repository, for example git/shuckie/repo.git
#[arg(value_parser = RelativePathParser)]