@@ -251,55 +251,66 @@ SchemaUpdate::SchemaUpdate(TaskInitializer arg) : verbose_(false) {
251
251
}
252
252
}
253
253
254
- static bool IsCustomizedCopy (const string& file_name);
254
+ static bool MaybeCreateDirectory (fs::path dir) {
255
+ if (!fs::exists (dir)) {
256
+ boost::system ::error_code ec;
257
+ if (!fs::create_directories (dir, ec)) {
258
+ LOG (ERROR) << " error creating directory '" << dir.string () << " '." ;
259
+ return false ;
260
+ }
261
+ }
262
+ return true ;
263
+ }
255
264
256
- static bool TrashCustomizedCopy (const fs::path& shared_copy,
257
- const fs::path& user_copy,
258
- const string& version_key,
259
- const fs::path& trash) {
265
+ static bool RemoveVersionSuffix (string* version, const string& suffix) {
266
+ size_t suffix_pos = version->find (suffix);
267
+ if (suffix_pos != string::npos) {
268
+ version->erase (suffix_pos);
269
+ return true ;
270
+ }
271
+ return false ;
272
+ }
273
+
274
+ static bool TrashDeprecatedUserCopy (const fs::path& shared_copy,
275
+ const fs::path& user_copy,
276
+ const string& version_key,
277
+ const fs::path& trash) {
260
278
if (!fs::exists (shared_copy) ||
261
279
!fs::exists (user_copy) ||
262
280
fs::equivalent (shared_copy, user_copy)) {
263
281
return false ;
264
282
}
265
- if (IsCustomizedCopy (user_copy.string ())) {
266
- string shared_copy_version;
267
- string user_copy_version;
268
- Config shared_config;
269
- if (shared_config.LoadFromFile (shared_copy.string ())) {
270
- shared_config.GetString (version_key, &shared_copy_version);
271
- }
272
- Config user_config;
273
- if (user_config.LoadFromFile (user_copy.string ()) &&
274
- user_config.GetString (version_key, &user_copy_version)) {
275
- size_t custom_version_suffix = user_copy_version.find (" .custom." );
276
- if (custom_version_suffix != string::npos) {
277
- user_copy_version.erase (custom_version_suffix);
278
- }
279
- }
280
- if (CompareVersionString (shared_copy_version, user_copy_version) >= 0 ) {
281
- fs::path backup = trash / user_copy.filename ();
282
- boost::system ::error_code ec;
283
- fs::rename (user_copy, backup, ec);
284
- if (ec) {
285
- LOG (ERROR) << " error trashing file " << user_copy.string ();
286
- return false ;
287
- }
288
- return true ;
283
+ string shared_copy_version;
284
+ string user_copy_version;
285
+ Config shared_config;
286
+ if (shared_config.LoadFromFile (shared_copy.string ())) {
287
+ shared_config.GetString (version_key, &shared_copy_version);
288
+ // treat "X.Y.minimal" as equal to (not greater than) "X.Y"
289
+ // to avoid trashing the user installed full version
290
+ RemoveVersionSuffix (&shared_copy_version, " .minimal" );
291
+ }
292
+ Config user_config;
293
+ bool is_customized_user_copy =
294
+ user_config.LoadFromFile (user_copy.string ()) &&
295
+ user_config.GetString (version_key, &user_copy_version) &&
296
+ RemoveVersionSuffix (&user_copy_version, " .custom." );
297
+ int cmp = CompareVersionString (shared_copy_version, user_copy_version);
298
+ // rime-installed user copy of the same version should be kept for integrity.
299
+ // also it could have been manually edited by user.
300
+ if (cmp > 0 || (cmp == 0 && is_customized_user_copy)) {
301
+ if (!MaybeCreateDirectory (trash)) {
302
+ return false ;
289
303
}
290
- }
291
- return false ;
292
- }
293
-
294
- static bool MaybeCreateDirectory (fs::path dir) {
295
- if (!fs::exists (dir)) {
304
+ fs::path backup = trash / user_copy.filename ();
296
305
boost::system ::error_code ec;
297
- if (!fs::create_directories (dir, ec)) {
298
- LOG (ERROR) << " error creating directory '" << dir.string () << " '." ;
306
+ fs::rename (user_copy, backup, ec);
307
+ if (ec) {
308
+ LOG (ERROR) << " error trashing file " << user_copy.string ();
299
309
return false ;
300
310
}
311
+ return true ;
301
312
}
302
- return true ;
313
+ return false ;
303
314
}
304
315
305
316
bool SchemaUpdate::Run (Deployer* deployer) {
@@ -416,10 +427,10 @@ bool ConfigFileUpdate::Run(Deployer* deployer) {
416
427
fs::path source_config_path (shared_data_path / file_name_);
417
428
fs::path dest_config_path (user_data_path / file_name_);
418
429
fs::path trash = user_data_path / " trash" ;
419
- if (TrashCustomizedCopy (source_config_path,
420
- dest_config_path,
421
- version_key_,
422
- trash)) {
430
+ if (TrashDeprecatedUserCopy (source_config_path,
431
+ dest_config_path,
432
+ version_key_,
433
+ trash)) {
423
434
LOG (INFO) << " deprecated user copy of '" << file_name_
424
435
<< " ' is moved to " << trash;
425
436
}
@@ -523,13 +534,8 @@ bool BackupConfigFiles::Run(Deployer* deployer) {
523
534
if (!fs::exists (user_data_path))
524
535
return false ;
525
536
fs::path backup_dir (deployer->user_data_sync_dir ());
526
- if (!fs::exists (backup_dir)) {
527
- boost::system ::error_code ec;
528
- if (!fs::create_directories (backup_dir, ec)) {
529
- LOG (ERROR) << " error creating directory '"
530
- << backup_dir.string () << " '." ;
531
- return false ;
532
- }
537
+ if (!MaybeCreateDirectory (backup_dir)) {
538
+ return false ;
533
539
}
534
540
int success = 0 , failure = 0 , latest = 0 , skipped = 0 ;
535
541
for (fs::directory_iterator iter (user_data_path), end;
@@ -587,12 +593,8 @@ bool CleanupTrash::Run(Deployer* deployer) {
587
593
boost::ends_with (filename, " .reverse.kct" ) ||
588
594
boost::ends_with (filename, " .userdb.kct.old" ) ||
589
595
boost::ends_with (filename, " .userdb.kct.snapshot" )) {
590
- if (!success && !failure && !fs::exists (trash)) {
591
- boost::system ::error_code ec;
592
- if (!fs::create_directories (trash, ec)) {
593
- LOG (ERROR) << " error creating directory '" << trash.string () << " '." ;
594
- return false ;
595
- }
596
+ if (!success && !MaybeCreateDirectory (trash)) {
597
+ return false ;
596
598
}
597
599
fs::path backup = trash / entry.filename ();
598
600
boost::system ::error_code ec;
0 commit comments