diff options
-rw-r--r-- | Cargo.lock | 108 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/activate.rs | 16 | ||||
-rw-r--r-- | src/main.rs | 25 | ||||
-rw-r--r-- | src/utils/deploy.rs | 20 | ||||
-rw-r--r-- | src/utils/mod.rs | 95 |
6 files changed, 206 insertions, 60 deletions
@@ -66,6 +66,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi 0.3.9", +] + +[[package]] name = "clap" version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -123,12 +136,12 @@ name = "deploy-rs" version = "0.1.0" dependencies = [ "clap", + "flexi_logger", "fork", "futures-util", "log", "merge", "notify", - "pretty_env_logger", "rnix", "serde", "serde_derive", @@ -142,19 +155,6 @@ dependencies = [ ] [[package]] -name = "env_logger" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[package]] name = "filetime" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -167,6 +167,22 @@ dependencies = [ ] [[package]] +name = "flexi_logger" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c37586928c27a25ff5fce49ff3f8e071b3beeef48b4f004fe7d40d75a26e3db5" +dependencies = [ + "atty", + "chrono", + "glob", + "lazy_static", + "log", + "regex", + "thiserror", + "yansi", +] + +[[package]] name = "fork" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -254,6 +270,12 @@ dependencies = [ ] [[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] name = "hashbrown" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -278,15 +300,6 @@ dependencies = [ ] [[package]] -name = "humantime" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", -] - -[[package]] name = "indexmap" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -527,6 +540,16 @@ dependencies = [ ] [[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] name = "num-traits" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -615,16 +638,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "pretty_env_logger" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" -dependencies = [ - "env_logger", - "log", -] - -[[package]] name = "proc-macro-error" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -670,12 +683,6 @@ dependencies = [ ] [[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] name = "quote" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -901,6 +908,17 @@ dependencies = [ ] [[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi", + "winapi 0.3.9", +] + +[[package]] name = "tokio" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -984,6 +1002,12 @@ dependencies = [ ] [[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] name = "whoami" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1043,6 +1067,12 @@ dependencies = [ ] [[package]] +name = "yansi" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" + +[[package]] name = "yn" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -19,7 +19,7 @@ serde = "1.0.104" merge = "0.1.0" whoami = "0.9.0" log = "0.4" -pretty_env_logger = "0.4" +flexi_logger = "0.16" notify = "5.0.0-pre.3" futures-util = "0.3.6" fork = "0.1" diff --git a/src/activate.rs b/src/activate.rs index 84d4b12..b982d72 100644 --- a/src/activate.rs +++ b/src/activate.rs @@ -18,7 +18,6 @@ use notify::{RecommendedWatcher, RecursiveMode, Watcher}; use thiserror::Error; -extern crate pretty_env_logger; #[macro_use] extern crate log; @@ -35,6 +34,13 @@ struct Opts { profile_path: String, closure: String, + /// Print debug logs to output + #[clap(short, long)] + debug_logs: bool, + /// File to print logs to (including the background activation process) + #[clap(long)] + log_dir: Option<String>, + /// Temp path for any temporary files that may be needed during activation #[clap(long)] temp_path: String, @@ -347,14 +353,10 @@ pub async fn activate( #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { - if std::env::var("DEPLOY_LOG").is_err() { - std::env::set_var("DEPLOY_LOG", "info"); - } - - pretty_env_logger::init_custom_env("DEPLOY_LOG"); - let opts: Opts = Opts::parse(); + utils::init_logger(opts.debug_logs, opts.log_dir.as_deref(), true)?; + match activate( opts.profile_path, opts.closure, diff --git a/src/main.rs b/src/main.rs index be7ad40..c003da7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,8 +12,6 @@ use tokio::process::Command; use thiserror::Error; -extern crate pretty_env_logger; - #[macro_use] extern crate log; @@ -39,6 +37,13 @@ struct Opts { /// Extra arguments to be passed to nix build extra_build_args: Vec<String>, + /// Print debug logs to output + #[clap(short, long)] + debug_logs: bool, + /// Directory to print logs to (including the background activation process) + #[clap(long)] + log_dir: Option<String>, + /// Keep the build outputs of each built profile #[clap(short, long)] keep_result: bool, @@ -336,6 +341,8 @@ async fn run_deploy( keep_result: bool, result_path: Option<&str>, extra_build_args: &[String], + debug_logs: bool, + log_dir: Option<String>, ) -> Result<(), RunDeployError> { let to_deploy: Vec<((&str, &utils::data::Node), (&str, &utils::data::Profile))> = match (&deploy_flake.node, &deploy_flake.profile) { @@ -432,6 +439,8 @@ async fn run_deploy( profile, profile_name, &cmd_overrides, + debug_logs, + log_dir.as_deref(), ); let deploy_defs = deploy_data.defs()?; @@ -480,19 +489,17 @@ enum RunError { GetDeploymentDataError(#[from] GetDeploymentDataError), #[error("Error parsing flake: {0}")] ParseFlakeError(#[from] utils::ParseFlakeError), + #[error("Error initiating logger: {0}")] + LoggerError(#[from] flexi_logger::FlexiLoggerError), #[error("{0}")] RunDeployError(#[from] RunDeployError), } async fn run() -> Result<(), RunError> { - if std::env::var("DEPLOY_LOG").is_err() { - std::env::set_var("DEPLOY_LOG", "info"); - } - - pretty_env_logger::init_custom_env("DEPLOY_LOG"); - let opts: Opts = Opts::parse(); + utils::init_logger(opts.debug_logs, opts.log_dir.as_deref(), false)?; + let deploy_flake = utils::parse_flake(opts.flake.as_str())?; let cmd_overrides = utils::CmdOverrides { @@ -534,6 +541,8 @@ async fn run() -> Result<(), RunError> { opts.keep_result, result_path, &opts.extra_build_args, + opts.debug_logs, + opts.log_dir, ) .await?; diff --git a/src/utils/deploy.rs b/src/utils/deploy.rs index 14a44a0..3aced6c 100644 --- a/src/utils/deploy.rs +++ b/src/utils/deploy.rs @@ -16,6 +16,8 @@ fn build_activate_command( temp_path: &Cow<str>, confirm_timeout: u16, magic_rollback: bool, + debug_logs: bool, + log_dir: Option<&str>, ) -> String { let mut self_activate_command = format!( "{}/activate-rs '{}' '{}' --temp-path {} --confirm-timeout {}", @@ -30,6 +32,14 @@ fn build_activate_command( self_activate_command = format!("{} --auto-rollback", self_activate_command); } + if debug_logs { + self_activate_command = format!("{} --debug-logs", self_activate_command); + } + + if let Some(log_dir) = log_dir { + self_activate_command = format!("{} --log-file {}", self_activate_command, log_dir); + } + if let Some(sudo_cmd) = &sudo { self_activate_command = format!("{} {}", sudo_cmd, self_activate_command); } @@ -47,6 +57,8 @@ fn test_activation_command_builder() { let temp_path = &"/tmp".into(); let confirm_timeout = 30; let magic_rollback = true; + let debug_logs = true; + let log_dir = Some("/tmp/something.txt"); assert_eq!( build_activate_command( @@ -56,9 +68,11 @@ fn test_activation_command_builder() { auto_rollback, temp_path, confirm_timeout, - magic_rollback + magic_rollback, + debug_logs, + log_dir ), - "sudo -u test /nix/store/blah/etc/activate-rs '/blah/profiles/test' '/nix/store/blah/etc' --temp-path /tmp --confirm-timeout 30 --magic-rollback --auto-rollback" + "sudo -u test /nix/store/blah/etc/activate-rs '/blah/profiles/test' '/nix/store/blah/etc' --temp-path /tmp --confirm-timeout 30 --magic-rollback --auto-rollback --debug-logs --log-file /tmp/something.txt" .to_string(), ); } @@ -107,6 +121,8 @@ pub async fn deploy_profile( &temp_path, confirm_timeout, magic_rollback, + deploy_data.debug_logs, + deploy_data.log_dir, ); debug!("Constructed activation command: {}", self_activate_command); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 5770f98..42c81f7 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -3,14 +3,14 @@ // // SPDX-License-Identifier: MPL-2.0 -use rnix::{types::*, NodeOrToken, SyntaxKind::*, SyntaxNode}; - -use std::path::PathBuf; +use rnix::{types::*, SyntaxKind::*}; use merge::Merge; use thiserror::Error; +use flexi_logger::*; + #[macro_export] macro_rules! good_panic { ($($tts:tt)*) => {{ @@ -19,6 +19,87 @@ macro_rules! good_panic { }} } +pub fn logger_formatter_activate( + w: &mut dyn std::io::Write, + _now: &mut DeferredNow, + record: &Record, +) -> Result<(), std::io::Error> { + let level = record.level(); + + write!( + w, + "⭐ REMOTE ⭐ {0} {1} {0} {2}", + match level { + log::Level::Error => "❌", + log::Level::Warn => "⚠️", + log::Level::Info => "ℹ️", + log::Level::Debug => "❓", + log::Level::Trace => "🖊️", + }, + style(level, level.to_string()), + record.args() + ) +} + +pub fn logger_formatter_deploy( + w: &mut dyn std::io::Write, + _now: &mut DeferredNow, + record: &Record, +) -> Result<(), std::io::Error> { + let level = record.level(); + + write!( + w, + "🚀 {0} {1} {0} {2}", + match level { + log::Level::Error => "❌", + log::Level::Warn => "⚠️", + log::Level::Info => "ℹ️", + log::Level::Debug => "❓", + log::Level::Trace => "🖊️", + }, + style(level, level.to_string()), + record.args() + ) +} + +pub fn init_logger( + debug_logs: bool, + log_dir: Option<&str>, + activate: bool, +) -> Result<(), FlexiLoggerError> { + let logger_formatter = match activate { + true => logger_formatter_activate, + false => logger_formatter_deploy, + }; + + if let Some(log_dir) = log_dir { + Logger::with_env_or_str("debug") + .log_to_file() + .format_for_stderr(logger_formatter) + .set_palette("196;208;51;7;8".to_string()) + .directory(log_dir) + .discriminant(if activate { "activate" } else { "deploy" }) + .duplicate_to_stderr(match debug_logs { + true => Duplicate::Debug, + false => Duplicate::Info, + }) + .print_message() + .start()?; + } else { + Logger::with_env_or_str(match debug_logs { + true => "debug", + false => "info", + }) + .log_target(LogTarget::StdErr) + .format(logger_formatter_deploy) + .set_palette("196;208;51;7;8".to_string()) + .start()?; + } + + Ok(()) +} + pub mod data; pub mod deploy; pub mod push; @@ -191,6 +272,9 @@ pub struct DeployData<'a> { pub cmd_overrides: &'a CmdOverrides, pub merged_settings: data::GenericSettings, + + pub debug_logs: bool, + pub log_dir: Option<&'a str>, } #[derive(Debug)] @@ -259,6 +343,8 @@ pub fn make_deploy_data<'a, 's>( profile: &'a data::Profile, profile_name: &'a str, cmd_overrides: &'a CmdOverrides, + debug_logs: bool, + log_dir: Option<&'a str>, ) -> DeployData<'a> { let mut merged_settings = top_settings.clone(); merged_settings.merge(node.generic_settings.clone()); @@ -292,6 +378,9 @@ pub fn make_deploy_data<'a, 's>( cmd_overrides, merged_settings, + + debug_logs, + log_dir, } } |