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`.
This commit is contained in:
elipeter 2025-06-23 19:37:19 +02:00
parent 47d850843c
commit 17d327a572
6 changed files with 196 additions and 45 deletions

134
Cargo.lock generated
View file

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

View file

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

View file

@ -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<dyn std::error::Error>> {
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);
}

View file

@ -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<Local> = meta.modified()?.into();
println!(" {:14} {}", style("Size"), size);
println!(" {:14} {}", style("Modified"), mtime.format("%Y-%m-%d %H:%M:%S"));
}
exit(0);
}
}
Ok(())

View file

@ -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<dyn std::error::Error>> {
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<Local> = 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);
}

View file

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