Add Unreal cleanup script.
This commit is contained in:
parent
0d7717896b
commit
229bcdb9c2
1 changed files with 148 additions and 0 deletions
148
source/project/unreal_clean.py
Normal file
148
source/project/unreal_clean.py
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Drop this script into a folder you want to clean, and run it.
|
||||
Eventually I'll configure this as runnable from a scripts directory without having to drop it at a root directory; that relies on a config. If no config found, it will run in current directory.
|
||||
"""
|
||||
|
||||
__license__ = "MPL 2.0"
|
||||
__version__ = "0.1"
|
||||
__credits__ = ["Brian Ernst (leetNightshade)"]
|
||||
|
||||
__maintainer__ = "leetNightshade"
|
||||
__status__ = "Prototype"
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import pathlib
|
||||
import shutil
|
||||
import stat
|
||||
import sys
|
||||
import time
|
||||
|
||||
ignore_folders = {
|
||||
'.git'
|
||||
}
|
||||
|
||||
dirs_to_delete = {
|
||||
".idea",
|
||||
".vs",
|
||||
"Binaries",
|
||||
"DerivedDataCache",
|
||||
"Intermediate",
|
||||
"Saved",
|
||||
}
|
||||
files_to_delete = {
|
||||
".vsconfig",
|
||||
"*.sln",
|
||||
}
|
||||
|
||||
def get_file_directory():
|
||||
return pathlib.Path(__file__).parent
|
||||
|
||||
def del_rw(action, name, exc):
|
||||
os.chmod(name, stat.S_IWRITE)
|
||||
os.remove(name)
|
||||
|
||||
def clean_unreal_temps(dry_run = False, verbose = False, quiet = False):
|
||||
|
||||
target_path = get_file_directory()
|
||||
|
||||
count_dirs_deleted = 0
|
||||
count_files_deleted = 0
|
||||
|
||||
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.
|
||||
|
||||
start = time.time()
|
||||
|
||||
counted_iterated = 0
|
||||
|
||||
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)
|
||||
continue
|
||||
|
||||
if dir not in dirs_to_delete:
|
||||
# We do want os.walk to continue to look into this directory.
|
||||
continue
|
||||
|
||||
# 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)
|
||||
|
||||
dir_path = root_path / dir
|
||||
|
||||
if not dry_run:
|
||||
shutil.rmtree(dir_path, onerror=del_rw)
|
||||
|
||||
count_dirs_deleted += 1
|
||||
|
||||
if verbose and not quiet:
|
||||
if dry_run:
|
||||
print(f" Pretend Deleted: {dir_path}")
|
||||
else:
|
||||
print(f" Deleted: {dir_path}")
|
||||
|
||||
for file in files:
|
||||
if not any(pathlib.PurePath(file).match(pattern) for pattern in files_to_delete):
|
||||
continue
|
||||
|
||||
file_path = root_path / file
|
||||
|
||||
if not dry_run:
|
||||
file_path.unlink()
|
||||
|
||||
count_files_deleted += 1
|
||||
|
||||
if verbose and not quiet:
|
||||
if dry_run:
|
||||
print(f" Pretend Deleted: {dir_path}")
|
||||
else:
|
||||
print(f" Deleted: {dir_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.")
|
||||
|
||||
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.)")
|
||||
|
||||
print(f" Done. Finished in {str(time.time() - start)}s")
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
parser = argparse.ArgumentParser(description="Script to clean temp Unreal files/folders")
|
||||
|
||||
parser.add_argument('--dry-run', '-n', action='store_true', help='Dry run without any modifications.')
|
||||
parser.add_argument('--unattended', '-u', action='store_true', help='Run without waiting.')
|
||||
parser.add_argument('--quiet', '-q', action='store_true', help='Quiet output.')
|
||||
parser.add_argument('--verbose', '-v', action='store_true', help='Verbose output.')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
clean_unreal_temps(dry_run = args.dry_run, verbose = args.verbose)
|
||||
|
||||
if not args.unattended:
|
||||
input("Waiting for input...")
|
||||
Loading…
Add table
Add a link
Reference in a new issue