feat(core): improve migration error logging
This commit is contained in:
parent
f984d22f0c
commit
b47279db63
|
@ -19,12 +19,20 @@
|
||||||
|
|
||||||
use std::{path::PathBuf, sync::Mutex};
|
use std::{path::PathBuf, sync::Mutex};
|
||||||
|
|
||||||
use crate::{exit_code::{MIGRATE_ALREADY_NEW_FORMAT, MIGRATE_CLEAN_FAILURE, MIGRATE_DIRTY_FAILURE, MIGRATE_LEGACY_INSTANCE_RUNNING, MIGRATE_SUCCESS, MIGRATE_UNEXPECTED_FAILURE, MIGRATE_USER_ABORTED}, lock::acquire_legacy_lock};
|
use crate::{
|
||||||
|
exit_code::{
|
||||||
|
MIGRATE_ALREADY_NEW_FORMAT, MIGRATE_CLEAN_FAILURE, MIGRATE_DIRTY_FAILURE,
|
||||||
|
MIGRATE_LEGACY_INSTANCE_RUNNING, MIGRATE_SUCCESS, MIGRATE_UNEXPECTED_FAILURE,
|
||||||
|
MIGRATE_USER_ABORTED,
|
||||||
|
},
|
||||||
|
lock::acquire_legacy_lock,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{CliModule, CliModuleArgs};
|
use super::{CliModule, CliModuleArgs};
|
||||||
use colored::*;
|
use colored::*;
|
||||||
use dialoguer::Confirm;
|
use dialoguer::Confirm;
|
||||||
use fs_extra::dir::CopyOptions;
|
use fs_extra::dir::CopyOptions;
|
||||||
|
use log::{error, info};
|
||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
@ -33,8 +41,11 @@ lazy_static! {
|
||||||
|
|
||||||
pub fn new() -> CliModule {
|
pub fn new() -> CliModule {
|
||||||
CliModule {
|
CliModule {
|
||||||
|
enable_logs: true,
|
||||||
|
disable_logs_terminal_output: true,
|
||||||
requires_paths: true,
|
requires_paths: true,
|
||||||
requires_config: true,
|
requires_config: true,
|
||||||
|
log_mode: super::LogMode::AppendOnly,
|
||||||
subcommand: "migrate".to_string(),
|
subcommand: "migrate".to_string(),
|
||||||
entry: migrate_main,
|
entry: migrate_main,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -45,19 +56,21 @@ fn migrate_main(args: CliModuleArgs) -> i32 {
|
||||||
let paths = args.paths.expect("missing paths argument");
|
let paths = args.paths.expect("missing paths argument");
|
||||||
let cli_args = args.cli_args.expect("missing cli_args");
|
let cli_args = args.cli_args.expect("missing cli_args");
|
||||||
|
|
||||||
|
info!("--- MIGRATION STARTED ---");
|
||||||
|
|
||||||
configure_custom_panic_hook();
|
configure_custom_panic_hook();
|
||||||
|
|
||||||
if !args.is_legacy_config {
|
if !args.is_legacy_config {
|
||||||
eprintln!("Can't migrate configurations, as the default directory [1] is already encoded with the new format");
|
error_print_and_log("Can't migrate configurations, as the default directory [1] is already encoded with the new format");
|
||||||
eprintln!("[1]: {:?}", paths.config);
|
error_print_and_log(&format!("[1]: {:?}", paths.config));
|
||||||
eprintln!("The migration tool is only meant to convert the espanso's legacy configuration format (prior to");
|
error_print_and_log("The migration tool is only meant to convert the espanso's legacy configuration format (prior to");
|
||||||
eprintln!("version 0.7.3) to the new one (since version 2.0)");
|
error_print_and_log("version 0.7.3) to the new one (since version 2.0)");
|
||||||
return MIGRATE_ALREADY_NEW_FORMAT;
|
return MIGRATE_ALREADY_NEW_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
let legacy_lock_file = acquire_legacy_lock(&paths.runtime);
|
let legacy_lock_file = acquire_legacy_lock(&paths.runtime);
|
||||||
if legacy_lock_file.is_none() {
|
if legacy_lock_file.is_none() {
|
||||||
eprintln!("An instance of legacy espanso is running, please terminate it, otherwise the migration can't be performed");
|
error_print_and_log("An instance of legacy espanso is running, please terminate it, otherwise the migration can't be performed");
|
||||||
return MIGRATE_LEGACY_INSTANCE_RUNNING;
|
return MIGRATE_LEGACY_INSTANCE_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +93,15 @@ fn migrate_main(args: CliModuleArgs) -> i32 {
|
||||||
println!(" the current content of the config directory.");
|
println!(" the current content of the config directory.");
|
||||||
println!("");
|
println!("");
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"backing up the configuration directory: '{}'",
|
||||||
|
paths.config.to_string_lossy()
|
||||||
|
);
|
||||||
|
info!(
|
||||||
|
" -> into this folder: '{}'",
|
||||||
|
target_backup_dir.to_string_lossy()
|
||||||
|
);
|
||||||
|
|
||||||
if !cli_args.is_present("noconfirm") {
|
if !cli_args.is_present("noconfirm") {
|
||||||
if !Confirm::new()
|
if !Confirm::new()
|
||||||
.with_prompt("Do you want to proceed?")
|
.with_prompt("Do you want to proceed?")
|
||||||
|
@ -104,15 +126,19 @@ fn migrate_main(args: CliModuleArgs) -> i32 {
|
||||||
)
|
)
|
||||||
.expect("unable to backup the current config");
|
.expect("unable to backup the current config");
|
||||||
println!("{}", "Backup completed!".green());
|
println!("{}", "Backup completed!".green());
|
||||||
|
info!("backup completed!");
|
||||||
|
|
||||||
println!("Converting the configuration...");
|
println!("Converting the configuration...");
|
||||||
|
info!("converting the configuration...");
|
||||||
let temp_dir = TempDir::new("espanso-migrate-out").expect("unable to create temporary directory");
|
let temp_dir = TempDir::new("espanso-migrate-out").expect("unable to create temporary directory");
|
||||||
let temp_out_dir = temp_dir.path().join("out");
|
let temp_out_dir = temp_dir.path().join("out");
|
||||||
espanso_migrate::migrate(&paths.config, &paths.packages, &temp_out_dir)
|
espanso_migrate::migrate(&paths.config, &paths.packages, &temp_out_dir)
|
||||||
.expect("an error occurred while converting the configuration");
|
.expect("an error occurred while converting the configuration");
|
||||||
println!("{}", "Conversion completed!".green());
|
println!("{}", "Conversion completed!".green());
|
||||||
|
info!("conversion completed!");
|
||||||
|
|
||||||
println!("Replacing old configuration with the new one...");
|
println!("Replacing old configuration with the new one...");
|
||||||
|
info!("replacing old configuration with the new one...");
|
||||||
update_panic_exit_code(MIGRATE_DIRTY_FAILURE);
|
update_panic_exit_code(MIGRATE_DIRTY_FAILURE);
|
||||||
|
|
||||||
let mut to_be_removed = Vec::new();
|
let mut to_be_removed = Vec::new();
|
||||||
|
@ -137,6 +163,7 @@ fn migrate_main(args: CliModuleArgs) -> i32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{}", "Configuration successfully migrated!".green());
|
println!("{}", "Configuration successfully migrated!".green());
|
||||||
|
info!("configuration migrated!");
|
||||||
|
|
||||||
MIGRATE_SUCCESS
|
MIGRATE_SUCCESS
|
||||||
}
|
}
|
||||||
|
@ -166,12 +193,44 @@ fn configure_custom_panic_hook() {
|
||||||
std::panic::set_hook(Box::new(move |info| {
|
std::panic::set_hook(Box::new(move |info| {
|
||||||
(*previous_hook)(info);
|
(*previous_hook)(info);
|
||||||
|
|
||||||
|
// Part of this code is taken from the "rust-log-panics" crate
|
||||||
|
let thread = std::thread::current();
|
||||||
|
let thread = thread.name().unwrap_or("<unnamed>");
|
||||||
|
|
||||||
|
let msg = match info.payload().downcast_ref::<&'static str>() {
|
||||||
|
Some(s) => *s,
|
||||||
|
None => match info.payload().downcast_ref::<String>() {
|
||||||
|
Some(s) => &**s,
|
||||||
|
None => "Box<Any>",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
match info.location() {
|
||||||
|
Some(location) => {
|
||||||
|
eprintln!(
|
||||||
|
"ERROR: '{}' panicked at '{}': {}:{}",
|
||||||
|
thread,
|
||||||
|
msg,
|
||||||
|
location.file(),
|
||||||
|
location.line(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
None => eprintln!("ERROR: '{}' panicked at '{}'", thread, msg,),
|
||||||
|
}
|
||||||
|
|
||||||
let exit_code = CURRENT_PANIC_EXIT_CODE.lock().unwrap();
|
let exit_code = CURRENT_PANIC_EXIT_CODE.lock().unwrap();
|
||||||
std::process::exit(*exit_code);
|
std::process::exit(*exit_code);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_panic_exit_code(exit_code: i32) {
|
fn update_panic_exit_code(exit_code: i32) {
|
||||||
let mut lock = CURRENT_PANIC_EXIT_CODE.lock().expect("unable to update panic exit code");
|
let mut lock = CURRENT_PANIC_EXIT_CODE
|
||||||
|
.lock()
|
||||||
|
.expect("unable to update panic exit code");
|
||||||
*lock = exit_code;
|
*lock = exit_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn error_print_and_log(msg: &str) {
|
||||||
|
error!("{}", msg);
|
||||||
|
eprintln!("{}", msg);
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ pub mod worker;
|
||||||
|
|
||||||
pub struct CliModule {
|
pub struct CliModule {
|
||||||
pub enable_logs: bool,
|
pub enable_logs: bool,
|
||||||
|
pub disable_logs_terminal_output: bool,
|
||||||
pub log_mode: LogMode,
|
pub log_mode: LogMode,
|
||||||
pub requires_paths: bool,
|
pub requires_paths: bool,
|
||||||
pub requires_config: bool,
|
pub requires_config: bool,
|
||||||
|
@ -43,6 +44,7 @@ impl Default for CliModule {
|
||||||
Self {
|
Self {
|
||||||
enable_logs: false,
|
enable_logs: false,
|
||||||
log_mode: LogMode::Read,
|
log_mode: LogMode::Read,
|
||||||
|
disable_logs_terminal_output: false,
|
||||||
requires_paths: false,
|
requires_paths: false,
|
||||||
requires_config: false,
|
requires_config: false,
|
||||||
subcommand: "".to_string(),
|
subcommand: "".to_string(),
|
||||||
|
|
|
@ -30,7 +30,7 @@ use cli::{CliModule, CliModuleArgs};
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use logging::FileProxy;
|
use logging::FileProxy;
|
||||||
use simplelog::{
|
use simplelog::{
|
||||||
CombinedLogger, ConfigBuilder, LevelFilter, TermLogger, TerminalMode, WriteLogger,
|
CombinedLogger, ConfigBuilder, LevelFilter, SharedLogger, TermLogger, TerminalMode, WriteLogger,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::cli::LogMode;
|
use crate::cli::LogMode;
|
||||||
|
@ -224,9 +224,8 @@ fn main() {
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("migrate")
|
SubCommand::with_name("migrate")
|
||||||
.about("Automatically migrate legacy config files to the new v2 format.")
|
.about("Automatically migrate legacy config files to the new v2 format.")
|
||||||
.arg(Arg::with_name("noconfirm")
|
.arg(Arg::with_name("noconfirm").long("noconfirm"))
|
||||||
.long("noconfirm"))
|
.help("Migrate the configuration without asking for confirmation"),
|
||||||
.help("Migrate the configuration without asking for confirmation"),
|
|
||||||
)
|
)
|
||||||
// .subcommand(SubCommand::with_name("match")
|
// .subcommand(SubCommand::with_name("match")
|
||||||
// .about("List and execute matches from the CLI")
|
// .about("List and execute matches from the CLI")
|
||||||
|
@ -319,11 +318,20 @@ fn main() {
|
||||||
.add_filter_ignore_str("html5ever")
|
.add_filter_ignore_str("html5ever")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
CombinedLogger::init(vec![
|
let mut outputs: Vec<Box<dyn SharedLogger>> = vec![WriteLogger::new(
|
||||||
TermLogger::new(log_level, config.clone(), TerminalMode::Mixed),
|
LevelFilter::Info,
|
||||||
WriteLogger::new(LevelFilter::Info, config, log_proxy.clone()),
|
config.clone(),
|
||||||
])
|
log_proxy.clone(),
|
||||||
.expect("unable to initialize logs");
|
)];
|
||||||
|
|
||||||
|
if !handler.disable_logs_terminal_output {
|
||||||
|
outputs.insert(
|
||||||
|
0,
|
||||||
|
TermLogger::new(log_level, config.clone(), TerminalMode::Mixed),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
CombinedLogger::init(outputs).expect("unable to initialize logs");
|
||||||
|
|
||||||
// Activate logging for panics
|
// Activate logging for panics
|
||||||
log_panics::init();
|
log_panics::init();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user