Files
Ten-Shineandfanlusky 4eed9c8442 fix(installer): 升级不再删除 custom_translations.txt (#1035)
* fix(installer): 升级不再删除 custom_translations.txt

custom_translations.txt 是用户手工放在数据目录根下的中英翻译覆盖表,
安装包不携带、引擎只读不写。覆盖安装时 CleanAppDataExceptUserFiles 会
清掉根下所有不在 IsPreservedAppDataItem 名单里的条目,换数据目录时
MigrateUserDataDir 的 robocopy 清单也不含它,于是升级会把它删掉,或留在
旧目录随 RemoveDataDir 一起消失。它没有 config.toml 那样的出厂副本可
回退,删掉即内容彻底丢失。

新增 IsUserTranslationFile 并接入 IsPreservedAppDataItem,覆盖安装时与
其他用户数据同等保留;MigrateUserDataDir 的 robocopy 文件清单补上它,
换数据目录时一并搬走。preserve-user-data.ps1 的 $required 同步更新。

同步 installer/README.md 的迁移清单与 PRIVACY.md 的升级保留说明,并订正
新增函数注释里引用的 README 章节名。

* fix(installer): 迁移 custom_translations.txt 时不覆盖、不静默丢失

换数据目录时 robocopy /MOVE 会用旧目录那份直接盖掉目标目录里已有的
custom_translations.txt,而冲突检查只管 config.toml。现在 ConfigMigrationProblem
对它做同样的检查:两份内容不同就拒绝这个目录,相同就删掉旧目录的残留再搬。
这也避免了 RemoveDataDir 在非独占目录里按名字删掉没搬走的那一份。

迁移失败时原先只有用户词库和 config.toml 会中止安装,custom_translations.txt
被当成皮肤一样可重建的东西只记日志。它没有出厂副本,新增
TranslationMigrationFailure,没搬成同样中止。

同步 PRIVACY.md 与 installer/README.md 的保留/迁移清单,补上此前就漏掉的
stats.db、helpcodes\custom、shuangpin、models。

---------

Co-authored-by: fanlusky <1730976608@qq.com>
2026-10-17 21:46:48 +08:00

36 lines
1.5 KiB
Python

"""Check the production install order that protects user configuration."""
from pathlib import Path
import unittest
SCRIPT = (Path(__file__).resolve().parents[1] / "msime_setup.iss").read_text(encoding="utf-8")
def function_body(name: str, kind: str = "function") -> str:
start = SCRIPT.index(f"{kind} {name}(")
return SCRIPT[start : SCRIPT.index("\nend;", start)]
class CloudChoiceTests(unittest.TestCase):
def test_migration_conflict_is_checked_before_stop_and_migration(self):
prepare = function_body("PrepareToInstall")
migrate = function_body("MigrateUserDataDir")
self.assertLess(prepare.index("ConfigMigrationProblem("), prepare.index("StopImeProcesses;"))
self.assertLess(migrate.index("ConfigMigrationProblem("), migrate.index("Log('Migrating user data"))
self.assertIn("ConfigMigrationFailure(", migrate)
self.assertIn("TranslationMigrationFailure(", migrate)
def test_conflict_is_rejected_on_the_data_dir_page(self):
self.assertIn("ConfigMigrationProblem(", function_body("NextButtonClick"))
def test_cloud_choice_runs_after_required_post_install_steps(self):
post_install = function_body("CurStepChanged", "procedure")
for step in ("CreateWatchdogLogonTask;", "EnsureImeUserDataDir;", "'MetasequoiaImeWatchdog'"):
self.assertLess(post_install.index(step), post_install.index("ApplyNetworkChoiceToUserConfig;"))
if __name__ == "__main__":
unittest.main()