diff --git a/Cargo.lock b/Cargo.lock index b973e3d..b9c7571 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "arrayref" version = "0.3.7" @@ -20,6 +35,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -61,9 +91,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cached-nix-shell" @@ -71,7 +101,9 @@ version = "0.1.5" dependencies = [ "blake3", "bytelines", + "env_logger", "itertools", + "log", "nix", "once_cell", "serde_json", @@ -126,6 +158,15 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "env_logger" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +dependencies = [ + "log", +] + [[package]] name = "errno" version = "0.3.1" @@ -158,9 +199,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -173,9 +214,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -183,15 +224,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -200,15 +241,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", @@ -217,21 +258,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -255,6 +296,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "hermit-abi" version = "0.3.1" @@ -307,9 +354,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "libc" -version = "0.2.144" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "linux-raw-sys" @@ -317,6 +364,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + [[package]] name = "memchr" version = "2.5.0" @@ -332,6 +385,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "nix" version = "0.26.2" @@ -346,6 +408,15 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.17.1" @@ -354,9 +425,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -366,18 +437,18 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.58" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.27" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -391,6 +462,12 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustix" version = "0.37.19" @@ -430,9 +507,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -451,9 +528,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.16" +version = "2.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8" dependencies = [ "proc-macro2", "quote", @@ -475,14 +552,13 @@ dependencies = [ [[package]] name = "tokio" -version = "1.28.1" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ - "autocfg", + "backtrace", "bytes", "pin-project-lite", - "windows-sys 0.48.0", ] [[package]] @@ -499,9 +575,9 @@ checksum = "b879826c277a7addb7b93bdd50d47c02710fe2845f4f07999887ca17fbc6b648" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "version_check" diff --git a/Cargo.toml b/Cargo.toml index 99a31fc..afb4a60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,9 @@ which = "4.4.0" [dependencies] blake3 = "1.3.3" bytelines = "2.4.0" +env_logger = { version = "0.10.1", default-features = false } itertools = "0.10.5" +log = "0.4.20" nix = "0.26.2" once_cell = "1.17.1" serde_json = "1.0.96" diff --git a/src/args.rs b/src/args.rs index 22d76b2..e3146ee 100644 --- a/src/args.rs +++ b/src/args.rs @@ -17,6 +17,7 @@ use std::os::unix::ffi::OsStrExt; use std::os::unix::process::CommandExt; use std::process::{exit, Command}; use ufcs::Pipe; +use log::info; pub enum RunMode { /// no arg @@ -196,7 +197,7 @@ fn is_alpha(b: u8) -> bool { } fn exit_version() { - println!( + info!( "cached-nix-shell v{}{}", env!("CARGO_PKG_VERSION"), option_env!("CNS_GIT_COMMIT") @@ -204,9 +205,9 @@ fn exit_version() { .unwrap_or("".into()) ); if env!("CNS_NIX").is_empty() { - println!("Using nix-shell from $PATH"); + info!("Using nix-shell from $PATH"); } else { - println!("Using {}nix-shell", env!("CNS_NIX")); + info!("Using {}nix-shell", env!("CNS_NIX")); } std::io::stdout().flush().unwrap(); Command::new(concat!(env!("CNS_NIX"), "nix-shell")) diff --git a/src/main.rs b/src/main.rs index f2952f8..43acc86 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,8 @@ use std::process::{exit, Command, Stdio}; use std::time::Instant; use tempfile::NamedTempFile; use ufcs::Pipe; +use log::{error, warn, info}; +use env_logger::{Builder, Env, Target}; mod args; mod bash; @@ -88,7 +90,7 @@ fn unwrap_or_errx(x: Result) -> T { match x { Ok(x) => x, Err(x) => { - eprintln!("cached-nix-shell: {x}"); + error!("{x}"); exit(1) } } @@ -250,7 +252,7 @@ fn run_nix_shell(inp: &NixShellInput) -> NixShellOutput { .status() .expect("failed to execute nix-shell"); if !status.success() { - eprintln!("cached-nix-shell: nix-shell: {status}"); + error!("nix-shell: {status}"); let code = status .code() .or_else(|| status.signal().map(|x| x + 127)) @@ -280,7 +282,7 @@ fn run_nix_shell(inp: &NixShellInput) -> NixShellOutput { .expect("Can't read trace file"); let trace = Trace::load(trace_data); if trace.check_for_changes() { - eprintln!("cached-nix-shell: some files are already updated, cache won't be reused"); + info!("some files are already updated, cache won't be reused"); } std::mem::drop(trace_file); @@ -305,8 +307,8 @@ fn run_nix_shell(inp: &NixShellInput) -> NixShellOutput { stderr.extend(exec.stderr); } if !exec.status.success() { - eprintln!( - "cached-nix-shell: failed to execute nix show-derivation" + error!( + "failed to execute nix show-derivation" ); let _ = std::io::stderr().write_all(&stderr); exit(1); @@ -335,7 +337,6 @@ fn run_script( let exec = if is_literal_bash_string(nix_shell_args.interpreter.as_bytes()) { - // eprintln!("Interpreter is a literal string, executing directly"); Command::new(nix_shell_args.interpreter) .arg(fname) .args(script_args) @@ -343,7 +344,6 @@ fn run_script( .envs(&env.env) .exec() } else { - // eprintln!("Interpreter is bash command, executing 'bash -c'"); let mut exec_string = OsString::new(); exec_string.push("exec "); exec_string.push(nix_shell_args.interpreter); @@ -359,7 +359,7 @@ fn run_script( .exec() }; - eprintln!("cached-nix-shell: couldn't run: {exec:?}"); + error!("couldn't run: {exec:?}"); exit(1); } @@ -441,7 +441,7 @@ fn run_from_args(args: Vec) { .env_clear() .envs(&env.env) .exec(); - eprintln!("cached-nix-shell: couldn't run: {exec:?}"); + error!("couldn't run: {exec:?}"); exit(1); } @@ -457,10 +457,10 @@ fn cached_shell_env(pure: bool, inp: &NixShellInput) -> EnvOptions { let mut env = if let Some(env) = check_cache(&inputs_hash) { env } else { - eprintln!("cached-nix-shell: updating cache"); + info!("updating cache"); let start = Instant::now(); let outp = run_nix_shell(inp); - eprintln!("cached-nix-shell: done in {:?}", start.elapsed()); + info!("done in {:?}", start.elapsed()); // TODO: use flock cache_write(&inputs_hash, "inputs", &inputs); @@ -586,7 +586,7 @@ fn cache_write(hash: &str, ext: &str, text: &[u8]) { }; match f() { Ok(_) => (), - Err(e) => eprintln!("Warning: can't store cache: {e}"), + Err(e) => warn!("can't store cache: {e}"), } } @@ -599,14 +599,14 @@ fn cache_symlink(hash: &str, ext: &str, target: &str) { }; match f() { Ok(_) => (), - Err(e) => eprintln!("Warning: can't symlink to cache: {e}"), + Err(e) => warn!("can't symlink to cache: {e}"), } } fn wrap(cmd: Vec) { if cmd.is_empty() { - eprintln!("cached-nix-shell: command not specified"); - eprintln!("usage: cached-nix-shell --wrap COMMAND ARGS..."); + error!("command not specified"); + error!("usage: cached-nix-shell --wrap COMMAND ARGS..."); exit(1); } @@ -616,8 +616,8 @@ fn wrap(cmd: Vec) { ) .is_err() { - eprintln!( - "cached-nix-shell: couldn't wrap, {}/nix-shell is not executable", + error!( + "couldn't wrap, {}/nix-shell is not executable", env!("CNS_WRAP_PATH") ); exit(1); @@ -634,13 +634,32 @@ fn wrap(cmd: Vec) { .args(&cmd[1..]) .env("PATH", OsStr::from_bytes(&new_path)) .exec(); - eprintln!("cached-nix-shell: couldn't run: {exec}"); + error!("couldn't run: {exec}"); exit(1); } +fn init_logger(target: Target) { + let env = Env::default() + .filter_or("CNS_LOG_LEVEL", "trace") + .write_style("CNS_LOG_STYLE"); + + Builder::from_env(env) + .format_level(false) + .target(target) + .init(); +} + fn main() { let argv: Vec = std::env::args_os().collect(); + // We need to print version into stdout, this is why the condition. + // A naive assumption: the version could be only the first and a single CLI argument. + init_logger(if argv.len() == 2 && argv[1] == "--version" { + Target::Stdout + } else { + Target::Stderr + }); + if argv.len() >= 2 && argv[1] == "--wrap" { wrap(std::env::args_os().skip(2).collect()); } diff --git a/src/trace.rs b/src/trace.rs index d804945..aa01a3b 100644 --- a/src/trace.rs +++ b/src/trace.rs @@ -4,6 +4,7 @@ use std::ffi::{OsStr, OsString}; use std::fs::{read, read_dir, read_link, symlink_metadata}; use std::io::ErrorKind; use std::os::unix::ffi::OsStrExt; +use log::info; /// Output of trace-nix.so, sorted and deduplicated. pub struct Trace { @@ -80,8 +81,8 @@ fn check_item_updated(k: &[u8], v: &[u8]) -> bool { }; if res.as_bytes() != v { - eprintln!( - "cached-nix-shell: {:?}: expected {:?}, got {:?}", + info!( + "{:?}: expected {:?}, got {:?}", fname, OsStr::from_bytes(v), res