feat: add orphan mod cleanup tool with GUI integration and live-server tests
- Add arma_modlist_tools/cleaner.py: find_orphan_folders() detects @ModName folders no longer referenced in comparison.json; uses _normalize_name from fetcher for consistent three-level matching - Add clean_orphans.py: CLI with --dry-run and --yes/-y flags; junction-safe deletion via _is_junction() guard before shutil.rmtree - Add Clean Orphans tab to gui/views/tools.py: scrollable checkbox list, background scan/delete threads, pending-done-msg pattern for post-scan status, EN/VI localization strings in gui/locales.py - Add 23 unit tests (section 12), 6 E2E subprocess tests (section 13), 23 coverage-gap tests (section 14), 9 live-server fetcher tests (section 15) - Fix leaked builtins.open mock in _test_read_os_release_parses_file - Overall coverage: 84% → 93%; fetcher.py: 36% → 72%
This commit is contained in:
@@ -224,6 +224,36 @@ _EN: dict[str, str] = {
|
||||
"tools.rm_btn": "Generate Report",
|
||||
"tools.rm_last": "Last generated: {ts}",
|
||||
"tools.rm_none": "No report yet.",
|
||||
|
||||
# ── Tools — Clean Orphans ────────────────────────────────────────────────
|
||||
"tools.oc_desc": (
|
||||
"Scan the downloads folder for mod folders that are no longer "
|
||||
"referenced in comparison.json. These orphans accumulate when you "
|
||||
"remove mods from your presets and re-run the pipeline. "
|
||||
"Select the ones you want to remove to free up disk space."
|
||||
),
|
||||
"tools.oc_warn": (
|
||||
"⚠ Deleting orphans permanently removes mod files from disk. "
|
||||
"This cannot be undone."
|
||||
),
|
||||
"tools.oc_scan_btn": "Scan for Orphans",
|
||||
"tools.oc_scanning": "Scanning…",
|
||||
"tools.oc_no_config": "No config found. Complete Setup first.",
|
||||
"tools.oc_no_comparison": "No comparison.json found — run the pipeline first.",
|
||||
"tools.oc_none_found": "No orphans found. Your downloads folder is clean.",
|
||||
"tools.oc_found": "{count} orphan(s) found — {size} total",
|
||||
"tools.oc_sel_all": "Select All",
|
||||
"tools.oc_sel_none": "Deselect All",
|
||||
"tools.oc_delete_btn": "Delete Selected",
|
||||
"tools.oc_confirm_title": "Confirm Delete",
|
||||
"tools.oc_confirm_body": (
|
||||
"Permanently delete {count} orphan folder(s) ({size})?\n\n"
|
||||
"This cannot be undone."
|
||||
),
|
||||
"tools.oc_done": "Deleted {count} folder(s), freed {size}.",
|
||||
"tools.oc_error": "Error deleting {path}: {e}",
|
||||
"tools.oc_error_title": "Delete errors",
|
||||
"tools.oc_scan_error": "Scan error: {e}",
|
||||
}
|
||||
|
||||
_VI: dict[str, str] = {
|
||||
@@ -431,6 +461,36 @@ _VI: dict[str, str] = {
|
||||
"tools.rm_btn": "Tạo báo cáo",
|
||||
"tools.rm_last": "Tạo lần cuối: {ts}",
|
||||
"tools.rm_none": "Chưa có báo cáo.",
|
||||
|
||||
# ── Tools — Clean Orphans ────────────────────────────────────────────────
|
||||
"tools.oc_desc": (
|
||||
"Quét thư mục downloads để tìm các thư mục mod không còn được "
|
||||
"tham chiếu trong comparison.json. Các mod mồ côi này tích tụ khi "
|
||||
"bạn xóa mod khỏi preset và chạy lại pipeline. "
|
||||
"Chọn các thư mục muốn xóa để giải phóng dung lượng."
|
||||
),
|
||||
"tools.oc_warn": (
|
||||
"⚠ Xóa mod mồ côi sẽ xóa vĩnh viễn tệp mod khỏi ổ đĩa. "
|
||||
"Thao tác này không thể hoàn tác."
|
||||
),
|
||||
"tools.oc_scan_btn": "Quét mod mồ côi",
|
||||
"tools.oc_scanning": "Đang quét…",
|
||||
"tools.oc_no_config": "Chưa tìm thấy cấu hình. Vui lòng hoàn thành thiết lập.",
|
||||
"tools.oc_no_comparison": "Chưa có comparison.json — hãy chạy pipeline trước.",
|
||||
"tools.oc_none_found": "Không tìm thấy mod mồ côi. Thư mục downloads sạch.",
|
||||
"tools.oc_found": "Tìm thấy {count} mod mồ côi — tổng {size}",
|
||||
"tools.oc_sel_all": "Chọn tất cả",
|
||||
"tools.oc_sel_none": "Bỏ chọn",
|
||||
"tools.oc_delete_btn": "Xóa đã chọn",
|
||||
"tools.oc_confirm_title": "Xác nhận xóa",
|
||||
"tools.oc_confirm_body": (
|
||||
"Xóa vĩnh viễn {count} thư mục mồ côi ({size})?\n\n"
|
||||
"Thao tác này không thể hoàn tác."
|
||||
),
|
||||
"tools.oc_done": "Đã xóa {count} thư mục, giải phóng {size}.",
|
||||
"tools.oc_error": "Lỗi khi xóa {path}: {e}",
|
||||
"tools.oc_error_title": "Lỗi xóa",
|
||||
"tools.oc_scan_error": "Lỗi quét: {e}",
|
||||
}
|
||||
|
||||
# Guard: both dicts must have identical key sets
|
||||
|
||||
Reference in New Issue
Block a user