feat(core): introduce migrate cli command
This commit is contained in:
parent
f98ab3dffd
commit
2cf6cafdb6
65
Cargo.lock
generated
65
Cargo.lock
generated
|
@ -170,6 +170,32 @@ dependencies = [
|
||||||
"vec_map",
|
"vec_map",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colored"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"lazy_static",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console"
|
||||||
|
version = "0.14.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45"
|
||||||
|
dependencies = [
|
||||||
|
"encode_unicode",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"regex",
|
||||||
|
"terminal_size",
|
||||||
|
"unicode-width",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const_fn"
|
name = "const_fn"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
|
@ -281,6 +307,18 @@ dependencies = [
|
||||||
"libdbus-sys",
|
"libdbus-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dialoguer"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c9dd058f8b65922819fabb4a41e7d1964e56344042c26efbccd465202c23fa0c"
|
||||||
|
dependencies = [
|
||||||
|
"console",
|
||||||
|
"lazy_static",
|
||||||
|
"tempfile",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diff"
|
name = "diff"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
@ -348,6 +386,12 @@ version = "1.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encode_unicode"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enum-as-inner"
|
name = "enum-as-inner"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -366,7 +410,9 @@ version = "1.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
|
"colored",
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
|
"dialoguer",
|
||||||
"dirs 3.0.1",
|
"dirs 3.0.1",
|
||||||
"enum-as-inner",
|
"enum-as-inner",
|
||||||
"espanso-clipboard",
|
"espanso-clipboard",
|
||||||
|
@ -376,11 +422,13 @@ dependencies = [
|
||||||
"espanso-inject",
|
"espanso-inject",
|
||||||
"espanso-ipc",
|
"espanso-ipc",
|
||||||
"espanso-match",
|
"espanso-match",
|
||||||
|
"espanso-migrate",
|
||||||
"espanso-modulo",
|
"espanso-modulo",
|
||||||
"espanso-path",
|
"espanso-path",
|
||||||
"espanso-render",
|
"espanso-render",
|
||||||
"espanso-ui",
|
"espanso-ui",
|
||||||
"fs2",
|
"fs2",
|
||||||
|
"fs_extra",
|
||||||
"html2text",
|
"html2text",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
|
@ -392,6 +440,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"simplelog",
|
"simplelog",
|
||||||
|
"tempdir",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
@ -1554,6 +1603,16 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "terminal_size"
|
||||||
|
version = "0.1.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "test-case"
|
name = "test-case"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -1811,6 +1870,12 @@ dependencies = [
|
||||||
"linked-hash-map",
|
"linked-hash-map",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zeroize"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zip"
|
name = "zip"
|
||||||
version = "0.5.12"
|
version = "0.5.12"
|
||||||
|
|
|
@ -31,6 +31,7 @@ espanso-render = { path = "../espanso-render" }
|
||||||
espanso-path = { path = "../espanso-path" }
|
espanso-path = { path = "../espanso-path" }
|
||||||
espanso-ipc = { path = "../espanso-ipc" }
|
espanso-ipc = { path = "../espanso-ipc" }
|
||||||
espanso-modulo = { path = "../espanso-modulo", optional = true }
|
espanso-modulo = { path = "../espanso-modulo", optional = true }
|
||||||
|
espanso-migrate = { path = "../espanso-migrate" }
|
||||||
maplit = "1.0.2"
|
maplit = "1.0.2"
|
||||||
simplelog = "0.9.0"
|
simplelog = "0.9.0"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
|
@ -48,6 +49,10 @@ html2text = "0.2.1"
|
||||||
log-panics = "2.0.0"
|
log-panics = "2.0.0"
|
||||||
fs2 = "0.4.3"
|
fs2 = "0.4.3"
|
||||||
serde_yaml = "0.8.17"
|
serde_yaml = "0.8.17"
|
||||||
|
fs_extra = "1.2.0"
|
||||||
|
dialoguer = "0.8.0"
|
||||||
|
colored = "2.0.0"
|
||||||
|
tempdir = "0.3.7"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
named_pipe = "0.4.1"
|
named_pipe = "0.4.1"
|
||||||
|
|
144
espanso/src/cli/migrate.rs
Normal file
144
espanso/src/cli/migrate.rs
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* This file is part of espanso.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 Federico Terzi
|
||||||
|
*
|
||||||
|
* espanso is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* espanso is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use super::{CliModule, CliModuleArgs};
|
||||||
|
use colored::*;
|
||||||
|
use dialoguer::Confirm;
|
||||||
|
use fs_extra::dir::CopyOptions;
|
||||||
|
use tempdir::TempDir;
|
||||||
|
|
||||||
|
pub fn new() -> CliModule {
|
||||||
|
CliModule {
|
||||||
|
requires_paths: true,
|
||||||
|
requires_config: true,
|
||||||
|
subcommand: "migrate".to_string(),
|
||||||
|
entry: migrate_main,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn migrate_main(args: CliModuleArgs) -> i32 {
|
||||||
|
let paths = args.paths.expect("missing paths argument");
|
||||||
|
|
||||||
|
if !args.is_legacy_config {
|
||||||
|
eprintln!("Can't migrate configurations, as the default directory [1] is already encoded with the new format");
|
||||||
|
eprintln!("[1]: {:?}", paths.config);
|
||||||
|
eprintln!("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)");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check if legacy version is still running
|
||||||
|
|
||||||
|
let target_backup_dir = find_available_backup_dir();
|
||||||
|
|
||||||
|
println!("\n{}\n", "Welcome to espanso v2!".bold());
|
||||||
|
println!("This migration tool will help you to smoothly transition to the new espanso v2 configuration format.");
|
||||||
|
println!("");
|
||||||
|
println!(
|
||||||
|
"1. Firstly, espanso will {} your current configuration, located in:\n",
|
||||||
|
"backup".green().bold()
|
||||||
|
);
|
||||||
|
println!(" {}\n", paths.config.to_string_lossy().italic());
|
||||||
|
println!(" into this folder:\n");
|
||||||
|
println!(" {}\n", target_backup_dir.to_string_lossy().italic());
|
||||||
|
println!(
|
||||||
|
"2. Then, it will {} your configuration to the new format, replacing",
|
||||||
|
"convert".bold().green()
|
||||||
|
);
|
||||||
|
println!(" the current content of the config directory.");
|
||||||
|
println!("");
|
||||||
|
|
||||||
|
if !Confirm::new()
|
||||||
|
.with_prompt("Do you want to proceed?")
|
||||||
|
.default(true)
|
||||||
|
.interact()
|
||||||
|
.expect("unable to read choice")
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Backing up your configuration...");
|
||||||
|
|
||||||
|
fs_extra::dir::copy(
|
||||||
|
&paths.config,
|
||||||
|
&target_backup_dir,
|
||||||
|
&CopyOptions {
|
||||||
|
copy_inside: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("unable to backup the current config");
|
||||||
|
println!("{}", "Backup completed!".green());
|
||||||
|
|
||||||
|
println!("Converting the configuration...");
|
||||||
|
let temp_dir = TempDir::new("espanso-migrate-out").expect("unable to create temporary directory");
|
||||||
|
let temp_out_dir = temp_dir.path().join("out");
|
||||||
|
espanso_migrate::migrate(&paths.config, &paths.packages, &temp_out_dir)
|
||||||
|
.expect("an error occurred while converting the configuration");
|
||||||
|
println!("{}", "Conversion completed!".green());
|
||||||
|
|
||||||
|
println!("Replacing old configuration with the new one...");
|
||||||
|
|
||||||
|
let mut to_be_removed = Vec::new();
|
||||||
|
let legacy_dir_content = fs_extra::dir::get_dir_content(&paths.config).expect("unable to list legacy dir files");
|
||||||
|
to_be_removed.extend(legacy_dir_content.files);
|
||||||
|
to_be_removed.extend(legacy_dir_content.directories);
|
||||||
|
fs_extra::remove_items(&to_be_removed).expect("unable to remove previous configuration");
|
||||||
|
fs_extra::dir::copy(
|
||||||
|
&temp_out_dir,
|
||||||
|
&paths.config,
|
||||||
|
&CopyOptions {
|
||||||
|
copy_inside: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("unable to copy new configuration into target location");
|
||||||
|
|
||||||
|
let target_packages_dir = &paths.config.join("match").join("packages");
|
||||||
|
if !target_packages_dir.is_dir() {
|
||||||
|
std::fs::create_dir_all(target_packages_dir).expect("unable to create new packages directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", "Configuration successfully migrated!".green());
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_available_backup_dir() -> PathBuf {
|
||||||
|
for i in 1..20 {
|
||||||
|
let num = if i > 1 {
|
||||||
|
format!("-{}", i)
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
let target_backup_dir = dirs::document_dir()
|
||||||
|
.expect("unable to generate backup directory")
|
||||||
|
.join(format!("espanso-migrate-backup{}", num));
|
||||||
|
|
||||||
|
if !target_backup_dir.is_dir() {
|
||||||
|
return target_backup_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("could not generate valid backup directory");
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ use espanso_path::Paths;
|
||||||
|
|
||||||
pub mod daemon;
|
pub mod daemon;
|
||||||
pub mod log;
|
pub mod log;
|
||||||
|
pub mod migrate;
|
||||||
pub mod modulo;
|
pub mod modulo;
|
||||||
pub mod path;
|
pub mod path;
|
||||||
pub mod worker;
|
pub mod worker;
|
||||||
|
|
|
@ -27,7 +27,7 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||||
use cli::{CliModule, CliModuleArgs};
|
use cli::{CliModule, CliModuleArgs};
|
||||||
use log::{error, info};
|
use log::{error, info, warn};
|
||||||
use logging::FileProxy;
|
use logging::FileProxy;
|
||||||
use simplelog::{
|
use simplelog::{
|
||||||
CombinedLogger, ConfigBuilder, LevelFilter, TermLogger, TerminalMode, WriteLogger,
|
CombinedLogger, ConfigBuilder, LevelFilter, TermLogger, TerminalMode, WriteLogger,
|
||||||
|
@ -55,6 +55,7 @@ lazy_static! {
|
||||||
cli::worker::new(),
|
cli::worker::new(),
|
||||||
cli::daemon::new(),
|
cli::daemon::new(),
|
||||||
cli::modulo::new(),
|
cli::modulo::new(),
|
||||||
|
cli::migrate::new(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +219,10 @@ fn main() {
|
||||||
)
|
)
|
||||||
.subcommand(SubCommand::with_name("base").about("Print the default match file path.")),
|
.subcommand(SubCommand::with_name("base").about("Print the default match file path.")),
|
||||||
)
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("migrate")
|
||||||
|
.about("Automatically migrate legacy config files to the new v2 format.")
|
||||||
|
)
|
||||||
// .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")
|
||||||
// .subcommand(SubCommand::with_name("list")
|
// .subcommand(SubCommand::with_name("list")
|
||||||
|
@ -353,6 +358,11 @@ fn main() {
|
||||||
cli_args.is_legacy_config = is_legacy_config;
|
cli_args.is_legacy_config = is_legacy_config;
|
||||||
cli_args.config_store = Some(config_store);
|
cli_args.config_store = Some(config_store);
|
||||||
cli_args.match_store = Some(match_store);
|
cli_args.match_store = Some(match_store);
|
||||||
|
|
||||||
|
if is_legacy_config {
|
||||||
|
warn!("espanso is reading the configuration using compatibility mode, thus some features might not be available");
|
||||||
|
warn!("you can migrate to the new configuration format by running 'espanso migrate' in a terminal");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if handler.enable_logs {
|
if handler.enable_logs {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user