From 84fa72e919fae8c4e1eff1b749fe920f2fbc83e4 Mon Sep 17 00:00:00 2001 From: Chen Gong Date: Thu, 15 Mar 2018 22:17:25 +0800 Subject: [PATCH 1/3] fix(config_file_update): trash deprecated user copy created by older rime version --- src/rime/lever/deployment_tasks.cc | 65 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/src/rime/lever/deployment_tasks.cc b/src/rime/lever/deployment_tasks.cc index 1431eab11..6fc6e7d73 100644 --- a/src/rime/lever/deployment_tasks.cc +++ b/src/rime/lever/deployment_tasks.cc @@ -251,42 +251,41 @@ SchemaUpdate::SchemaUpdate(TaskInitializer arg) : verbose_(false) { } } -static bool IsCustomizedCopy(const string& file_name); - -static bool TrashCustomizedCopy(const fs::path& shared_copy, - const fs::path& user_copy, - const string& version_key, - const fs::path& trash) { +static bool TrashDeprecatedUserCopy(const fs::path& shared_copy, + const fs::path& user_copy, + const string& version_key, + const fs::path& trash) { if (!fs::exists(shared_copy) || !fs::exists(user_copy) || fs::equivalent(shared_copy, user_copy)) { return false; } - if (IsCustomizedCopy(user_copy.string())) { - string shared_copy_version; - string user_copy_version; - Config shared_config; - if (shared_config.LoadFromFile(shared_copy.string())) { - shared_config.GetString(version_key, &shared_copy_version); - } - Config user_config; - if (user_config.LoadFromFile(user_copy.string()) && - user_config.GetString(version_key, &user_copy_version)) { - size_t custom_version_suffix = user_copy_version.find(".custom."); - if (custom_version_suffix != string::npos) { - user_copy_version.erase(custom_version_suffix); - } + string shared_copy_version; + string user_copy_version; + Config shared_config; + if (shared_config.LoadFromFile(shared_copy.string())) { + shared_config.GetString(version_key, &shared_copy_version); + } + bool is_customized_copy = false; + Config user_config; + if (user_config.LoadFromFile(user_copy.string()) && + user_config.GetString(version_key, &user_copy_version)) { + size_t custom_version_suffix = user_copy_version.find(".custom."); + if (custom_version_suffix != string::npos) { + user_copy_version.erase(custom_version_suffix); + is_customized_copy = true; } - if (CompareVersionString(shared_copy_version, user_copy_version) >= 0) { - fs::path backup = trash / user_copy.filename(); - boost::system::error_code ec; - fs::rename(user_copy, backup, ec); - if (ec) { - LOG(ERROR) << "error trashing file " << user_copy.string(); - return false; - } - return true; + } + int cmp = CompareVersionString(shared_copy_version, user_copy_version); + if (cmp > 0 || (cmp == 0 && is_customized_copy)) { + fs::path backup = trash / user_copy.filename(); + boost::system::error_code ec; + fs::rename(user_copy, backup, ec); + if (ec) { + LOG(ERROR) << "error trashing file " << user_copy.string(); + return false; } + return true; } return false; } @@ -416,10 +415,10 @@ bool ConfigFileUpdate::Run(Deployer* deployer) { fs::path source_config_path(shared_data_path / file_name_); fs::path dest_config_path(user_data_path / file_name_); fs::path trash = user_data_path / "trash"; - if (TrashCustomizedCopy(source_config_path, - dest_config_path, - version_key_, - trash)) { + if (TrashDeprecatedUserCopy(source_config_path, + dest_config_path, + version_key_, + trash)) { LOG(INFO) << "deprecated user copy of '" << file_name_ << "' is moved to " << trash; } From f018c3eb0f1f36b1af76fa29b80ed7d12da73f1d Mon Sep 17 00:00:00 2001 From: Chen Gong Date: Thu, 15 Mar 2018 22:50:22 +0800 Subject: [PATCH 2/3] fix(config_file_update): create trash directory when needed to trash config files --- src/rime/lever/deployment_tasks.cc | 45 ++++++++++++++---------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/rime/lever/deployment_tasks.cc b/src/rime/lever/deployment_tasks.cc index 6fc6e7d73..9e5a71f60 100644 --- a/src/rime/lever/deployment_tasks.cc +++ b/src/rime/lever/deployment_tasks.cc @@ -251,6 +251,17 @@ SchemaUpdate::SchemaUpdate(TaskInitializer arg) : verbose_(false) { } } +static bool MaybeCreateDirectory(fs::path dir) { + if (!fs::exists(dir)) { + boost::system::error_code ec; + if (!fs::create_directories(dir, ec)) { + LOG(ERROR) << "error creating directory '" << dir.string() << "'."; + return false; + } + } + return true; +} + static bool TrashDeprecatedUserCopy(const fs::path& shared_copy, const fs::path& user_copy, const string& version_key, @@ -277,7 +288,13 @@ static bool TrashDeprecatedUserCopy(const fs::path& shared_copy, } } int cmp = CompareVersionString(shared_copy_version, user_copy_version); + LOG(INFO) << shared_copy.string() << ':' << shared_copy_version + << (cmp == 0 ? '=' : cmp > 0 ? '>' : '<') + << user_copy_version << ':' << user_copy.string(); if (cmp > 0 || (cmp == 0 && is_customized_copy)) { + if (!MaybeCreateDirectory(trash)) { + return false; + } fs::path backup = trash / user_copy.filename(); boost::system::error_code ec; fs::rename(user_copy, backup, ec); @@ -290,17 +307,6 @@ static bool TrashDeprecatedUserCopy(const fs::path& shared_copy, return false; } -static bool MaybeCreateDirectory(fs::path dir) { - if (!fs::exists(dir)) { - boost::system::error_code ec; - if (!fs::create_directories(dir, ec)) { - LOG(ERROR) << "error creating directory '" << dir.string() << "'."; - return false; - } - } - return true; -} - bool SchemaUpdate::Run(Deployer* deployer) { fs::path source_path(schema_file_); if (!fs::exists(source_path)) { @@ -522,13 +528,8 @@ bool BackupConfigFiles::Run(Deployer* deployer) { if (!fs::exists(user_data_path)) return false; fs::path backup_dir(deployer->user_data_sync_dir()); - if (!fs::exists(backup_dir)) { - boost::system::error_code ec; - if (!fs::create_directories(backup_dir, ec)) { - LOG(ERROR) << "error creating directory '" - << backup_dir.string() << "'."; - return false; - } + if (!MaybeCreateDirectory(backup_dir)) { + return false; } int success = 0, failure = 0, latest = 0, skipped = 0; for (fs::directory_iterator iter(user_data_path), end; @@ -586,12 +587,8 @@ bool CleanupTrash::Run(Deployer* deployer) { boost::ends_with(filename, ".reverse.kct") || boost::ends_with(filename, ".userdb.kct.old") || boost::ends_with(filename, ".userdb.kct.snapshot")) { - if (!success && !failure && !fs::exists(trash)) { - boost::system::error_code ec; - if (!fs::create_directories(trash, ec)) { - LOG(ERROR) << "error creating directory '" << trash.string() << "'."; - return false; - } + if (!success && !MaybeCreateDirectory(trash)) { + return false; } fs::path backup = trash / entry.filename(); boost::system::error_code ec; From 31cbb2e8895df0d4a47ff6887285a6e18bc01884 Mon Sep 17 00:00:00 2001 From: Chen Gong Date: Thu, 15 Mar 2018 23:20:26 +0800 Subject: [PATCH 3/3] fix(config_file_update): prefer rime-installed user copy to shared minimal version if numbers match' --- src/rime/lever/deployment_tasks.cc | 32 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/rime/lever/deployment_tasks.cc b/src/rime/lever/deployment_tasks.cc index 9e5a71f60..ec8f5ca93 100644 --- a/src/rime/lever/deployment_tasks.cc +++ b/src/rime/lever/deployment_tasks.cc @@ -262,6 +262,15 @@ static bool MaybeCreateDirectory(fs::path dir) { return true; } +static bool RemoveVersionSuffix(string* version, const string& suffix) { + size_t suffix_pos = version->find(suffix); + if (suffix_pos != string::npos) { + version->erase(suffix_pos); + return true; + } + return false; +} + static bool TrashDeprecatedUserCopy(const fs::path& shared_copy, const fs::path& user_copy, const string& version_key, @@ -276,22 +285,19 @@ static bool TrashDeprecatedUserCopy(const fs::path& shared_copy, Config shared_config; if (shared_config.LoadFromFile(shared_copy.string())) { shared_config.GetString(version_key, &shared_copy_version); + // treat "X.Y.minimal" as equal to (not greater than) "X.Y" + // to avoid trashing the user installed full version + RemoveVersionSuffix(&shared_copy_version, ".minimal"); } - bool is_customized_copy = false; Config user_config; - if (user_config.LoadFromFile(user_copy.string()) && - user_config.GetString(version_key, &user_copy_version)) { - size_t custom_version_suffix = user_copy_version.find(".custom."); - if (custom_version_suffix != string::npos) { - user_copy_version.erase(custom_version_suffix); - is_customized_copy = true; - } - } + bool is_customized_user_copy = + user_config.LoadFromFile(user_copy.string()) && + user_config.GetString(version_key, &user_copy_version) && + RemoveVersionSuffix(&user_copy_version, ".custom."); int cmp = CompareVersionString(shared_copy_version, user_copy_version); - LOG(INFO) << shared_copy.string() << ':' << shared_copy_version - << (cmp == 0 ? '=' : cmp > 0 ? '>' : '<') - << user_copy_version << ':' << user_copy.string(); - if (cmp > 0 || (cmp == 0 && is_customized_copy)) { + // rime-installed user copy of the same version should be kept for integrity. + // also it could have been manually edited by user. + if (cmp > 0 || (cmp == 0 && is_customized_user_copy)) { if (!MaybeCreateDirectory(trash)) { return false; }