1
0
mirror of https://gitlab.com/80486DX2-66/gists synced 2024-12-26 11:30:03 +05:30
gists/gitignore_clean.py

81 lines
2.2 KiB
Python

#!/usr/bin/python3
from glob import glob
from os import remove as os_remove
from os.path import isdir as path_isdir, isfile as path_isfile, abspath, \
basename
from pathlib import Path
from re import sub as re_sub
from shutil import rmtree
DRY_RUN = False
remove_comments = lambda s: re_sub(r"(?<!\\)#.*$", "", s).replace(r"\#", "#")
def read_gitignore(path: str) -> str:
with open(path, "r", encoding="utf-8-sig") as gitignore_file:
res = gitignore_file.read().splitlines()
return res
def delete(file_path: str) -> None:
is_dir = path_isdir(file_path)
is_file = path_isfile(file_path)
if not (is_dir or is_file):
return
display_file_path = abspath(file_path)
if DRY_RUN:
if is_dir:
print("Removing directory", display_file_path)
elif is_file:
print("Removing file", display_file_path)
if DRY_RUN:
return
if is_dir:
rmtree(file_path, ignore_errors=True)
elif is_file:
os_remove(file_path)
def extend_wildcards(patterns: list) -> list:
res = []
for pattern in patterns:
processed_line = remove_comments(pattern).strip()
if processed_line.startswith("!"):
exception_pattern = processed_line[1:]
exceptions = glob(exception_pattern, recursive=True)
res = [path for path in res if path not in exceptions]
else:
res.extend(glob(processed_line, recursive=True))
return res
def clean_gitignored_files(base_path: str = ".") -> None:
for gitignore_path in list(Path(base_path).rglob("*.gitignore")):
for file_path in extend_wildcards(read_gitignore(gitignore_path)):
delete(file_path)
if __name__ == "__main__":
from sys import argv
if "-h" in argv or "--help" in argv:
print("Usage:", basename(argv[0]), "[options]")
print()
print("[ ]: Optional arguments")
print()
print("Options:")
print(" -h, --help: Display this help text")
print(" -d, --dry-run: Only list files")
else:
if (argc := len(argv)) == 2 and argv[1] in ["-d", "--dry-run"]:
DRY_RUN = True
clean_gitignored_files()