MinDalle_StableDiff/Python310/Lib/site-packages/cleanpy/_finder.py

90 lines
2.9 KiB
Python

import os
import re
from logging import Logger
from os import DirEntry
from typing import AbstractSet, Dict, List, Optional, Set, Tuple, cast
from ._const import (
IGNORE_DIRS,
SPHINX_BUILD_TARGET,
TARGETS,
Category,
DeleteEntry,
EntryType,
RemoveTarget,
)
from ._manipulator import DirEntryManipulator
class Finder:
def __init__(
self,
logger: Logger,
manipulator: DirEntryManipulator,
exclude_pattern: Optional[str],
include_categories: AbstractSet[str],
) -> None:
self.__logger = logger
self.__manipulator = manipulator
self.__include_categories = include_categories
self.__target_map = self.__make_target_map()
self.__exclude_pattern = re.compile(exclude_pattern) if exclude_pattern else None
self.__delete_entries: Set[DeleteEntry] = set()
logger.debug(f"exclude_pattern: {exclude_pattern}")
logger.debug(f"include_categories: {include_categories}")
def is_remove_entry(self, entry: DirEntry) -> Tuple[bool, Optional[RemoveTarget]]:
for target in self.__target_map.get(self.__manipulator.get_entry_type(entry), []):
if target.regexp.search(entry.name):
return (True, target)
if Category.BUILD in self.__include_categories:
if entry.name == "_build" and SPHINX_BUILD_TARGET.regexp.search(entry.path) is not None:
return (True, target)
return (False, None)
def is_skip_entry(self, entry: DirEntry) -> bool:
if self.__exclude_pattern and self.__exclude_pattern.search(entry.name):
self.__logger.debug(f"match exclude pattern: {entry.path}")
return True
if self.__manipulator.is_dir(entry) and entry.name in IGNORE_DIRS:
return True
return False
def get_delete_entries(self) -> AbstractSet[DeleteEntry]:
return self.__delete_entries
def traverse(self, root: str) -> AbstractSet[DeleteEntry]:
with os.scandir(root) as it:
for entry in it:
if self.is_skip_entry(entry):
self.__logger.debug(f"skip entry: {entry.path}")
continue
is_remove, remove_target = self.is_remove_entry(entry)
if is_remove:
self.__logger.debug(f"add delete target: {entry.path}")
self.__delete_entries.add((entry, cast(RemoveTarget, remove_target)))
continue
if self.__manipulator.is_dir(entry):
self.traverse(entry.path)
return self.__delete_entries
def __make_target_map(self) -> Dict[EntryType, List[RemoveTarget]]:
target_map: Dict[EntryType, List[RemoveTarget]] = {}
for target in TARGETS:
if target.category not in self.__include_categories:
continue
target_map.setdefault(target.target_type, []).append(target)
return target_map