IMG_Worker/tests/setup_clean.py

148 lines
5.8 KiB
Python

import os
import glob
import fnmatch
def clean_files_oswalk():
"""os.walk를 사용한 기존 방식 - 더 세밀한 컨트롤 가능"""
# 1. 삭제할 확장자 정의
target_extensions = ('.c', '.pyd')
# 2. 제외할 폴더 이름 (어디에 있든 이름이 일치하면 제외)
# 대소문자를 정확히 입력해주세요. 필요시 '.git', '__pycache__' 등 추가
exclude_folder_names = {
'scripts', 'build', 'Lib', '.git', '__pycache__', 'venv',
'env', '.env', '.venv', 'virtualenv', '.virtualenv',
'conda', 'miniconda', 'anaconda', 'miniforge',
'node_modules', 'dist', 'build', 'target',
'.vscode', '.idea', '__pycache__', '.pytest_cache',
'.mypy_cache', '.tox', '.coverage', '.DS_Store'
}
# 3. 제외할 특정 경로 (현재 위치 기준 상대 경로)
# 예: 'src/browsers'는 ./src/browsers 폴더 하위를 모두 제외함
exclude_specific_paths = {'src/browsers'}
# 경로 구분자 통일 (Windows '\', Mac/Linux '/' 호환성 확보)
exclude_specific_paths = {os.path.normpath(p) for p in exclude_specific_paths}
current_dir = os.getcwd() # 현재 실행 위치
print(f"작업 시작 위치: {current_dir}")
print("-" * 30)
for root, dirs, files in os.walk(current_dir):
# [중요] dirs 리스트를 제자리에서 수정(slice assignment)하여
# os.walk가 제외된 폴더로 진입하지 않도록 막습니다.
# 1차 필터링: 폴더 이름으로 제외 (예: build, Lib)
dirs[:] = [d for d in dirs if d not in exclude_folder_names]
# 2차 필터링: 특정 경로로 제외 (예: src/browsers)
allowed_dirs = []
for d in dirs:
# 현재 탐색 중인 폴더(root) + 하위 폴더(d)의 전체 경로 생성
full_path = os.path.join(root, d)
# 실행 위치 기준 상대 경로 계산
rel_path = os.path.relpath(full_path, current_dir)
# 제외할 경로 리스트에 포함되어 있는지 확인
if rel_path not in exclude_specific_paths:
allowed_dirs.append(d)
else:
print(f"[제외됨] 경로: {rel_path}")
dirs[:] = allowed_dirs
# 파일 삭제 로직
for file in files:
if file.endswith(target_extensions):
file_path = os.path.join(root, file)
try:
os.remove(file_path)
print(f"삭제됨: {file_path}")
except Exception as e:
print(f"오류 발생 ({file}): {e}")
def clean_files_glob():
"""glob을 사용한 방식 - 더 간단하지만 덜 세밀한 컨트롤"""
current_dir = os.getcwd()
print(f"작업 시작 위치: {current_dir}")
print("-" * 30)
# 제외할 폴더 패턴들
exclude_patterns = [
'**/venv/**', '**/env/**', '**/.env/**', '**/.venv/**',
'**/virtualenv/**', '**/.virtualenv/**', '**/conda/**',
'**/miniconda/**', '**/anaconda/**', '**/miniforge/**',
'**/node_modules/**', '**/dist/**', '**/build/**', '**/target/**',
'**/.git/**', '**/__pycache__/**', '**/.vscode/**', '**/.idea/**',
'**/.pytest_cache/**', '**/.mypy_cache/**', '**/.tox/**', '**/.coverage/**'
]
deleted_count = 0
total_size = 0
# .c 파일들 찾기
for c_file in glob.glob("**/*.c", recursive=True):
if not _is_excluded_by_patterns(c_file, exclude_patterns):
try:
size = os.path.getsize(c_file)
os.remove(c_file)
print(f"삭제됨: {c_file} ({size} bytes)")
deleted_count += 1
total_size += size
except Exception as e:
print(f"오류 발생 ({c_file}): {e}")
# .pyd 파일들 찾기
for pyd_file in glob.glob("**/*.pyd", recursive=True):
if not _is_excluded_by_patterns(pyd_file, exclude_patterns):
try:
size = os.path.getsize(pyd_file)
os.remove(pyd_file)
print(f"삭제됨: {pyd_file} ({size} bytes)")
deleted_count += 1
total_size += size
except Exception as e:
print(f"오류 발생 ({pyd_file}): {e}")
print(f"\n{deleted_count}개 파일 삭제, {total_size} bytes 정리됨")
def _is_excluded_by_patterns(file_path, exclude_patterns):
"""파일 경로가 제외 패턴에 매칭되는지 확인"""
for pattern in exclude_patterns:
# glob 패턴을 fnmatch 스타일로 변환
if fnmatch.fnmatch(file_path, pattern):
return True
return False
def clean_files():
"""메인 정리 함수 - 기본적으로 oswalk 방식을 사용 (더 안전하고 세밀한 컨트롤)"""
print("=== Cython 빌드 파일 정리기 ===")
print("두 가지 정리 방식이 있습니다:")
print("1: os.walk 방식 (세밀한 컨트롤, 폴더별 제외, 추천)")
print("2: glob 방식 (간단하지만 덜 정밀)")
try:
choice = input("방식을 선택하세요 (1 또는 2, 기본값: 1): ").strip()
if choice == "2":
print("glob 방식을 선택했습니다.")
clean_files_glob()
else:
print("os.walk 방식을 선택했습니다.")
clean_files_oswalk()
except KeyboardInterrupt:
print("\n\n작업이 취소되었습니다.")
return
if __name__ == "__main__":
# 실수로 실행하는 것을 방지하기 위해 사용자 확인을 추가할 수 있습니다.
confirm = input("현재 폴더 내의 모든 .c, .pyd 파일을 삭제하시겠습니까? (y/n): ")
if confirm.lower() == 'y':
clean_files()
print("\n작업 완료.")
else:
print("취소되었습니다.")