diff --git a/Cargo.lock b/Cargo.lock index 193ca6f..40790b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "allocator-api2" version = "0.2.18" @@ -85,6 +94,27 @@ dependencies = [ "winapi", ] +[[package]] +name = "directories" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys", +] + [[package]] name = "either" version = "1.11.0" @@ -97,6 +127,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -146,9 +187,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" @@ -156,6 +197,16 @@ version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", +] + [[package]] name = "lock_api" version = "0.4.12" @@ -181,6 +232,21 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + [[package]] name = "mio" version = "0.8.11" @@ -193,12 +259,34 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.2" @@ -228,6 +316,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + [[package]] name = "proc-macro2" version = "1.0.81" @@ -274,6 +368,61 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + [[package]] name = "rustversion" version = "1.0.15" @@ -325,6 +474,15 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "signal-hook" version = "0.3.17" @@ -422,9 +580,115 @@ dependencies = [ "anyhow", "colored", "crossterm", + "directories", + "lazy_static", "ratatui", "serde", "serde_yaml", + "tracing", + "tracing-error", + "tracing-subscriber", +] + +[[package]] +name = "thiserror" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -451,6 +715,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 7dae75f..30239b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,11 @@ edition = "2021" anyhow = "1.0.79" colored = "2.1.0" crossterm = "0.27.0" +directories = "5.0.1" +lazy_static = "1.5.0" ratatui = "0.25.0" serde = "1.0.195" serde_yaml = "0.9.30" +tracing = "0.1.40" +tracing-error = "0.2.0" +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } diff --git a/src/main.rs b/src/main.rs index 5a0ef50..7b360a8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,8 +9,13 @@ use taskui::{ mod taskfile; mod taskui; +mod trace; fn main() -> Result<()> { + trace::initialize_logging()?; + + trace_dbg!("Starting taskui"); + let taskfile = taskfile::config::load()?; let cfg = Config::load(); diff --git a/src/taskfile/config.rs b/src/taskfile/config.rs index 15d71c7..131a0ea 100644 --- a/src/taskfile/config.rs +++ b/src/taskfile/config.rs @@ -1,18 +1,18 @@ -use anyhow::{bail, Result}; +use anyhow::{anyhow, bail, Result}; use serde_yaml::Value; use std::{ fs::{metadata, File}, path::PathBuf, }; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Task { pub name: String, pub body: String, pub internal: bool, } -#[derive(Clone)] +#[derive(Clone, Debug)] struct Include { name: String, path: String, @@ -57,7 +57,7 @@ fn find_supported_file() -> Result<&'static str> { match found { Some(file_name) => Ok(file_name), - None => bail!("no supported file found"), + None => Err(anyhow!("no supported file found")), } } @@ -73,15 +73,7 @@ fn handle_includes(includes: Vec, current_path: &str) -> Result = prefix_tasks(include_tasks.clone(), include.name.clone()); - let include_tasks: Vec = include_tasks - .into_iter() - .map(|task| Task { - name: task.name, - body: task.body, - internal: task.internal || include.internal, - }) - .collect(); - + let include_tasks: Vec = flag_internal_tasks(&include, include_tasks); tasks.extend(include_tasks); if let Some(sub_includes) = get_includes(&taskfile_yml)? { @@ -90,15 +82,15 @@ fn handle_includes(includes: Vec, current_path: &str) -> Result = prefix_tasks(sub_include_tasks.clone(), include.name.clone()); + let sub_include_tasks = flag_internal_tasks(&include, sub_include_tasks); tasks.extend(sub_include_tasks); } } Err(_) => { if include.optional { continue; - } else { - bail!("include not found: {}", include.path); } + bail!("include not found: {}", include.path); } } } @@ -108,6 +100,17 @@ fn handle_includes(includes: Vec, current_path: &str) -> Result) -> Vec { + tasks + .into_iter() + .map(|task| Task { + name: task.name, + body: task.body, + internal: task.internal || include.internal, + }) + .collect() +} + fn prefix_tasks(tasks: Vec, include_name: String) -> Vec { tasks .into_iter() diff --git a/src/trace.rs b/src/trace.rs new file mode 100644 index 0000000..410bcb4 --- /dev/null +++ b/src/trace.rs @@ -0,0 +1,78 @@ +use std::path::PathBuf; + +use anyhow::Result; +use directories::ProjectDirs; +use lazy_static::lazy_static; +use tracing_error::ErrorLayer; +use tracing_subscriber::{self, layer::SubscriberExt, util::SubscriberInitExt, Layer}; + +lazy_static! { + pub static ref PROJECT_NAME: String = env!("CARGO_CRATE_NAME").to_uppercase().to_string(); + pub static ref DATA_FOLDER: Option = + std::env::var(format!("{}_DATA", PROJECT_NAME.clone())) + .ok() + .map(PathBuf::from); + pub static ref LOG_ENV: String = format!("{}_LOGLEVEL", PROJECT_NAME.clone()); + pub static ref LOG_FILE: String = format!("{}.log", env!("CARGO_PKG_NAME")); +} + +fn project_directory() -> Option { + ProjectDirs::from("de", "thmshmm", env!("CARGO_PKG_NAME")) +} + +pub fn get_data_dir() -> PathBuf { + let directory = if let Some(s) = DATA_FOLDER.clone() { + s + } else if let Some(proj_dirs) = project_directory() { + proj_dirs.data_local_dir().to_path_buf() + } else { + PathBuf::from(".").join(".data") + }; + directory +} + +pub fn initialize_logging() -> Result<()> { + let directory = get_data_dir(); + std::fs::create_dir_all(directory.clone())?; + let log_path = directory.join(LOG_FILE.clone()); + let log_file = std::fs::File::create(log_path)?; + std::env::set_var( + "RUST_LOG", + std::env::var("RUST_LOG") + .or_else(|_| std::env::var(LOG_ENV.clone())) + .unwrap_or_else(|_| format!("{}=info", env!("CARGO_CRATE_NAME"))), + ); + let file_subscriber = tracing_subscriber::fmt::layer() + .with_file(true) + .with_line_number(true) + .with_writer(log_file) + .with_target(false) + .with_ansi(false) + .with_filter(tracing_subscriber::filter::EnvFilter::from_default_env()); + tracing_subscriber::registry() + .with(file_subscriber) + .with(ErrorLayer::default()) + .init(); + Ok(()) +} + +#[macro_export] +macro_rules! trace_dbg { + (target: $target:expr, level: $level:expr, $ex:expr) => {{ + match $ex { + value => { + tracing::event!(target: $target, $level, ?value, stringify!($ex)); + value + } + } + }}; + (level: $level:expr, $ex:expr) => { + trace_dbg!(target: module_path!(), level: $level, $ex) + }; + (target: $target:expr, $ex:expr) => { + trace_dbg!(target: $target, level: tracing::Level::DEBUG, $ex) + }; + ($ex:expr) => { + trace_dbg!(level: tracing::Level::DEBUG, $ex) + }; +}