From d4b064070d6b5c27fe461757a41dbbf802762d0b Mon Sep 17 00:00:00 2001 From: Intel A80486DX2-66 Date: Sat, 6 Jul 2024 16:19:58 +0200 Subject: [PATCH] Initial commit --- .editorconfig | 16 +++++++++ gitignore_clean.py | 83 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 .editorconfig create mode 100644 gitignore_clean.py diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b2284e5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +root = true + +[*] +charset = utf-8 +end_of_line = crlf +indent_size = 4 +insert_final_newline = true + +[{*.{c,d,h,py,sh},Makefile}] +max_line_length = 80 + +[Makefile] +indent_style = tab + +[*.{c,h}] +trim_trailing_whitespace = true diff --git a/gitignore_clean.py b/gitignore_clean.py new file mode 100644 index 0000000..0db60d2 --- /dev/null +++ b/gitignore_clean.py @@ -0,0 +1,83 @@ +#!/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, dirname +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"(? 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: + # FIXME: doesn't work as intended + for gitignore_path in list(Path(base_path).rglob("*.gitignore")): + directory = dirname(gitignore_path) + for file_path in extend_wildcards(read_gitignore(gitignore_path)): + full_path = directory + "/" + file_path + delete(full_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()