Первый выпуск SysDevCleaner
Анализ Windows и очистка кешей, мусора и остатков разработки. Ядро: - каталог правил: 228 правил путей (496 шаблонов) + 43 правила артефактов проектов — Windows, браузеры, кеши сборки, IDE, приложения, пакетные менеджеры; - рекурсивный поиск node_modules, target, build, __pycache__, .venv и т.п. с проверкой маркеров проекта, чтобы не ловить ложные срабатывания; - поиск крупных файлов и дубликатов (хеш по началу/середине/концу и полная сверка), инвентаризация установленных программ через реестр; - ограничение области сканирования по дискам; - рекомендации и текстовый отчёт. Безопасность: - четыре уровня риска, автоматически отмечается только «Безопасно»; - список защищённых путей проверяется и при выборе, и перед удалением; - для каталогов вроде %TEMP% удаляется содержимое, а не сам каталог; - удаление в Корзину по умолчанию, пробный запуск, журнал очисток. Интерфейс на Dear PyGui: - JetBrains Mono Nerd Font: кириллица и иконки в одном шрифте; - тёмная и светлая темы, адаптивная раскладка; - заголовок окна ставится через SetWindowTextW — Dear PyGui отдаёт его в ANSI-функцию как UTF-8 и портит кириллицу; - запуск всегда с правами администратора: манифест UAC в exe и самоперезапуск через ShellExecuteW при работе из исходников. Сборка в один exe через PyInstaller со вшитым шрифтом и значком. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
645
sysdevcleaner/core/rules.py
Normal file
645
sysdevcleaner/core/rules.py
Normal file
@@ -0,0 +1,645 @@
|
||||
"""Каталог правил: где в Windows копится кеш, мусор и остатки разработки.
|
||||
|
||||
Пути записаны шаблонами с плейсхолдерами ``{LOCAL}``, ``{ROAMING}``, ``{HOME}``,
|
||||
``{WINDIR}``, ``{PROGRAMDATA}``, ``{TEMP}``, ``{LOCALLOW}``, ``{PROGRAMFILES}``,
|
||||
``{PROGRAMFILES86}``, ``{PUBLIC}``, ``{SYSTEMDRIVE}``.
|
||||
Поддерживаются glob-маски (``*``), поэтому одно правило покрывает все профили
|
||||
браузеров и все версии IDE сразу.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from .model import Category, Risk
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Rule:
|
||||
id: str
|
||||
title: str
|
||||
category: Category
|
||||
risk: Risk
|
||||
detail: str
|
||||
paths: tuple[str, ...] = ()
|
||||
contents_only: bool = False # чистим внутренности, каталог оставляем
|
||||
needs_admin: bool = False
|
||||
processes: tuple[str, ...] = () # предупредить, если запущены
|
||||
min_size: int = 0 # не показывать мелочь
|
||||
files_only: tuple[str, ...] = () # маски файлов внутри paths
|
||||
|
||||
|
||||
C = Category
|
||||
R = Risk
|
||||
|
||||
# --------------------------------------------------------------- Windows ----
|
||||
|
||||
WINDOWS_RULES: list[Rule] = [
|
||||
Rule("win.temp.user", "Временные файлы пользователя", C.WINDOWS, R.SAFE,
|
||||
"Рабочая свалка установщиков и приложений. Занятые файлы пропускаются автоматически.",
|
||||
("{TEMP}",), contents_only=True),
|
||||
Rule("win.temp.system", "Временные файлы системы", C.WINDOWS, R.SAFE,
|
||||
"C:\\Windows\\Temp — то же самое, но для служб. Нужны права администратора.",
|
||||
("{WINDIR}\\Temp",), contents_only=True, needs_admin=True),
|
||||
Rule("win.update.download", "Кеш загрузок Windows Update", C.WINDOWS, R.LOW,
|
||||
"Скачанные пакеты обновлений. Уже установленные не нужны; система скачает заново, если потребуется.",
|
||||
("{WINDIR}\\SoftwareDistribution\\Download",), contents_only=True, needs_admin=True),
|
||||
Rule("win.delivery", "Оптимизация доставки", C.WINDOWS, R.LOW,
|
||||
"Кеш P2P-раздачи обновлений другим ПК в сети. Часто вырастает до нескольких ГБ.",
|
||||
("{WINDIR}\\ServiceProfiles\\NetworkService\\AppData\\Local\\Microsoft\\Windows\\DeliveryOptimization",),
|
||||
contents_only=True, needs_admin=True),
|
||||
Rule("win.old", "Windows.old (прошлая версия Windows)", C.WINDOWS, R.MEDIUM,
|
||||
"Полная копия старой системы после обновления. Удаление лишает возможности откатиться назад.",
|
||||
("{SYSTEMDRIVE}Windows.old",), needs_admin=True),
|
||||
Rule("win.prefetch", "Prefetch", C.WINDOWS, R.LOW,
|
||||
"Данные предзагрузки приложений. После очистки первые запуски программ будут чуть медленнее.",
|
||||
("{WINDIR}\\Prefetch",), contents_only=True, needs_admin=True),
|
||||
Rule("win.crashdumps", "Дампы аварийных завершений", C.WINDOWS, R.SAFE,
|
||||
"Снимки памяти упавших программ. Нужны только для разбора конкретного сбоя.",
|
||||
("{LOCAL}\\CrashDumps", "{WINDIR}\\Minidump",), contents_only=True),
|
||||
Rule("win.memorydmp", "Полный дамп памяти (MEMORY.DMP)", C.WINDOWS, R.LOW,
|
||||
"Снимок всей оперативной памяти после BSOD — обычно равен объёму ОЗУ.",
|
||||
("{WINDIR}\\MEMORY.DMP",), needs_admin=True),
|
||||
Rule("win.wer", "Отчёты об ошибках (WER)", C.WINDOWS, R.SAFE,
|
||||
"Очереди отчётов Windows Error Reporting.",
|
||||
("{LOCAL}\\Microsoft\\Windows\\WER", "{PROGRAMDATA}\\Microsoft\\Windows\\WER"),
|
||||
contents_only=True),
|
||||
Rule("win.thumbcache", "Кеш эскизов и значков", C.WINDOWS, R.SAFE,
|
||||
"thumbcache_*.db / iconcache_*.db. Пересоздаётся проводником на лету.",
|
||||
("{LOCAL}\\Microsoft\\Windows\\Explorer",), contents_only=True,
|
||||
files_only=("thumbcache_*.db", "iconcache_*.db")),
|
||||
Rule("win.fontcache", "Кеш шрифтов", C.WINDOWS, R.LOW,
|
||||
"Служебный кеш подсистемы шрифтов.",
|
||||
("{WINDIR}\\ServiceProfiles\\LocalService\\AppData\\Local\\FontCache",),
|
||||
contents_only=True, needs_admin=True),
|
||||
Rule("win.inetcache", "Кеш Internet Explorer / WinINet", C.WINDOWS, R.SAFE,
|
||||
"Общесистемный HTTP-кеш, которым пользуются и многие desktop-приложения.",
|
||||
("{LOCAL}\\Microsoft\\Windows\\INetCache",), contents_only=True),
|
||||
Rule("win.d3dcache", "Кеш шейдеров DirectX", C.WINDOWS, R.SAFE,
|
||||
"Скомпилированные шейдеры. Пересобираются при следующем запуске игры.",
|
||||
("{LOCAL}\\D3DSCache", "{LOCAL}\\Microsoft\\DirectX Shader Cache"), contents_only=True),
|
||||
Rule("win.recycle", "Корзина", C.WINDOWS, R.MEDIUM,
|
||||
"Файлы, удалённые ранее. После очистки восстановить их уже нельзя.",
|
||||
("{SYSTEMDRIVE}$Recycle.Bin",), contents_only=True),
|
||||
Rule("win.installer.patch", "Кеш патчей установщика Windows", C.WINDOWS, R.MEDIUM,
|
||||
"$PatchCache$ нужен для отката и восстановления MSI-программ.",
|
||||
("{WINDIR}\\Installer\\$PatchCache$",), contents_only=True, needs_admin=True),
|
||||
Rule("win.panther", "Логи установки системы (Panther)", C.WINDOWS, R.SAFE,
|
||||
"Отчёты установщика Windows и драйверов.",
|
||||
("{WINDIR}\\Panther", "{WINDIR}\\inf\\setupapi.dev.log"),
|
||||
contents_only=True, needs_admin=True),
|
||||
Rule("win.defender.history", "История проверок Windows Defender", C.WINDOWS, R.LOW,
|
||||
"Журнал сканирований антивируса. На саму защиту не влияет.",
|
||||
("{PROGRAMDATA}\\Microsoft\\Windows Defender\\Scans\\History\\Service",
|
||||
"{PROGRAMDATA}\\Microsoft\\Windows Defender\\Scans\\History\\Results"),
|
||||
contents_only=True, needs_admin=True),
|
||||
Rule("win.clipboard", "Кеш перьевого/облачного ввода", C.WINDOWS, R.LOW,
|
||||
"Служебные данные InputPersonalization и истории буфера.",
|
||||
("{LOCAL}\\Microsoft\\InputPersonalization\\TextHarvester",), contents_only=True),
|
||||
Rule("win.livekernel", "LiveKernelReports", C.WINDOWS, R.SAFE,
|
||||
"Дампы сбоев драйверов без полного BSOD.",
|
||||
("{WINDIR}\\LiveKernelReports",), contents_only=True, needs_admin=True),
|
||||
Rule("win.downloadedinstall", "Downloaded Installations", C.WINDOWS, R.LOW,
|
||||
"Распакованные дистрибутивы старых установщиков.",
|
||||
("{PROGRAMDATA}\\Downloaded Installations",), contents_only=True),
|
||||
Rule("win.hyperv.cache", "Кеш Microsoft Store / AppX", C.WINDOWS, R.SAFE,
|
||||
"Временные файлы доставки приложений из Store.",
|
||||
("{LOCAL}\\Packages\\Microsoft.Windows.Search_cw5n1h2txyewy\\LocalState\\AppIconCache",
|
||||
"{LOCAL}\\Microsoft\\Windows\\Caches"), contents_only=True),
|
||||
]
|
||||
|
||||
# ------------------------------------------------------------- Логи ---------
|
||||
|
||||
LOG_RULES: list[Rule] = [
|
||||
Rule("log.windows", "Системные журналы Windows", C.LOGS, R.LOW,
|
||||
"C:\\Windows\\Logs — логи CBS, DISM, обслуживания компонентов.",
|
||||
("{WINDIR}\\Logs\\CBS", "{WINDIR}\\Logs\\DISM", "{WINDIR}\\Logs\\MoSetup",
|
||||
"{WINDIR}\\Logs\\WindowsUpdate"), contents_only=True, needs_admin=True),
|
||||
Rule("log.perflogs", "PerfLogs", C.LOGS, R.SAFE,
|
||||
"Отчёты монитора производительности.",
|
||||
("{SYSTEMDRIVE}PerfLogs",), contents_only=True, needs_admin=True),
|
||||
Rule("log.appdata", "Логи приложений в AppData", C.LOGS, R.SAFE,
|
||||
"Каталоги logs/ внутри данных установленных программ.",
|
||||
("{ROAMING}\\*\\logs", "{LOCAL}\\*\\logs", "{LOCAL}\\*\\log"),
|
||||
contents_only=True, min_size=2 * 1024 * 1024),
|
||||
Rule("log.npm", "Логи npm/yarn", C.LOGS, R.SAFE,
|
||||
"_logs со stack trace неудачных установок пакетов.",
|
||||
("{LOCAL}\\npm-cache\\_logs", "{ROAMING}\\npm-cache\\_logs"), contents_only=True),
|
||||
Rule("log.nvidia", "Логи и кеш NVIDIA", C.LOGS, R.SAFE,
|
||||
"Отчёты драйвера и телеметрии GeForce Experience.",
|
||||
("{PROGRAMDATA}\\NVIDIA Corporation\\NvTelemetry",
|
||||
"{LOCAL}\\NVIDIA Corporation\\NvTelemetry",
|
||||
"{PROGRAMDATA}\\NVIDIA Corporation\\Downloader"), contents_only=True),
|
||||
]
|
||||
|
||||
# ---------------------------------------------------------- Браузеры --------
|
||||
|
||||
_CHROMIUM = [
|
||||
("Google Chrome", "{LOCAL}\\Google\\Chrome\\User Data", "chrome.exe"),
|
||||
("Google Chrome Beta", "{LOCAL}\\Google\\Chrome Beta\\User Data", "chrome.exe"),
|
||||
("Microsoft Edge", "{LOCAL}\\Microsoft\\Edge\\User Data", "msedge.exe"),
|
||||
("Brave", "{LOCAL}\\BraveSoftware\\Brave-Browser\\User Data", "brave.exe"),
|
||||
("Opera", "{ROAMING}\\Opera Software\\Opera Stable", "opera.exe"),
|
||||
("Opera GX", "{ROAMING}\\Opera Software\\Opera GX Stable", "opera.exe"),
|
||||
("Vivaldi", "{LOCAL}\\Vivaldi\\User Data", "vivaldi.exe"),
|
||||
("Yandex", "{LOCAL}\\Yandex\\YandexBrowser\\User Data", "browser.exe"),
|
||||
("Chromium", "{LOCAL}\\Chromium\\User Data", "chromium.exe"),
|
||||
]
|
||||
|
||||
_CHROMIUM_CACHES = [
|
||||
("Cache\\Cache_Data", "HTTP-кеш страниц", R.SAFE),
|
||||
("Code Cache", "Скомпилированный JavaScript", R.SAFE),
|
||||
("GPUCache", "Кеш GPU-шейдеров", R.SAFE),
|
||||
("ShaderCache", "Кеш шейдеров", R.SAFE),
|
||||
("GrShaderCache", "Кеш шейдеров Skia", R.SAFE),
|
||||
("DawnCache", "Кеш WebGPU", R.SAFE),
|
||||
("DawnGraphiteCache", "Кеш WebGPU (Graphite)", R.SAFE),
|
||||
("DawnWebGPUCache", "Кеш WebGPU", R.SAFE),
|
||||
("Service Worker\\CacheStorage", "Кеш service worker'ов сайтов", R.LOW),
|
||||
("Service Worker\\ScriptCache", "Скрипты service worker'ов", R.LOW),
|
||||
("Application Cache", "Устаревший AppCache", R.SAFE),
|
||||
("Media Cache", "Кеш видео и аудио", R.SAFE),
|
||||
("File System", "Sandboxed FileSystem API сайтов", R.MEDIUM),
|
||||
("IndexedDB", "Локальные базы сайтов (офлайн-данные)", R.MEDIUM),
|
||||
]
|
||||
|
||||
|
||||
def _browser_rules() -> list[Rule]:
|
||||
out: list[Rule] = []
|
||||
for name, root, proc in _CHROMIUM:
|
||||
for sub, desc, risk in _CHROMIUM_CACHES:
|
||||
out.append(Rule(
|
||||
f"br.{name.lower().replace(' ', '')}.{sub.split(chr(92))[0].lower().replace(' ', '')}",
|
||||
f"{name} — {desc}",
|
||||
C.BROWSERS, risk,
|
||||
f"{desc}. Профили: все найденные. Браузер лучше закрыть перед очисткой.",
|
||||
(f"{root}\\*\\{sub}", f"{root}\\{sub}"),
|
||||
contents_only=True, processes=(proc,), min_size=256 * 1024,
|
||||
))
|
||||
out.append(Rule(
|
||||
f"br.{name.lower().replace(' ', '')}.crashpad",
|
||||
f"{name} — отчёты о падениях",
|
||||
C.BROWSERS, R.SAFE, "Crashpad-дампы браузера.",
|
||||
(f"{root}\\Crashpad\\reports", f"{root}\\Crashpad\\completed"),
|
||||
contents_only=True, processes=(proc,),
|
||||
))
|
||||
out += [
|
||||
Rule("br.firefox.cache", "Firefox — кеш", C.BROWSERS, R.SAFE,
|
||||
"cache2 всех профилей Firefox.",
|
||||
("{LOCAL}\\Mozilla\\Firefox\\Profiles\\*\\cache2",
|
||||
"{LOCAL}\\Mozilla\\Firefox\\Profiles\\*\\startupCache",
|
||||
"{LOCAL}\\Mozilla\\Firefox\\Profiles\\*\\shader-cache",
|
||||
"{LOCAL}\\Mozilla\\Firefox\\Profiles\\*\\thumbnails"),
|
||||
contents_only=True, processes=("firefox.exe",)),
|
||||
Rule("br.firefox.crash", "Firefox — отчёты о падениях", C.BROWSERS, R.SAFE,
|
||||
"Minidump'ы Mozilla Crash Reporter.",
|
||||
("{ROAMING}\\Mozilla\\Firefox\\Crash Reports",), contents_only=True),
|
||||
Rule("br.tor.cache", "Tor Browser — кеш", C.BROWSERS, R.SAFE,
|
||||
"Кеш профиля Tor Browser.",
|
||||
("{ROAMING}\\tor-browser\\*\\cache2",), contents_only=True),
|
||||
]
|
||||
return out
|
||||
|
||||
|
||||
BROWSER_RULES = _browser_rules()
|
||||
|
||||
# ----------------------------------------------- Кеши инструментов разработки -
|
||||
|
||||
DEV_CACHE_RULES: list[Rule] = [
|
||||
# --- JavaScript ---
|
||||
Rule("dev.npm", "npm — глобальный кеш пакетов", C.DEV_CACHE, R.LOW,
|
||||
"_cacache. npm скачает пакеты заново при следующей установке.",
|
||||
("{LOCAL}\\npm-cache\\_cacache", "{ROAMING}\\npm-cache\\_cacache"), contents_only=True),
|
||||
Rule("dev.yarn", "Yarn — кеш пакетов", C.DEV_CACHE, R.LOW,
|
||||
"Глобальный кеш Yarn 1.x и Berry.",
|
||||
("{LOCAL}\\Yarn\\Cache", "{LOCAL}\\Yarn\\Berry\\cache", "{HOME}\\.yarn\\berry\\cache"),
|
||||
contents_only=True),
|
||||
Rule("dev.pnpm", "pnpm — content-addressable store", C.DEV_CACHE, R.MEDIUM,
|
||||
"Общее хранилище пакетов pnpm. После удаления все проекты потребуют pnpm install.",
|
||||
("{LOCAL}\\pnpm\\store", "{LOCAL}\\pnpm-store", "{HOME}\\.pnpm-store"), contents_only=True),
|
||||
Rule("dev.bun", "Bun — кеш установок", C.DEV_CACHE, R.LOW,
|
||||
"Кеш менеджера пакетов Bun.",
|
||||
("{LOCAL}\\bun\\install\\cache", "{HOME}\\.bun\\install\\cache"), contents_only=True),
|
||||
Rule("dev.deno", "Deno — кеш модулей", C.DEV_CACHE, R.LOW,
|
||||
"Скачанные удалённые модули и скомпилированный код.",
|
||||
("{LOCAL}\\deno", "{HOME}\\.deno"), contents_only=True),
|
||||
Rule("dev.node.gyp", "node-gyp — заголовки Node", C.DEV_CACHE, R.SAFE,
|
||||
"Исходники Node для сборки нативных модулей.",
|
||||
("{LOCAL}\\node-gyp\\Cache", "{HOME}\\.node-gyp"), contents_only=True),
|
||||
Rule("dev.electron", "Electron / electron-builder — кеш", C.DEV_CACHE, R.LOW,
|
||||
"Скачанные бинарники Electron и распакованные зависимости сборщика.",
|
||||
("{LOCAL}\\electron\\Cache", "{LOCAL}\\electron-builder\\Cache",
|
||||
"{LOCAL}\\electron-builder\\cache"), contents_only=True),
|
||||
Rule("dev.puppeteer", "Puppeteer / Playwright — браузеры", C.DEV_CACHE, R.MEDIUM,
|
||||
"Скачанные сборки Chromium/Firefox/WebKit для e2e-тестов. Обычно 1–3 ГБ.",
|
||||
("{LOCAL}\\ms-playwright", "{HOME}\\.cache\\puppeteer", "{LOCAL}\\puppeteer"),
|
||||
contents_only=True),
|
||||
Rule("dev.cypress", "Cypress — кеш бинарников", C.DEV_CACHE, R.LOW,
|
||||
"Каждая версия Cypress весит ~500 МБ и остаётся навсегда.",
|
||||
("{LOCAL}\\Cypress\\Cache",), contents_only=True),
|
||||
|
||||
# --- Python ---
|
||||
Rule("dev.pip", "pip — кеш колёс и загрузок", C.DEV_CACHE, R.SAFE,
|
||||
"Скачанные wheel/sdist. Восстанавливается при следующей установке.",
|
||||
("{LOCAL}\\pip\\Cache", "{HOME}\\.cache\\pip"), contents_only=True),
|
||||
Rule("dev.poetry", "Poetry — кеш", C.DEV_CACHE, R.LOW,
|
||||
"Артефакты и виртуальные окружения, созданные Poetry.",
|
||||
("{LOCAL}\\pypoetry\\Cache\\cache", "{LOCAL}\\pypoetry\\Cache\\artifacts"),
|
||||
contents_only=True),
|
||||
Rule("dev.uv", "uv — кеш пакетов", C.DEV_CACHE, R.SAFE,
|
||||
"Кеш быстрого установщика uv.",
|
||||
("{LOCAL}\\uv\\cache", "{HOME}\\.cache\\uv"), contents_only=True),
|
||||
Rule("dev.conda", "Conda — распакованные пакеты", C.DEV_CACHE, R.MEDIUM,
|
||||
"pkgs/ занимает десятки ГБ. Безопаснее `conda clean -a`, но каталог можно чистить и вручную.",
|
||||
("{HOME}\\anaconda3\\pkgs", "{HOME}\\miniconda3\\pkgs", "{HOME}\\.conda\\pkgs"),
|
||||
contents_only=True),
|
||||
Rule("dev.pyinstaller", "PyInstaller — кеш сборок", C.DEV_CACHE, R.SAFE,
|
||||
"Промежуточные бинарники упаковщика.",
|
||||
("{ROAMING}\\pyinstaller",), contents_only=True),
|
||||
|
||||
# --- .NET / Java / Rust / Go ---
|
||||
Rule("dev.nuget", "NuGet — глобальные пакеты", C.DEV_CACHE, R.MEDIUM,
|
||||
"~/.nuget/packages. Все .NET-проекты потребуют restore после очистки.",
|
||||
("{HOME}\\.nuget\\packages",), contents_only=True),
|
||||
Rule("dev.nuget.http", "NuGet — HTTP-кеш и temp", C.DEV_CACHE, R.SAFE,
|
||||
"Промежуточный кеш скачивания, восстанавливается сам.",
|
||||
("{LOCAL}\\NuGet\\v3-cache", "{LOCAL}\\NuGet\\plugins-cache", "{LOCAL}\\Temp\\NuGetScratch"),
|
||||
contents_only=True),
|
||||
Rule("dev.maven", "Maven — локальный репозиторий", C.DEV_CACHE, R.MEDIUM,
|
||||
"~/.m2/repository. Часто десятки ГБ; при сборке скачается заново.",
|
||||
("{HOME}\\.m2\\repository",), contents_only=True),
|
||||
Rule("dev.gradle", "Gradle — кеши и дистрибутивы", C.DEV_CACHE, R.MEDIUM,
|
||||
"caches/ и wrapper/dists — один из самых крупных пожирателей места у Android-разработчиков.",
|
||||
("{HOME}\\.gradle\\caches", "{HOME}\\.gradle\\wrapper\\dists",
|
||||
"{HOME}\\.gradle\\daemon", "{HOME}\\.gradle\\native"), contents_only=True),
|
||||
Rule("dev.cargo", "Cargo — реестр и исходники крейтов", C.DEV_CACHE, R.LOW,
|
||||
"registry/cache, registry/src и git/checkouts. Восстанавливаются при сборке.",
|
||||
("{HOME}\\.cargo\\registry\\cache", "{HOME}\\.cargo\\registry\\src",
|
||||
"{HOME}\\.cargo\\git\\checkouts", "{HOME}\\.cargo\\git\\db"), contents_only=True),
|
||||
Rule("dev.gomod", "Go — кеш модулей и сборки", C.DEV_CACHE, R.LOW,
|
||||
"GOMODCACHE/download и GOCACHE. Модули read-only — потребуется `go clean -modcache`, "
|
||||
"если обычное удаление не пройдёт.",
|
||||
("{HOME}\\go\\pkg\\mod\\cache\\download", "{LOCAL}\\go-build"), contents_only=True),
|
||||
Rule("dev.sdkman", "Скачанные JDK / SDK", C.DEV_CACHE, R.MEDIUM,
|
||||
"Архивы и распакованные SDK, которые обычно уже не используются.",
|
||||
("{LOCAL}\\Temurin", "{HOME}\\.jdks", "{HOME}\\.sdkman\\archives"), contents_only=True),
|
||||
|
||||
# --- Mobile / Game / прочее ---
|
||||
Rule("dev.android.sdk", "Android SDK — временные каталоги", C.DEV_CACHE, R.LOW,
|
||||
"Кеш SDK-менеджера и загрузок.",
|
||||
("{LOCAL}\\Android\\Sdk\\.temp", "{LOCAL}\\Android\\Sdk\\.downloadIntermediates",
|
||||
"{HOME}\\.android\\cache", "{HOME}\\.android\\build-cache"), contents_only=True),
|
||||
Rule("dev.android.emulator", "Образы эмулятора Android", C.DEV_CACHE, R.HIGH,
|
||||
"system-images и созданные AVD. Каждое устройство — несколько ГБ. "
|
||||
"Удаляйте только те, которыми точно не пользуетесь.",
|
||||
("{LOCAL}\\Android\\Sdk\\system-images\\*", "{HOME}\\.android\\avd\\*"),
|
||||
min_size=200 * 1024 * 1024),
|
||||
Rule("dev.flutter", "Flutter / Dart — pub cache", C.DEV_CACHE, R.MEDIUM,
|
||||
"Скачанные пакеты Dart и артефакты движка Flutter.",
|
||||
("{LOCAL}\\Pub\\Cache\\hosted", "{LOCAL}\\Pub\\Cache\\git", "{HOME}\\.pub-cache\\hosted"),
|
||||
contents_only=True),
|
||||
Rule("dev.composer", "Composer — кеш PHP-пакетов", C.DEV_CACHE, R.SAFE,
|
||||
"Скачанные zip-архивы и метаданные packagist.",
|
||||
("{LOCAL}\\Composer\\files", "{LOCAL}\\Composer\\repo", "{ROAMING}\\Composer\\cache"),
|
||||
contents_only=True),
|
||||
Rule("dev.ruby", "RubyGems / Bundler — кеш", C.DEV_CACHE, R.LOW,
|
||||
"Скачанные .gem-архивы.",
|
||||
("{LOCAL}\\gem\\cache", "{HOME}\\.bundle\\cache", "{HOME}\\.gem\\cache"),
|
||||
contents_only=True),
|
||||
Rule("dev.terraform", "Terraform — кеш плагинов", C.DEV_CACHE, R.LOW,
|
||||
"Скачанные провайдеры (каждый — сотни МБ).",
|
||||
("{ROAMING}\\terraform.d\\plugin-cache", "{LOCAL}\\terraform.d"), contents_only=True),
|
||||
Rule("dev.helm", "Helm / Kubernetes — кеш", C.DEV_CACHE, R.SAFE,
|
||||
"Кеш репозиториев чартов.",
|
||||
("{LOCAL}\\helm\\repository\\cache", "{LOCAL}\\Temp\\helm"), contents_only=True),
|
||||
Rule("dev.vcpkg", "vcpkg / Conan — кеш сборок", C.DEV_CACHE, R.MEDIUM,
|
||||
"Бинарные кеши C++-зависимостей. Пересборка может занять часы.",
|
||||
("{LOCAL}\\vcpkg\\archives", "{LOCAL}\\vcpkg\\downloads", "{HOME}\\.conan\\data",
|
||||
"{HOME}\\.conan2\\p"), contents_only=True),
|
||||
Rule("dev.ccache", "ccache / sccache", C.DEV_CACHE, R.LOW,
|
||||
"Кеш компилятора C/C++. Ускоряет пересборку, но безопасно удаляется.",
|
||||
("{LOCAL}\\ccache", "{LOCAL}\\Mozilla\\sccache", "{HOME}\\.ccache"), contents_only=True),
|
||||
Rule("dev.unity.global", "Unity — глобальные кеши", C.DEV_CACHE, R.MEDIUM,
|
||||
"Asset Pipeline cache, кеш пакетов и загрузок Unity Hub.",
|
||||
("{LOCAL}\\Unity\\cache", "{ROAMING}\\Unity\\cache", "{LOCAL}\\Unity\\Caches",
|
||||
"{ROAMING}\\UnityHub\\Caches"), contents_only=True),
|
||||
Rule("dev.unreal", "Unreal Engine — DDC", C.DEV_CACHE, R.MEDIUM,
|
||||
"Derived Data Cache. Легко занимает 50+ ГБ; пересобирается долго.",
|
||||
("{LOCAL}\\UnrealEngine\\Common\\DerivedDataCache",
|
||||
"{LOCAL}\\UnrealEngine\\*\\DerivedDataCache"), contents_only=True),
|
||||
Rule("dev.docker", "Docker Desktop — логи и кеш", C.DEV_CACHE, R.LOW,
|
||||
"Логи и служебный кеш. Образы хранятся в WSL-диске — их чистят через `docker system prune`.",
|
||||
("{LOCAL}\\Docker\\log", "{ROAMING}\\Docker\\log", "{ROAMING}\\Docker Desktop\\logs"),
|
||||
contents_only=True),
|
||||
]
|
||||
|
||||
# ------------------------------------------------------------ IDE / редакторы -
|
||||
|
||||
IDE_RULES: list[Rule] = [
|
||||
Rule("ide.vscode", "VS Code — кеш и временные данные", C.DEV_CACHE, R.LOW,
|
||||
"Cache, CachedData, GPUCache, логи. Настройки и расширения не затрагиваются.",
|
||||
("{ROAMING}\\Code\\Cache", "{ROAMING}\\Code\\CachedData",
|
||||
"{ROAMING}\\Code\\CachedExtensionVSIXs", "{ROAMING}\\Code\\Code Cache",
|
||||
"{ROAMING}\\Code\\GPUCache", "{ROAMING}\\Code\\logs",
|
||||
"{ROAMING}\\Code\\User\\workspaceStorage"),
|
||||
contents_only=True, processes=("code.exe",)),
|
||||
Rule("ide.vscode.insiders", "VS Code Insiders / VSCodium — кеш", C.DEV_CACHE, R.LOW,
|
||||
"То же самое для альтернативных сборок редактора.",
|
||||
("{ROAMING}\\Code - Insiders\\Cache", "{ROAMING}\\Code - Insiders\\CachedData",
|
||||
"{ROAMING}\\VSCodium\\Cache", "{ROAMING}\\VSCodium\\CachedData"), contents_only=True),
|
||||
Rule("ide.cursor", "Cursor / Windsurf — кеш", C.DEV_CACHE, R.LOW,
|
||||
"Кеши AI-редакторов на базе VS Code.",
|
||||
("{ROAMING}\\Cursor\\Cache", "{ROAMING}\\Cursor\\CachedData",
|
||||
"{ROAMING}\\Cursor\\Code Cache", "{ROAMING}\\Cursor\\GPUCache",
|
||||
"{ROAMING}\\Windsurf\\Cache", "{ROAMING}\\Windsurf\\CachedData"),
|
||||
contents_only=True, processes=("cursor.exe",)),
|
||||
Rule("ide.jetbrains.caches", "JetBrains — индексы и кеши", C.DEV_CACHE, R.LOW,
|
||||
"Индексы IDEA/PyCharm/WebStorm и др. Перестраиваются при открытии проекта.",
|
||||
("{LOCAL}\\JetBrains\\*\\caches", "{LOCAL}\\JetBrains\\*\\index",
|
||||
"{LOCAL}\\JetBrains\\*\\tmp", "{LOCAL}\\JetBrains\\*\\log"),
|
||||
contents_only=True, processes=("idea64.exe", "pycharm64.exe", "webstorm64.exe")),
|
||||
Rule("ide.jetbrains.old", "JetBrains — данные старых версий IDE", C.DEV_CACHE, R.MEDIUM,
|
||||
"Конфигурация и кеши версий, которые давно не запускались.",
|
||||
("{ROAMING}\\JetBrains\\*",), min_size=100 * 1024 * 1024),
|
||||
Rule("ide.visualstudio", "Visual Studio — кеши", C.DEV_CACHE, R.LOW,
|
||||
"ComponentModelCache, кеш телеметрии и отладчика.",
|
||||
("{LOCAL}\\Microsoft\\VisualStudio\\*\\ComponentModelCache",
|
||||
"{LOCAL}\\Microsoft\\VisualStudio\\*\\Designer\\ShadowCache",
|
||||
"{LOCAL}\\Microsoft\\VisualStudio\\Packages\\_Instances",
|
||||
"{LOCAL}\\Microsoft\\VSCommon\\*\\SQM"),
|
||||
contents_only=True, processes=("devenv.exe",)),
|
||||
Rule("ide.vs.installer", "Visual Studio Installer — кеш дистрибутивов", C.DEV_CACHE, R.MEDIUM,
|
||||
"Скачанные пакеты установщика VS. Часто 10–20 ГБ, нужны только при изменении состава.",
|
||||
("{PROGRAMDATA}\\Microsoft\\VisualStudio\\Packages",), contents_only=True,
|
||||
needs_admin=True, min_size=200 * 1024 * 1024),
|
||||
Rule("ide.vs.backup", "Visual Studio — автосохранения и трассировки", C.DEV_CACHE, R.LOW,
|
||||
"Backup Files и ActivityLog.",
|
||||
("{LOCAL}\\Microsoft\\VisualStudio\\*\\ActivityLog.xml",
|
||||
"{HOME}\\Documents\\Visual Studio *\\Backup Files"), contents_only=True),
|
||||
Rule("ide.xamarin", "Xamarin / .NET Android — кеш", C.DEV_CACHE, R.LOW,
|
||||
"Скачанные компоненты Xamarin.",
|
||||
("{LOCAL}\\Xamarin\\zips", "{LOCAL}\\Xamarin\\Cache"), contents_only=True),
|
||||
Rule("ide.eclipse", "Eclipse / NetBeans — кеш", C.DEV_CACHE, R.LOW,
|
||||
"Метаданные рабочих областей и индексы.",
|
||||
("{ROAMING}\\NetBeans\\*\\var\\cache", "{HOME}\\.eclipse\\*\\configuration\\org.eclipse.osgi"),
|
||||
contents_only=True),
|
||||
]
|
||||
|
||||
# ------------------------------------------------------------ Приложения ----
|
||||
|
||||
APP_RULES: list[Rule] = [
|
||||
Rule("app.discord", "Discord — кеш", C.APPS, R.SAFE,
|
||||
"Cache, Code Cache, GPUCache клиента Discord.",
|
||||
("{ROAMING}\\discord\\Cache", "{ROAMING}\\discord\\Code Cache",
|
||||
"{ROAMING}\\discord\\GPUCache", "{ROAMING}\\discordptb\\Cache",
|
||||
"{ROAMING}\\discordcanary\\Cache"),
|
||||
contents_only=True, processes=("discord.exe",)),
|
||||
Rule("app.slack", "Slack — кеш", C.APPS, R.SAFE,
|
||||
"Кеш сообщений и вложений Slack.",
|
||||
("{ROAMING}\\Slack\\Cache", "{ROAMING}\\Slack\\Code Cache",
|
||||
"{ROAMING}\\Slack\\GPUCache", "{ROAMING}\\Slack\\Service Worker\\CacheStorage"),
|
||||
contents_only=True, processes=("slack.exe",)),
|
||||
Rule("app.teams", "Microsoft Teams — кеш", C.APPS, R.LOW,
|
||||
"Кеш классического и нового клиента Teams.",
|
||||
("{ROAMING}\\Microsoft\\Teams\\Cache",
|
||||
"{ROAMING}\\Microsoft\\Teams\\Code Cache",
|
||||
"{ROAMING}\\Microsoft\\Teams\\GPUCache",
|
||||
"{ROAMING}\\Microsoft\\Teams\\Service Worker\\CacheStorage",
|
||||
"{LOCAL}\\Packages\\MSTeams_*\\LocalCache"),
|
||||
contents_only=True, processes=("ms-teams.exe", "teams.exe")),
|
||||
Rule("app.telegram", "Telegram Desktop — кеш медиа", C.APPS, R.LOW,
|
||||
"Скачанные фото и видео. При необходимости подтянутся с сервера заново.",
|
||||
("{ROAMING}\\Telegram Desktop\\tdata\\user_data\\cache",
|
||||
"{ROAMING}\\Telegram Desktop\\tdata\\user_data\\media_cache",
|
||||
"{ROAMING}\\Telegram Desktop\\tdata\\emoji"),
|
||||
contents_only=True, processes=("telegram.exe",)),
|
||||
Rule("app.spotify", "Spotify — кеш треков", C.APPS, R.SAFE,
|
||||
"Локальный кеш прослушанной музыки.",
|
||||
("{LOCAL}\\Spotify\\Data", "{LOCAL}\\Spotify\\Storage",
|
||||
"{ROAMING}\\Spotify\\Data"), contents_only=True, processes=("spotify.exe",)),
|
||||
Rule("app.steam", "Steam — кеш и логи", C.APPS, R.LOW,
|
||||
"htmlcache, shadercache, логи и незавершённые загрузки.",
|
||||
("{LOCAL}\\Steam\\htmlcache", "{PROGRAMFILES86}\\Steam\\logs",
|
||||
"{PROGRAMFILES86}\\Steam\\appcache\\httpcache",
|
||||
"{PROGRAMFILES86}\\Steam\\steamapps\\shadercache",
|
||||
"{PROGRAMFILES86}\\Steam\\steamapps\\temp",
|
||||
"{PROGRAMFILES86}\\Steam\\steamapps\\downloading"),
|
||||
contents_only=True, processes=("steam.exe",)),
|
||||
Rule("app.epic", "Epic Games — webcache", C.APPS, R.SAFE,
|
||||
"Кеш встроенного браузера лаунчера.",
|
||||
("{LOCAL}\\EpicGamesLauncher\\Saved\\webcache",
|
||||
"{LOCAL}\\EpicGamesLauncher\\Saved\\webcache_*",
|
||||
"{LOCAL}\\EpicGamesLauncher\\Saved\\Logs"), contents_only=True),
|
||||
Rule("app.battlenet", "Battle.net — кеш", C.APPS, R.SAFE,
|
||||
"Кеш агента обновлений Blizzard.",
|
||||
("{ROAMING}\\Battle.net\\Cache", "{PROGRAMDATA}\\Battle.net\\Agent\\data"),
|
||||
contents_only=True),
|
||||
Rule("app.origin", "EA / Origin — кеш", C.APPS, R.SAFE,
|
||||
"Кеш лаунчеров EA.",
|
||||
("{ROAMING}\\Origin\\Cache", "{LOCAL}\\Origin", "{LOCAL}\\Electronic Arts\\EA Desktop\\cache"),
|
||||
contents_only=True),
|
||||
Rule("app.adobe", "Adobe — медиакеш", C.APPS, R.LOW,
|
||||
"Media Cache Files Premiere/After Effects. Пересоздаётся при открытии проекта, "
|
||||
"но первый предпросмотр будет медленнее.",
|
||||
("{ROAMING}\\Adobe\\Common\\Media Cache Files",
|
||||
"{ROAMING}\\Adobe\\Common\\Media Cache",
|
||||
"{ROAMING}\\Adobe\\Common\\Peak Files",
|
||||
"{LOCAL}\\Adobe\\*\\Cache"), contents_only=True),
|
||||
Rule("app.obs", "OBS Studio — логи и профили сбоев", C.APPS, R.SAFE,
|
||||
"Логи трансляций и crash-репорты.",
|
||||
("{ROAMING}\\obs-studio\\logs", "{ROAMING}\\obs-studio\\crashes"), contents_only=True),
|
||||
Rule("app.zoom", "Zoom — данные и логи", C.APPS, R.LOW,
|
||||
"Кеш конференций и логи клиента.",
|
||||
("{ROAMING}\\Zoom\\logs", "{ROAMING}\\Zoom\\data"), contents_only=True),
|
||||
Rule("app.office", "Microsoft Office — кеш документов", C.APPS, R.LOW,
|
||||
"Кеш облачных документов Office. Несинхронизированные правки будут потеряны.",
|
||||
("{LOCAL}\\Microsoft\\Office\\*\\OfficeFileCache",
|
||||
"{LOCAL}\\Microsoft\\Office\\*\\WebServiceCache"), contents_only=True,
|
||||
processes=("winword.exe", "excel.exe")),
|
||||
Rule("app.onedrive", "OneDrive — логи", C.APPS, R.SAFE,
|
||||
"Телеметрия и логи синхронизации.",
|
||||
("{LOCAL}\\Microsoft\\OneDrive\\logs",), contents_only=True),
|
||||
Rule("app.nvidia.cache", "NVIDIA — кеш шейдеров", C.APPS, R.SAFE,
|
||||
"DXCache / GLCache / NV_Cache. Пересобирается играми автоматически.",
|
||||
("{LOCAL}\\NVIDIA\\DXCache", "{LOCAL}\\NVIDIA\\GLCache",
|
||||
"{LOCAL}\\NVIDIA Corporation\\NV_Cache", "{LOCAL}\\NVIDIA\\ComputeCache"),
|
||||
contents_only=True),
|
||||
Rule("app.amd.cache", "AMD — кеш шейдеров", C.APPS, R.SAFE,
|
||||
"DxCache и GLCache драйвера AMD.",
|
||||
("{LOCAL}\\AMD\\DxCache", "{LOCAL}\\AMD\\GLCache", "{LOCAL}\\AMD\\DxcCache"),
|
||||
contents_only=True),
|
||||
Rule("app.electron.generic", "Прочие Electron-приложения — кеш", C.APPS, R.LOW,
|
||||
"Автоматически найденные каталоги Cache/GPUCache в данных установленных приложений.",
|
||||
("{ROAMING}\\*\\Cache\\Cache_Data", "{ROAMING}\\*\\GPUCache",
|
||||
"{ROAMING}\\*\\Code Cache\\js", "{LOCAL}\\*\\GPUCache"),
|
||||
contents_only=True, min_size=10 * 1024 * 1024),
|
||||
]
|
||||
|
||||
# ------------------------------------------------------ Пакетные менеджеры --
|
||||
|
||||
PKG_RULES: list[Rule] = [
|
||||
Rule("pkg.chocolatey", "Chocolatey — кеш загрузок", C.PACKAGE_MANAGERS, R.SAFE,
|
||||
"Скачанные установщики пакетов choco.",
|
||||
("{LOCAL}\\Temp\\chocolatey", "{PROGRAMDATA}\\chocolatey\\lib-bkp"), contents_only=True),
|
||||
Rule("pkg.scoop", "Scoop — кеш и старые версии", C.PACKAGE_MANAGERS, R.LOW,
|
||||
"cache/ с архивами и apps/*/старые версии приложений.",
|
||||
("{HOME}\\scoop\\cache", "{PROGRAMDATA}\\scoop\\cache"), contents_only=True),
|
||||
Rule("pkg.winget", "winget — кеш установщиков", C.PACKAGE_MANAGERS, R.SAFE,
|
||||
"Временные файлы Windows Package Manager.",
|
||||
("{LOCAL}\\Packages\\Microsoft.DesktopAppInstaller_*\\LocalState\\TempState",
|
||||
"{LOCAL}\\Temp\\WinGet"), contents_only=True),
|
||||
Rule("pkg.msi.cache", "Кеш загруженных установщиков", C.PACKAGE_MANAGERS, R.LOW,
|
||||
"Package Cache — дистрибутивы Visual C++, .NET и подобных бандлов.",
|
||||
("{PROGRAMDATA}\\Package Cache",), contents_only=True, needs_admin=True,
|
||||
min_size=100 * 1024 * 1024),
|
||||
]
|
||||
|
||||
# ------------------------------------------- Артефакты внутри проектов ------
|
||||
#
|
||||
# Их ищет devscan.py: рекурсивный обход выбранных каталогов.
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ProjectRule:
|
||||
name: str # имя каталога/файла-артефакта
|
||||
title: str
|
||||
risk: Risk
|
||||
detail: str
|
||||
marker: tuple[str, ...] = () # файлы рядом, подтверждающие тип проекта
|
||||
inner: tuple[str, ...] = () # файлы внутри каталога, подтверждающие находку
|
||||
stop: bool = True # не заходить внутрь найденного каталога
|
||||
ecosystem: str = ""
|
||||
|
||||
|
||||
PROJECT_RULES: tuple[ProjectRule, ...] = (
|
||||
ProjectRule("node_modules", "node_modules", R.LOW,
|
||||
"Зависимости Node. Восстанавливаются командой npm/yarn/pnpm install.",
|
||||
("package.json",), stop=True, ecosystem="JavaScript"),
|
||||
ProjectRule(".next", "Сборка Next.js", R.SAFE,
|
||||
"Кеш и артефакты сборки Next.js.", ("package.json",), ecosystem="JavaScript"),
|
||||
ProjectRule(".nuxt", "Сборка Nuxt", R.SAFE, "Артефакты Nuxt.", ("package.json",),
|
||||
ecosystem="JavaScript"),
|
||||
ProjectRule(".output", "Вывод Nitro/Nuxt", R.SAFE, "Собранный сервер Nitro.",
|
||||
("package.json",), ecosystem="JavaScript"),
|
||||
ProjectRule(".turbo", "Кеш Turborepo", R.SAFE, "Кеш задач Turborepo.", ("package.json",),
|
||||
ecosystem="JavaScript"),
|
||||
ProjectRule(".parcel-cache", "Кеш Parcel", R.SAFE, "Кеш бандлера Parcel.", ("package.json",),
|
||||
ecosystem="JavaScript"),
|
||||
ProjectRule(".angular", "Кеш Angular CLI", R.SAFE, "Кеш сборки Angular.", ("angular.json",),
|
||||
ecosystem="JavaScript"),
|
||||
ProjectRule(".svelte-kit", "Сборка SvelteKit", R.SAFE, "Артефакты SvelteKit.",
|
||||
("package.json",), ecosystem="JavaScript"),
|
||||
ProjectRule(".astro", "Кеш Astro", R.SAFE, "Служебные типы и кеш Astro.", ("package.json",),
|
||||
ecosystem="JavaScript"),
|
||||
ProjectRule(".docusaurus", "Кеш Docusaurus", R.SAFE, "Кеш генератора документации.",
|
||||
("package.json",), ecosystem="JavaScript"),
|
||||
ProjectRule("storybook-static", "Сборка Storybook", R.SAFE, "Статическая сборка Storybook.",
|
||||
("package.json",), ecosystem="JavaScript"),
|
||||
ProjectRule("coverage", "Отчёты о покрытии", R.SAFE, "Результаты прогона тестов.",
|
||||
(), ecosystem="Тесты"),
|
||||
ProjectRule(".nyc_output", "Сырые данные покрытия", R.SAFE, "Промежуточные данные nyc.",
|
||||
(), ecosystem="Тесты"),
|
||||
ProjectRule("__pycache__", "Байт-код Python", R.SAFE,
|
||||
"Скомпилированные .pyc. Пересоздаются при запуске.", (), ecosystem="Python"),
|
||||
ProjectRule(".pytest_cache", "Кеш pytest", R.SAFE, "Кеш последнего прогона тестов.",
|
||||
(), ecosystem="Python"),
|
||||
ProjectRule(".mypy_cache", "Кеш mypy", R.SAFE, "Инкрементальный кеш проверки типов.",
|
||||
(), ecosystem="Python"),
|
||||
ProjectRule(".ruff_cache", "Кеш ruff", R.SAFE, "Кеш линтера ruff.", (), ecosystem="Python"),
|
||||
ProjectRule(".tox", "Окружения tox", R.LOW, "Виртуальные окружения матрицы тестов.",
|
||||
(), ecosystem="Python"),
|
||||
ProjectRule(".venv", "Виртуальное окружение", R.MEDIUM,
|
||||
"Пересоздаётся из requirements.txt / pyproject.toml, но не мгновенно.",
|
||||
(), inner=("pyvenv.cfg",), ecosystem="Python"),
|
||||
ProjectRule("venv", "Виртуальное окружение", R.MEDIUM,
|
||||
"Пересоздаётся из requirements.txt / pyproject.toml.",
|
||||
(), inner=("pyvenv.cfg",), ecosystem="Python"),
|
||||
ProjectRule("env", "Виртуальное окружение", R.MEDIUM,
|
||||
"Пересоздаётся из requirements.txt / pyproject.toml.",
|
||||
(), inner=("pyvenv.cfg",), ecosystem="Python"),
|
||||
ProjectRule(".conda", "Окружение conda в проекте", R.MEDIUM,
|
||||
"Локальное окружение conda.", (), inner=("conda-meta",), ecosystem="Python"),
|
||||
ProjectRule(".ipynb_checkpoints", "Чекпоинты Jupyter", R.SAFE, "Автосохранения ноутбуков.",
|
||||
(), ecosystem="Python"),
|
||||
ProjectRule("target", "Сборка Rust / Maven", R.LOW,
|
||||
"Артефакты cargo build или Maven. Пересборка может занять минуты.",
|
||||
("Cargo.toml", "pom.xml"), ecosystem="Rust/Java"),
|
||||
ProjectRule("bin", "Сборка .NET (bin)", R.LOW, "Выходные файлы сборки .NET.",
|
||||
("*.csproj", "*.sln", "*.fsproj", "*.vbproj"), ecosystem=".NET"),
|
||||
ProjectRule("obj", "Промежуточные файлы .NET", R.SAFE, "Объектные файлы сборки .NET.",
|
||||
("*.csproj", "*.sln", "*.fsproj", "*.vbproj"), ecosystem=".NET"),
|
||||
ProjectRule(".vs", "Служебный каталог Visual Studio", R.SAFE,
|
||||
"Кеш IntelliSense и состояние решения.", (), ecosystem=".NET"),
|
||||
ProjectRule("build", "Каталог сборки", R.LOW,
|
||||
"Выход CMake/Gradle/Flutter. Убедитесь, что это не исходники.",
|
||||
("CMakeLists.txt", "build.gradle", "build.gradle.kts", "pubspec.yaml",
|
||||
"package.json", "setup.py", "pyproject.toml"), ecosystem="Сборка"),
|
||||
ProjectRule("cmake-build-debug", "Сборка CMake (Debug)", R.SAFE, "Каталог сборки CLion.",
|
||||
(), ecosystem="C/C++"),
|
||||
ProjectRule("cmake-build-release", "Сборка CMake (Release)", R.SAFE, "Каталог сборки CLion.",
|
||||
(), ecosystem="C/C++"),
|
||||
ProjectRule("CMakeFiles", "Служебные файлы CMake", R.SAFE, "Промежуточные файлы генератора.",
|
||||
(), ecosystem="C/C++"),
|
||||
ProjectRule(".gradle", "Кеш Gradle в проекте", R.SAFE, "Локальный кеш задач Gradle.",
|
||||
(), ecosystem="Java/Android"),
|
||||
ProjectRule(".dart_tool", "Служебные файлы Dart", R.SAFE, "Кеш пакетов и сборки Dart.",
|
||||
("pubspec.yaml",), ecosystem="Flutter"),
|
||||
ProjectRule("Pods", "CocoaPods", R.LOW, "Зависимости iOS-проекта.", (), ecosystem="Mobile"),
|
||||
ProjectRule("vendor", "Зависимости Composer/Go/Bundler", R.LOW,
|
||||
"Восстанавливается composer install / bundle install.",
|
||||
("composer.json", "Gemfile", "go.mod"), ecosystem="PHP/Ruby/Go"),
|
||||
ProjectRule("Library", "Кеш проекта Unity", R.LOW,
|
||||
"Импортированные ассеты Unity. Перегенерируется при открытии проекта (долго).",
|
||||
("Assets", "ProjectSettings"), inner=("ArtifactDB", "ScriptAssemblies",
|
||||
"PackageCache"), ecosystem="Unity"),
|
||||
ProjectRule("Intermediate", "Промежуточные файлы Unreal", R.SAFE,
|
||||
"Артефакты компиляции Unreal Engine.", (), ecosystem="Unreal"),
|
||||
ProjectRule("DerivedDataCache", "DDC проекта Unreal", R.LOW,
|
||||
"Производные данные ассетов Unreal.", (), ecosystem="Unreal"),
|
||||
ProjectRule(".terraform", "Плагины Terraform в проекте", R.LOW,
|
||||
"Скачанные провайдеры. Восстанавливается terraform init.", (), ecosystem="DevOps"),
|
||||
ProjectRule(".serverless", "Артефакты Serverless Framework", R.SAFE,
|
||||
"Сгенерированные пакеты деплоя.", (), ecosystem="DevOps"),
|
||||
ProjectRule(".cache", "Обобщённый кеш инструментов", R.SAFE,
|
||||
"Кеш сборщиков и линтеров внутри проекта.", (), ecosystem="Сборка"),
|
||||
ProjectRule("dist", "Каталог сборки dist", R.LOW,
|
||||
"Собранные файлы. Убедитесь, что это не исходники, которые вы коммитите.",
|
||||
("package.json", "setup.py", "pyproject.toml", "rollup.config.js", "vite.config.js",
|
||||
"vite.config.ts"), ecosystem="Сборка"),
|
||||
ProjectRule("out", "Каталог сборки out", R.LOW, "Выход сборщика.",
|
||||
("package.json", "tsconfig.json"), ecosystem="Сборка"),
|
||||
)
|
||||
|
||||
# Файлы-артефакты (не каталоги), которые ищем в проектах
|
||||
PROJECT_FILES: tuple[tuple[str, str, Risk, str], ...] = (
|
||||
("*.pyc", "Скомпилированный Python вне __pycache__", R.SAFE, "Python"),
|
||||
("npm-debug.log*", "Лог сбоя npm", R.SAFE, "JavaScript"),
|
||||
("yarn-error.log", "Лог сбоя yarn", R.SAFE, "JavaScript"),
|
||||
(".eslintcache", "Кеш ESLint", R.SAFE, "JavaScript"),
|
||||
("tsconfig.tsbuildinfo", "Инкрементальный кеш TypeScript", R.SAFE, "JavaScript"),
|
||||
("*.stackdump", "Дамп аварийного завершения", R.SAFE, "Прочее"),
|
||||
("Thumbs.db", "Кеш эскизов Windows", R.SAFE, "Прочее"),
|
||||
("desktop.ini", "", R.HIGH, ""), # намеренно не предлагаем
|
||||
)
|
||||
|
||||
# Каталоги, внутрь которых не спускаемся при поиске артефактов, даже если сам
|
||||
# каталог не подошёл ни под одно правило: внутри всё равно нет «своих» проектов.
|
||||
NEVER_DESCEND = {
|
||||
"node_modules", "__pycache__", ".git", ".svn", ".hg", "site-packages",
|
||||
"dist-packages", ".venv", "venv", ".tox", ".mypy_cache", ".pytest_cache",
|
||||
".ruff_cache", ".gradle", ".vs", ".idea", "pods", "bower_components",
|
||||
}
|
||||
|
||||
# Каталоги, в которые никогда не заходим при рекурсивном поиске
|
||||
SKIP_DIRS = {
|
||||
"$recycle.bin", "system volume information", "windows", "winsxs", "program files",
|
||||
"program files (x86)", "programdata", "$windows.~bt", "$windows.~ws", "appdata",
|
||||
"onedrive", "recovery", "boot", "perflogs", "msocache", "config.msi",
|
||||
}
|
||||
|
||||
|
||||
def all_rules() -> list[Rule]:
|
||||
return (WINDOWS_RULES + LOG_RULES + BROWSER_RULES + DEV_CACHE_RULES
|
||||
+ IDE_RULES + APP_RULES + PKG_RULES)
|
||||
|
||||
|
||||
def rules_for(categories: set[Category]) -> list[Rule]:
|
||||
return [r for r in all_rules() if r.category in categories]
|
||||
Reference in New Issue
Block a user