Source code for ramble.cmd.clean

# Copyright 2022-2026 The Ramble Authors
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.


import argparse
import os
import shutil

from llnl.util import tty

import ramble.caches
import ramble.reports
from ramble.paths import lib_path, var_path
from ramble.util.logger import logger

import spack.util.spack_yaml as syaml

description = "remove temporary files and/or downloaded archives"
section = "cleanup"
level = "long"


[docs] class AllClean(argparse.Action): """Activates flags -d -m and -p simultaneously""" def __call__(self, parser, namespace, values, option_string=None): parser.parse_args(["-dmp"], namespace=namespace)
[docs] def setup_parser(subparser): subparser.add_argument( "-d", "--downloads", action="store_true", help="remove cached downloads (default)" ) subparser.add_argument( "-m", "--misc-cache", action="store_true", help="remove long-lived caches" ) subparser.add_argument( "-p", "--python-cache", action="store_true", help="remove .pyc, .pyo files and __pycache__ folders", ) subparser.add_argument( "-r", "--reports", action="store_true", help="remove pdf and image files generated by ramble reports", ) subparser.add_argument("-a", "--all", action=AllClean, help="equivalent to -dmp", nargs=0)
[docs] def clean(parser, args): # If nothing was set, activate the default if not any([args.downloads, args.misc_cache, args.python_cache, args.reports]): args.downloads = True if args.downloads: logger.msg("Removing cached downloads") ramble.caches.fetch_cache.destroy() if args.misc_cache: logger.msg("Removing cached information on repositories") ramble.caches.misc_cache.destroy() if args.python_cache: logger.msg("Removing python cache files") remove_python_caches() if args.reports: logger.msg("Removing pdf and image files generated by ramble reports") remove_reports_files()
[docs] def remove_python_caches(): logger.msg("Removing python cache files") for directory in [lib_path, var_path]: for root, dirs, files in os.walk(directory): for f in files: if f.endswith(".pyc") or f.endswith(".pyo"): fname = os.path.join(root, f) logger.debug(f"Removing {fname}") os.remove(fname) for d in dirs: if d == "__pycache__": dname = os.path.join(root, d) logger.debug(f"Removing {dname}") shutil.rmtree(dname)
[docs] def remove_reports_files(): reports_path = ramble.reports.get_reports_path() if reports_path: answer = tty.get_yes_or_no( f"Really remove all reports and images from {reports_path}?", default=False, ) if not answer: logger.die("Will not remove any files") for root, _, files in os.walk(reports_path, topdown=False): inventory_file = os.path.join(root, ramble.reports.INVENTORY_FILENAME) try: with open(inventory_file) as f: inventory = syaml.load(f) except FileNotFoundError: continue if inventory: for inv_file in inventory["files"]: if inv_file in files: fname = os.path.join(root, inv_file) logger.debug(f"Removing {fname}") os.remove(fname) logger.debug(f"Removing {inventory_file}") os.remove(inventory_file) if not os.listdir(root): logger.debug(f"Removing empty directory {root}") os.rmdir(root) # Clean up symlinks in root dir for item in os.listdir(reports_path): item_path = os.path.join(reports_path, item) if os.path.islink(item_path): logger.debug(f"Removing {item_path}") os.remove(item_path)