From 17d327a572ba30828508b67fc7aad539faa7db6e Mon Sep 17 00:00:00 2001 From: elipeter Date: Mon, 23 Jun 2025 19:37:19 +0200 Subject: [PATCH] Add `bytesize` and `chrono`, improve console output formatting - Added `bytesize` and `chrono` dependencies in `Cargo.toml` and `Cargo.lock` for enhanced size and time formatting. - Enhanced console output in `list.rs`, `index.rs`, `clean.rs`, and `config.rs` with improved styles for readability. - Updated file size and modified time formatting across commands using `ByteSize` and `chrono`. --- Cargo.lock | 134 +++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 +- src/commands/clean.rs | 15 ++--- src/commands/index.rs | 25 +++++--- src/commands/list.rs | 52 ++++++++-------- src/utils/config.rs | 12 +++- 6 files changed, 196 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04fe52e6..7f93f480 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.19" @@ -114,6 +129,12 @@ version = "3.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" +[[package]] +name = "bytesize" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3c8f83209414aacf0eeae3cf730b18d6981697fba62f200fcfb92b9f082acba" + [[package]] name = "cc" version = "1.2.27" @@ -129,6 +150,18 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-link", +] + [[package]] name = "clap" version = "4.5.40" @@ -194,6 +227,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -360,6 +399,30 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "ignore" version = "0.4.23" @@ -487,6 +550,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.17.0" @@ -502,6 +574,8 @@ name = "nyx" version = "0.1.0" dependencies = [ "blake3", + "bytesize", + "chrono", "clap", "console", "crossbeam-channel", @@ -514,7 +588,6 @@ dependencies = [ "rayon", "rusqlite", "serde", - "thiserror", "toml", "tracing", "tracing-subscriber", @@ -1341,6 +1414,65 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.59.0" diff --git a/Cargo.toml b/Cargo.toml index 5c258dda..79222ea2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,4 +30,5 @@ console = "0.15.11" rayon = "1.10.0" r2d2_sqlite = "0.30.0" r2d2 = "0.8.10" -thiserror = "2.0.12" +bytesize = "2.0.1" +chrono = { version = "0.4.41", default-features = false, features = ["std", "clock"] } diff --git a/src/commands/clean.rs b/src/commands/clean.rs index 67892980..d9b7cb9d 100644 --- a/src/commands/clean.rs +++ b/src/commands/clean.rs @@ -1,4 +1,5 @@ use std::{env, fs}; +use console::style; use crate::utils::get_project_info; pub fn handle( @@ -7,19 +8,19 @@ pub fn handle( config_dir: &std::path::Path, ) -> Result<(), Box> { if all { - println!("Cleaning all indexes..."); + println!("{}", style("Cleaning all indexes...").cyan().bold()); if config_dir.exists() { fs::remove_dir_all(config_dir)?; fs::create_dir_all(config_dir)?; } - println!("All indexes cleaned."); + println!("{}", style("✔ All indexes cleaned").green().bold()); } else if let Some(proj_name) = project { let db_path = config_dir.join(format!("{}.sqlite", proj_name)); if db_path.exists() { fs::remove_file(&db_path)?; - println!("Cleaned index for: {}", proj_name); + println!("{} {}", style("✔ Cleaned index for").green(), style(&proj_name).white().bold()); } else { - println!("No index found for: {}", proj_name); + println!("{} {}", style("✖ No index found for").red(), style(&proj_name).white().bold()); } } else { let current_dir = env::current_dir()?; @@ -27,11 +28,11 @@ pub fn handle( if db_path.exists() { fs::remove_file(&db_path)?; - println!("Cleaned index for: {}", project_name); + println!("{} {}", style("✔ Cleaned index for").green(), style(&project_name).white().bold()); } else { - println!("No index found for current project: {}", project_name); + println!("{} {}", style("✖ No index found for current project").red(), style(&project_name).white().bold()); } } - Ok(()) + std::process::exit(0); } \ No newline at end of file diff --git a/src/commands/index.rs b/src/commands/index.rs index bc9142f3..01232837 100644 --- a/src/commands/index.rs +++ b/src/commands/index.rs @@ -1,4 +1,8 @@ use std::fs; +use std::process::exit; +use bytesize::ByteSize; +use chrono::{DateTime, Local}; +use console::style; use crate::cli::IndexAction; use crate::database::index::{Indexer, IssueRow}; use crate::patterns::Severity; @@ -19,24 +23,29 @@ pub fn handle( if force || !db_path.exists() { build_index(&project_name, &build_path, &db_path, config)?; - println!("Index built: {}", db_path.display()); + println!("{} {} {}", "✔", style("Index built:" ).green(), style(db_path.display()).white().bold()); } else { - println!("Index already exists. Use --force to rebuild."); + println!("{} {}", style("↩ Index already exists").yellow(), style("(use --force to rebuild)").dim()); } } IndexAction::Status { path } => { let status_path = std::path::Path::new(&path).canonicalize()?; let (project_name, db_path) = get_project_info(&status_path, database_dir)?; - println!("Project: {}", project_name); - println!("Index path: {}", db_path.display()); - println!("Index exists: {}", db_path.exists()); + println!("{}", style("Project status").blue().bold().underlined()); + println!(" {:14} {}", style("Project"), style(&project_name).white().bold()); + println!(" {:14} {}", style("Index path"), style(db_path.display()).underlined()); + println!(" {:14} {}", style("Exists"), style(db_path.exists()).bold()); if db_path.exists() { - let metadata = fs::metadata(&db_path)?; - println!("Index size: {} bytes", metadata.len()); - println!("Last modified: {:?}", metadata.modified()?); + let meta = fs::metadata(&db_path)?; + let size = ByteSize::b(meta.len()); + let mtime: DateTime = meta.modified()?.into(); + println!(" {:14} {}", style("Size"), size); + println!(" {:14} {}", style("Modified"), mtime.format("%Y-%m-%d %H:%M:%S")); } + + exit(0); } } Ok(()) diff --git a/src/commands/list.rs b/src/commands/list.rs index 4b9200ab..e3d58ceb 100644 --- a/src/commands/list.rs +++ b/src/commands/list.rs @@ -1,35 +1,37 @@ use std::fs; +use bytesize::ByteSize; +use chrono::{DateTime, Local}; +use console::style; pub fn handle( verbose: bool, database_dir: &std::path::Path, ) -> Result<(), Box> { - println!("Indexed projects:"); + println!("{}", style("Indexed projects").blue().bold().underlined()); - if database_dir.exists() { - for entry in fs::read_dir(database_dir)? { - let entry = entry?; - let path = entry.path(); - - if path.extension().and_then(|s| s.to_str()) == Some("sqlite") { - let project_name = path - .file_stem() - .and_then(|s| s.to_str()) - .unwrap_or("unknown"); - - println!(" {}", project_name); - - if verbose { - let metadata = fs::metadata(&path)?; - println!(" Path: {}", path.display()); - println!(" Size: {} bytes", metadata.len()); - println!(" Modified: {:?}", metadata.modified()?); - } - } - } - } else { - println!(" No indexed projects found."); + if !database_dir.exists() { + println!(" {}", style("∅ No indexed projects found").dim()); + std::process::exit(0); } - Ok(()) + for entry in fs::read_dir(database_dir)? { + let path = entry?.path(); + if path.extension().and_then(|s| s.to_str()) != Some("sqlite") { + continue; + } + + let name = path.file_stem().and_then(|s| s.to_str()).unwrap_or("unknown"); + println!(" {}", style(name).white().bold()); + + if verbose { + let meta = fs::metadata(&path)?; + let size = ByteSize::b(meta.len()); + let mtime: DateTime = meta.modified()?.into(); + println!(" {:10} {}", style("Path"), style(path.display()).underlined()); + println!(" {:10} {}", style("Size"), size); + println!(" {:10} {}", style("Modified"), mtime.format("%Y-%m-%d %H:%M:%S")); + } + } + + std::process::exit(0); } \ No newline at end of file diff --git a/src/utils/config.rs b/src/utils/config.rs index 2418d3c2..9f864f7c 100644 --- a/src/utils/config.rs +++ b/src/utils/config.rs @@ -1,6 +1,7 @@ use serde::{Deserialize, Serialize}; use std::path::{Path}; use std::fs; +use console::style; use toml; use crate::patterns::Severity; @@ -187,10 +188,15 @@ impl Config { let user_config: Config = toml::from_str(&user_config_content)?; config = merge_configs(config, user_config); - - println!("Loaded user config from: {}", user_config_path.display()); + + println!("{}: Loaded user config from: {}\n", + style("note").green().bold(), + style(user_config_path.display()).underlined().white().bold()); } else { - println!("Using default configuration. Create {} to customize.", user_config_path.display()); + println!("{}: Using {} configuration.\n Create file in '{}'to customize.\n", + style("note").green().bold(), + style("default").bold(), + style(user_config_path.display()).underlined().white().bold()); } Ok(config)