diff --git a/Cargo.lock b/Cargo.lock index 33c6fe8..77990d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -478,6 +478,24 @@ dependencies = [ "unicase", ] +[[package]] +name = "espanso-migrate" +version = "0.1.0" +dependencies = [ + "anyhow", + "dunce", + "glob", + "include_dir", + "lazy_static", + "log", + "regex", + "tempdir", + "tempfile", + "test-case", + "thiserror", + "walkdir", +] + [[package]] name = "espanso-modulo" version = "0.1.0" @@ -657,6 +675,30 @@ dependencies = [ "syn 1.0.60", ] +[[package]] +name = "include_dir" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d58bdeb22b1c4691106c084b1063781904c35d0f22eda2a283598968eac61a" +dependencies = [ + "glob", + "include_dir_impl", + "proc-macro-hack", +] + +[[package]] +name = "include_dir_impl" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327869970574819d24d1dca25c891856144d29159ab797fa9dc725c5c3f57215" +dependencies = [ + "anyhow", + "proc-macro-hack", + "proc-macro2", + "quote 1.0.9", + "syn 1.0.60", +] + [[package]] name = "itertools" version = "0.10.0" @@ -1025,6 +1067,12 @@ dependencies = [ "treeline", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + [[package]] name = "proc-macro2" version = "1.0.24" @@ -1444,6 +1492,19 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "test-case" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956044ef122917dde830c19dec5f76d0670329fde4104836d62ebcb14f4865f1" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote 1.0.9", + "syn 1.0.60", + "version_check", +] + [[package]] name = "textwrap" version = "0.11.0" diff --git a/Cargo.toml b/Cargo.toml index d3a4f85..c668f9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,5 @@ members = [ "espanso-info", "espanso-path", "espanso-modulo", + "espanso-migrate", ] \ No newline at end of file diff --git a/espanso-migrate/Cargo.toml b/espanso-migrate/Cargo.toml new file mode 100644 index 0000000..50d61b1 --- /dev/null +++ b/espanso-migrate/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "espanso-migrate" +version = "0.1.0" +authors = ["Federico Terzi "] +edition = "2018" + +[dependencies] +log = "0.4.14" +anyhow = "1.0.38" +thiserror = "1.0.23" +glob = "0.3.0" +regex = "1.4.3" +lazy_static = "1.4.0" +dunce = "1.0.1" +walkdir = "2.3.1" + +[dev-dependencies] +tempdir = "0.3.7" +tempfile = "3.2.0" +include_dir = "0.6.0" +test-case = "1.1.0" \ No newline at end of file diff --git a/espanso-migrate/src/lib.rs b/espanso-migrate/src/lib.rs new file mode 100644 index 0000000..4c637d2 --- /dev/null +++ b/espanso-migrate/src/lib.rs @@ -0,0 +1,66 @@ +/* + * 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 . + */ + +#[macro_use] +extern crate lazy_static; + +#[macro_use] +#[cfg(test)] +extern crate include_dir; + +#[macro_use] +#[cfg(test)] +extern crate test_case; + +use anyhow::Result; +use thiserror::Error; + +// TODO: implement +// Use yaml-rust with "preserve-order" = true +// Strategy: +// 1. Backup the current config directory in a zip archive (also with the packages) +// 2. Create a temporary directory alonside the legacy one called "espanso-new" +// 3. Convert all the files and write the output into "espanso-new" +// 4. Rename the legacy dir to "espanso-old" +// 5. Rename new dir to "espanso" +// 6. If the legacy directory was a symlink, try to recreate it (ask the user first) + +// TODO: before attempting the migration strategy, check if the current +// espanso config directory is a symlink and, if so, attempt to remap +// the symlink with the new dir (after asking the user) +// This is necessary because in order to be safe, the migration strategy +// creates the new config on a new temporary directory and then "swaps" +// the old with the new one + +// TODO: test case with packages + +#[cfg(test)] +mod tests { + use super::*; + use test_case::test_case; + use include_dir::{include_dir, Dir}; + + static BASE_CASE: Dir = include_dir!("test/base"); + + #[test_case(&BASE_CASE; "base case")] + fn test_migration(test_data: &Dir) { + // TODO + assert!(false); + } +} diff --git a/espanso-migrate/test/README.md b/espanso-migrate/test/README.md new file mode 100644 index 0000000..5ccf659 --- /dev/null +++ b/espanso-migrate/test/README.md @@ -0,0 +1 @@ +This directory contains the files used to test the migration strategy. \ No newline at end of file diff --git a/espanso-migrate/test/all_params/legacy/default.yml b/espanso-migrate/test/all_params/legacy/default.yml new file mode 100644 index 0000000..da172fb --- /dev/null +++ b/espanso-migrate/test/all_params/legacy/default.yml @@ -0,0 +1,42 @@ +config_caching_interval: 1200 + +toggle_interval: 500 +toggle_key: "CTRL" + +preserve_clipboard: false + +backspace_limit: 5 + +inject_delay: 10 +restore_clipboard_delay: 400 + +secure_input_watcher_enabled: false +secure_input_notification: false +secure_input_watcher_interval: 3000 + +show_notifications: false +show_icon: false + +auto_restart: false +undo_backspace: false + +fast_inject: false + +post_inject_delay: 200 + +paste_shortcut: # TODO + +backend: Clipboard + +global_vars: + - name: "name" + type: "dummy" + params: + echo: "John" + +matches: + - name: ":hi" + trigger: "Hello" + + - name: ":greet" + trigger: "Hi {{name}}" \ No newline at end of file diff --git a/espanso-migrate/test/base/expected/config/default.yml b/espanso-migrate/test/base/expected/config/default.yml new file mode 100644 index 0000000..3b6eb10 --- /dev/null +++ b/espanso-migrate/test/base/expected/config/default.yml @@ -0,0 +1 @@ +backend: Clipboard \ No newline at end of file diff --git a/espanso-migrate/test/base/expected/config/disabled.yml b/espanso-migrate/test/base/expected/config/disabled.yml new file mode 100644 index 0000000..192a28d --- /dev/null +++ b/espanso-migrate/test/base/expected/config/disabled.yml @@ -0,0 +1,3 @@ +filter_title: "Disabled program" + +enabled: false \ No newline at end of file diff --git a/espanso-migrate/test/base/expected/config/extended.yml b/espanso-migrate/test/base/expected/config/extended.yml new file mode 100644 index 0000000..e1a3e61 --- /dev/null +++ b/espanso-migrate/test/base/expected/config/extended.yml @@ -0,0 +1,4 @@ +filter_exec: "Executable" + +extra_includes: + - "../match/_extended.yml" \ No newline at end of file diff --git a/espanso-migrate/test/base/expected/config/standalone.yml b/espanso-migrate/test/base/expected/config/standalone.yml new file mode 100644 index 0000000..6697559 --- /dev/null +++ b/espanso-migrate/test/base/expected/config/standalone.yml @@ -0,0 +1,4 @@ +filter_class: "Standalone" + +includes: + - "../match/_standalone.yml" \ No newline at end of file diff --git a/espanso-migrate/test/base/expected/match/_extended.yml b/espanso-migrate/test/base/expected/match/_extended.yml new file mode 100644 index 0000000..5e95626 --- /dev/null +++ b/espanso-migrate/test/base/expected/match/_extended.yml @@ -0,0 +1,9 @@ +global_vars: + - name: "test" + type: "date" + params: + format: "%H" + +matches: + - trigger: "extend" + replace: "match" \ No newline at end of file diff --git a/espanso-migrate/test/base/expected/match/_standalone.yml b/espanso-migrate/test/base/expected/match/_standalone.yml new file mode 100644 index 0000000..c204930 --- /dev/null +++ b/espanso-migrate/test/base/expected/match/_standalone.yml @@ -0,0 +1,3 @@ +matches: + - trigger: "hello" + replace: "world" \ No newline at end of file diff --git a/espanso-migrate/test/base/expected/match/base.yml b/espanso-migrate/test/base/expected/match/base.yml new file mode 100644 index 0000000..055cd1b --- /dev/null +++ b/espanso-migrate/test/base/expected/match/base.yml @@ -0,0 +1,12 @@ +global_vars: + - name: "name" + type: "echo" + params: + echo: "John" + +matches: + - name: ":hi" + trigger: "Hello" + + - name: ":greet" + trigger: "Hi {{name}}" \ No newline at end of file diff --git a/espanso-migrate/test/base/legacy/default.yml b/espanso-migrate/test/base/legacy/default.yml new file mode 100644 index 0000000..6afad09 --- /dev/null +++ b/espanso-migrate/test/base/legacy/default.yml @@ -0,0 +1,14 @@ +backend: Clipboard + +global_vars: + - name: "name" + type: "dummy" + params: + echo: "John" + +matches: + - name: ":hi" + trigger: "Hello" + + - name: ":greet" + trigger: "Hi {{name}}" \ No newline at end of file diff --git a/espanso-migrate/test/base/legacy/user/disabled.yml b/espanso-migrate/test/base/legacy/user/disabled.yml new file mode 100644 index 0000000..030e783 --- /dev/null +++ b/espanso-migrate/test/base/legacy/user/disabled.yml @@ -0,0 +1,3 @@ +filter_title: "Disabled program" + +enable_active: false \ No newline at end of file diff --git a/espanso-migrate/test/base/legacy/user/extended.yml b/espanso-migrate/test/base/legacy/user/extended.yml new file mode 100644 index 0000000..e94ffef --- /dev/null +++ b/espanso-migrate/test/base/legacy/user/extended.yml @@ -0,0 +1,13 @@ +parent: default + +filter_exec: "Executable" + +global_vars: + - name: "test" + type: "date" + params: + format: "%H" + +matches: + - trigger: "extend" + replace: "match" \ No newline at end of file diff --git a/espanso-migrate/test/base/legacy/user/standalone.yml b/espanso-migrate/test/base/legacy/user/standalone.yml new file mode 100644 index 0000000..bb41d98 --- /dev/null +++ b/espanso-migrate/test/base/legacy/user/standalone.yml @@ -0,0 +1,7 @@ +filter_class: "Standalone" + +exclude_default_entries: true + +matches: + - trigger: "hello" + replace: "world" \ No newline at end of file