logging via tracing

This commit is contained in:
raf 2025-07-22 01:21:42 +03:00
commit 9bd20270ba
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
7 changed files with 233 additions and 28 deletions

164
Cargo.lock generated
View file

@ -61,6 +61,12 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "cfg-if"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]]
name = "clap"
version = "4.5.41"
@ -113,6 +119,9 @@ version = "0.1.0"
dependencies = [
"clap",
"regex",
"tracing",
"tracing-subscriber",
"yansi",
]
[[package]]
@ -127,18 +136,58 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[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.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "proc-macro2"
version = "1.0.95"
@ -186,6 +235,21 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[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 = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "strsim"
version = "0.11.1"
@ -203,6 +267,72 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "thread_local"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [
"cfg-if",
]
[[package]]
name = "tracing"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
dependencies = [
"once_cell",
"valuable",
]
[[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.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
dependencies = [
"nu-ansi-term",
"sharded-slab",
"smallvec",
"thread_local",
"tracing-core",
"tracing-log",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
@ -215,6 +345,34 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.59.0"
@ -294,3 +452,9 @@ version = "0.1.0"
dependencies = [
"clap",
]
[[package]]
name = "yansi"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"

View file

@ -1,9 +1,9 @@
[workspace]
members = ["eh", "xtask"]
members = [ "eh", "xtask" ]
resolver = "3"
[workspace.package]
authors = [ "NotAShelf <raf@notashelf.dev>"]
authors = [ "NotAShelf <raf@notashelf.dev>" ]
description = "Ergonomic Nix CLI helper"
edition = "2024"
license = "MPL-2.0"
@ -12,5 +12,8 @@ rust-version = "1.85"
version = "0.1.0"
[workspace.dependencies]
clap = { version = "4.5", features = ["derive"] }
regex = "1.0"
clap = { features = [ "derive" ], version = "4.5" }
regex = "1.0"
tracing = "0.1"
tracing-subscriber = "0.3"
yansi = "1.0"

View file

@ -7,5 +7,8 @@ authors.workspace = true
rust-version.workspace = true
[dependencies]
clap.workspace = true
regex.workspace = true
clap.workspace = true
regex.workspace = true
tracing.workspace = true
tracing-subscriber.workspace = true
yansi.workspace = true

View file

@ -1,6 +1,8 @@
use crate::command::{NixCommand, StdIoInterceptor};
use crate::util::{HashExtractor, NixErrorClassifier, NixFileFixer};
use std::io::Write;
use tracing::{info, warn};
use yansi::Paint;
pub fn handle_nix_build(
args: &[String],
@ -28,7 +30,7 @@ pub fn handle_nix_build(
if let Some(new_hash) = hash_extractor.extract_hash(&stderr) {
if fixer.fix_hash_in_files(&new_hash) {
eprintln!("\x1b[32m✔ Fixed hash mismatch, retrying...\x1b[0m");
info!("{}", Paint::green("✔ Fixed hash mismatch, retrying..."));
let retry_status = NixCommand::new("build")
.print_build_logs(true)
.args(args.iter().cloned())
@ -40,8 +42,9 @@ pub fn handle_nix_build(
if classifier.should_retry(&stderr) {
if stderr.contains("unfree") {
eprintln!(
"\x1b[33m⚠ Unfree package detected, retrying with NIXPKGS_ALLOW_UNFREE=1...\x1b[0m"
warn!(
"{}",
Paint::yellow("⚠ Unfree package detected, retrying with NIXPKGS_ALLOW_UNFREE=1...")
);
let retry_status = NixCommand::new("build")
.print_build_logs(true)
@ -53,8 +56,11 @@ pub fn handle_nix_build(
std::process::exit(retry_status.code().unwrap_or(1));
}
if stderr.contains("insecure") {
eprintln!(
"\x1b[33m⚠ Insecure package detected, retrying with NIXPKGS_ALLOW_INSECURE=1...\x1b[0m"
warn!(
"{}",
Paint::yellow(
"⚠ Insecure package detected, retrying with NIXPKGS_ALLOW_INSECURE=1..."
)
);
let retry_status = NixCommand::new("build")
.print_build_logs(true)
@ -66,8 +72,9 @@ pub fn handle_nix_build(
std::process::exit(retry_status.code().unwrap_or(1));
}
if stderr.contains("broken") {
eprintln!(
"\x1b[33m⚠ Broken package detected, retrying with NIXPKGS_ALLOW_BROKEN=1...\x1b[0m"
warn!(
"{}",
Paint::yellow("⚠ Broken package detected, retrying with NIXPKGS_ALLOW_BROKEN=1...")
);
let retry_status = NixCommand::new("build")
.print_build_logs(true)

View file

@ -36,6 +36,14 @@ enum Command {
}
fn main() {
let format = tracing_subscriber::fmt::format()
.with_level(true) // don't include levels in formatted output
.with_target(true) // don't include targets
.with_thread_ids(false) // include the thread ID of the current thread
.with_thread_names(false) // include the name of the current thread
.compact(); // use the `Compact` formatting style.
tracing_subscriber::fmt().event_format(format).init();
let mut args = env::args();
let bin = args.next().unwrap_or_else(|| "eh".to_string());
let app_name = Path::new(&bin)
@ -43,6 +51,7 @@ fn main() {
.and_then(|name| name.to_str())
.unwrap_or("eh");
// If invoked as nr/ns/nb, dispatch directly and exit
match app_name {
"nr" => {
let rest: Vec<String> = args.collect();
@ -52,6 +61,7 @@ fn main() {
run::handle_nix_run(&rest, &hash_extractor, &fixer, &classifier);
return;
}
"ns" => {
let rest: Vec<String> = args.collect();
let hash_extractor = util::RegexHashExtractor;
@ -60,6 +70,7 @@ fn main() {
shell::handle_nix_shell(&rest, &hash_extractor, &fixer, &classifier);
return;
}
"nb" => {
let rest: Vec<String> = args.collect();
let hash_extractor = util::RegexHashExtractor;
@ -81,13 +92,16 @@ fn main() {
Some(Command::Run { args }) => {
run::handle_nix_run(&args, &hash_extractor, &fixer, &classifier);
}
Some(Command::Shell { args }) => {
shell::handle_nix_shell(&args, &hash_extractor, &fixer, &classifier);
}
Some(Command::Build { args }) => {
build::handle_nix_build(&args, &hash_extractor, &fixer, &classifier);
}
None => {
_ => {
Cli::command().print_help().unwrap();
println!();
std::process::exit(0);

View file

@ -1,6 +1,8 @@
use crate::command::{NixCommand, StdIoInterceptor};
use crate::util::{HashExtractor, NixErrorClassifier, NixFileFixer};
use std::io::Write;
use tracing::{info, warn};
use yansi::Paint;
pub fn handle_nix_run(
args: &[String],
@ -28,7 +30,7 @@ pub fn handle_nix_run(
if let Some(new_hash) = hash_extractor.extract_hash(&stderr) {
if fixer.fix_hash_in_files(&new_hash) {
eprintln!("\x1b[32m✔ Fixed hash mismatch, retrying...\x1b[0m");
info!("{}", Paint::green("✔ Fixed hash mismatch, retrying..."));
let retry_status = NixCommand::new("run")
.print_build_logs(true)
.args(args.iter().cloned())
@ -40,8 +42,9 @@ pub fn handle_nix_run(
if classifier.should_retry(&stderr) {
if stderr.contains("unfree") {
eprintln!(
"\x1b[33m⚠ Unfree package detected, retrying with NIXPKGS_ALLOW_UNFREE=1...\x1b[0m"
warn!(
"{}",
Paint::yellow("⚠ Unfree package detected, retrying with NIXPKGS_ALLOW_UNFREE=1...")
);
let retry_status = NixCommand::new("run")
.print_build_logs(true)
@ -53,8 +56,11 @@ pub fn handle_nix_run(
std::process::exit(retry_status.code().unwrap_or(1));
}
if stderr.contains("insecure") {
eprintln!(
"\x1b[33m⚠ Insecure package detected, retrying with NIXPKGS_ALLOW_INSECURE=1...\x1b[0m"
warn!(
"{}",
Paint::yellow(
"⚠ Insecure package detected, retrying with NIXPKGS_ALLOW_INSECURE=1..."
)
);
let retry_status = NixCommand::new("run")
.print_build_logs(true)
@ -66,8 +72,9 @@ pub fn handle_nix_run(
std::process::exit(retry_status.code().unwrap_or(1));
}
if stderr.contains("broken") {
eprintln!(
"\x1b[33m⚠ Broken package detected, retrying with NIXPKGS_ALLOW_BROKEN=1...\x1b[0m"
warn!(
"{}",
Paint::yellow("⚠ Broken package detected, retrying with NIXPKGS_ALLOW_BROKEN=1...")
);
let retry_status = NixCommand::new("run")
.print_build_logs(true)

View file

@ -1,6 +1,8 @@
use crate::command::{NixCommand, StdIoInterceptor};
use crate::util::{HashExtractor, NixErrorClassifier, NixFileFixer};
use std::io::Write;
use tracing::{info, warn};
use yansi::Paint;
pub fn handle_nix_shell(
args: &[String],
@ -28,7 +30,7 @@ pub fn handle_nix_shell(
if let Some(new_hash) = hash_extractor.extract_hash(&stderr) {
if fixer.fix_hash_in_files(&new_hash) {
eprintln!("\x1b[32m✔ Fixed hash mismatch, retrying...\x1b[0m");
info!("{}", Paint::green("✔ Fixed hash mismatch, retrying..."));
let retry_status = NixCommand::new("shell")
.print_build_logs(true)
.args(args.iter().cloned())
@ -40,8 +42,9 @@ pub fn handle_nix_shell(
if classifier.should_retry(&stderr) {
if stderr.contains("unfree") {
eprintln!(
"\x1b[33m⚠ Unfree package detected, retrying with NIXPKGS_ALLOW_UNFREE=1...\x1b[0m"
warn!(
"{}",
Paint::yellow("⚠ Unfree package detected, retrying with NIXPKGS_ALLOW_UNFREE=1...")
);
let retry_status = NixCommand::new("shell")
.print_build_logs(true)
@ -53,8 +56,11 @@ pub fn handle_nix_shell(
std::process::exit(retry_status.code().unwrap_or(1));
}
if stderr.contains("insecure") {
eprintln!(
"\x1b[33m⚠ Insecure package detected, retrying with NIXPKGS_ALLOW_INSECURE=1...\x1b[0m"
warn!(
"{}",
Paint::yellow(
"⚠ Insecure package detected, retrying with NIXPKGS_ALLOW_INSECURE=1..."
)
);
let retry_status = NixCommand::new("shell")
.print_build_logs(true)
@ -66,8 +72,9 @@ pub fn handle_nix_shell(
std::process::exit(retry_status.code().unwrap_or(1));
}
if stderr.contains("broken") {
eprintln!(
"\x1b[33m⚠ Broken package detected, retrying with NIXPKGS_ALLOW_BROKEN=1...\x1b[0m"
warn!(
"{}",
Paint::yellow("⚠ Broken package detected, retrying with NIXPKGS_ALLOW_BROKEN=1...")
);
let retry_status = NixCommand::new("shell")
.print_build_logs(true)