From 9e741096041a64e8c7e18b2b185818bef9381b20 Mon Sep 17 00:00:00 2001 From: Brian Ernst Date: Mon, 10 Nov 2025 13:56:12 -0800 Subject: [PATCH] Fixed up Unreal cleanup script. Included folders and files that might be included with source control, removed some configured paths. Tidied up script. --- source/project/unreal_clean.py | 126 ++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 58 deletions(-) diff --git a/source/project/unreal_clean.py b/source/project/unreal_clean.py index e527c9f..6c837f7 100644 --- a/source/project/unreal_clean.py +++ b/source/project/unreal_clean.py @@ -24,17 +24,18 @@ ignore_folders = { '.git' } +# NOTE: These are recursively deleted. dirs_to_delete = { - ".idea", ".vs", - "Binaries", "DerivedDataCache", "Intermediate", "Saved", } + +# NOTE: These are recursively deleted. +# Be careful not to mark for deletion files that are included with your version +# control. files_to_delete = { - ".vsconfig", - "*.sln", } def get_file_directory(): @@ -54,82 +55,91 @@ def clean_unreal_temps(dry_run = False, verbose = False, quiet = False): if not quiet: print(f"Iterating {target_path} for directories and files to cleanup{', doing a dry-run ' if dry_run else ''}...") - # TODO: If not doing a dry run could give people a 5+ second countdown or something to cancel the script. + # TODO: If not doing a dry run could give people a 5+ second countdown or + # something to cancel the script. start = time.time() counted_iterated = 0 - for root, dirs, files, in os.walk(target_path): - counted_iterated += 1 + if len(dirs_to_delete) or len(files_to_delete): + for root, dirs, files, in os.walk(target_path): + counted_iterated += 1 - # Don't waste time processing an empty directory. - if len(dirs) == 0 and len(files) == 0: - continue - - root_path = pathlib.Path(root) - - for dir in reversed(dirs): - if dir in ignore_folders: - dirs.remove(dir) + # Don't waste time processing an empty directory. + if len(dirs) == 0 and len(files) == 0: continue - if dir not in dirs_to_delete: - # We do want os.walk to continue to look into this directory. - continue + root_path = pathlib.Path(root) - # We're processing a directory we're going to delete, no need to leave - # os.walk to iterate over the files in this directory. Helpful during - # a dry-run to run similarly during non-dry-run. But also if we were - # multi-threaded, this wouldn't try to iterate files we're already - # trying to delete. - dirs.remove(dir) + if len(dirs_to_delete) or len(ignore_folders): + for dir in reversed(dirs): + if dir in ignore_folders: + dirs.remove(dir) + continue - dir_path = root_path / dir - - if not dry_run: - shutil.rmtree(dir_path, onerror=del_rw) + if dir not in dirs_to_delete: + # We do want os.walk to continue to look into this directory. + continue - count_dirs_deleted += 1 + # We're processing a directory we're going to delete, no need to leave + # os.walk to iterate over the files in this directory. Helpful during + # a dry-run to run similarly during non-dry-run. But also if we were + # multi-threaded, this wouldn't try to iterate files we're already + # trying to delete. + dirs.remove(dir) - if verbose and not quiet: - if dry_run: - print(f" Pretend Deleted: {dir_path}") - else: - print(f" Deleted: {dir_path}") + dir_path = root_path / dir + + if not dry_run: + shutil.rmtree(dir_path, onerror=del_rw) - for file in files: - if not any(pathlib.PurePath(file).match(pattern) for pattern in files_to_delete): - continue + count_dirs_deleted += 1 - file_path = root_path / file + if verbose and not quiet: + if dry_run: + print(f" Pretend Deleted: {dir_path}") + else: + print(f" Deleted: {dir_path}") - if not dry_run: - file_path.unlink() + if len(files_to_delete): + for file in files: + if not any(pathlib.PurePath(file).match(pattern) for pattern in files_to_delete): + continue - count_files_deleted += 1 + file_path = root_path / file - if verbose and not quiet: - if dry_run: - print(f" Pretend Deleted: {dir_path}") - else: - print(f" Deleted: {dir_path}") + if not dry_run: + file_path.unlink() - # Done, summarize everything. - if not quiet: - prefix = None - if dry_run: - prefix = "Dry-run, would have deleted" - else: - prefix = "Deleted" + count_files_deleted += 1 + + if verbose and not quiet: + if dry_run: + print(f" Pretend Deleted: {file_path}") + else: + print(f" Deleted: {file_path}") + + # Done, summarize everything. + if not quiet: + prefix = None + if dry_run: + prefix = "Dry-run, would have deleted" + else: + prefix = "Deleted" - print(f" {prefix} {count_dirs_deleted} director{'ies' if count_dirs_deleted != 1 else 'y'}, {count_files_deleted} file{'s' if count_files_deleted != 1 else ''}. Iterated {counted_iterated} paths.") + print(f" {prefix} {count_dirs_deleted} director{'ies' if count_dirs_deleted != 1 else 'y'}, {count_files_deleted} file{'s' if count_files_deleted != 1 else ''}. Iterated {counted_iterated} paths.") - if count_dirs_deleted > 0: - print(f" (NOTE: Number of {'potentially ' if dry_run else ''}deleted files does not currently include a count of files from a deleted directory.)") + # TODO: Add up the file size deleted (including from deleted folders) + # in a verbose run, or have that as an extra param. - print(f" Done. Finished in {str(time.time() - start)}s") + if count_dirs_deleted > 0: + print(f" (NOTE: Number of {'potentially ' if dry_run else ''}deleted files does not include files from a deleted directory.)") + + print(f" Done. Finished in {str(time.time() - start)}s") + else: + print(" Skipped. Nothing configured to be deleted.") if __name__ == "__main__":