aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/msubprojects.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/msubprojects.py')
-rwxr-xr-xmesonbuild/msubprojects.py64
1 files changed, 63 insertions, 1 deletions
diff --git a/mesonbuild/msubprojects.py b/mesonbuild/msubprojects.py
index d038fa7..bdd8c1f 100755
--- a/mesonbuild/msubprojects.py
+++ b/mesonbuild/msubprojects.py
@@ -4,7 +4,7 @@ from pathlib import Path
from . import mlog
from .mesonlib import quiet_git, verbose_git, GitException, Popen_safe, MesonException, windows_proof_rmtree
-from .wrap.wrap import API_ROOT, Resolver, WrapException, ALL_TYPES
+from .wrap.wrap import API_ROOT, PackageDefinition, Resolver, WrapException, ALL_TYPES
from .wrap import wraptool
ALL_TYPES_STRING = ', '.join(ALL_TYPES)
@@ -312,6 +312,61 @@ def foreach(r, wrap, repo_dir, options):
mlog.log(out, end='')
return True
+def purge(r: Resolver, wrap: PackageDefinition, repo_dir: str, options: argparse.Namespace) -> bool:
+ # if subproject is not wrap-based, then don't remove it
+ if not wrap.type:
+ return True
+
+ if wrap.type == 'redirect':
+ redirect_file = Path(wrap.filename).resolve()
+ if options.confirm:
+ redirect_file.unlink()
+ mlog.log(f'Deleting {redirect_file}')
+
+ if options.include_cache:
+ packagecache = Path(r.cachedir).resolve()
+ subproject_cache_file = packagecache / wrap.get("source_filename")
+ if subproject_cache_file.is_file():
+ if options.confirm:
+ subproject_cache_file.unlink()
+ mlog.log(f'Deleting {subproject_cache_file}')
+
+ try:
+ subproject_patch_file = packagecache / wrap.get("patch_filename")
+ if subproject_patch_file.is_file():
+ if options.confirm:
+ subproject_patch_file.unlink()
+ mlog.log(f'Deleting {subproject_patch_file}')
+ except WrapException:
+ pass
+
+ # Don't log that we will remove an empty directory
+ if packagecache.exists() and not any(packagecache.iterdir()):
+ packagecache.rmdir()
+
+ subproject_source_dir = Path(repo_dir).resolve()
+
+ # Don't follow symlink. This is covered by the next if statement, but why
+ # not be doubly sure.
+ if subproject_source_dir.is_symlink():
+ if options.confirm:
+ subproject_source_dir.unlink()
+ mlog.log(f'Deleting {subproject_source_dir}')
+ return True
+
+ if not subproject_source_dir.is_dir():
+ return True
+
+ try:
+ if options.confirm:
+ windows_proof_rmtree(str(subproject_source_dir))
+ mlog.log(f'Deleting {subproject_source_dir}')
+ except OSError as e:
+ mlog.error(f'Unable to remove: {subproject_source_dir}: {e}')
+ return False
+
+ return True
+
def add_common_arguments(p):
p.add_argument('--sourcedir', default='.',
help='Path to source directory')
@@ -361,6 +416,13 @@ def add_arguments(parser):
p.set_defaults(subprojects=[])
p.set_defaults(subprojects_func=foreach)
+ p = subparsers.add_parser('purge', help='Remove all wrap-based subproject artifacts')
+ add_common_arguments(p)
+ add_subprojects_argument(p)
+ p.add_argument('--include-cache', action='store_true', default=False, help='Remove the package cache as well')
+ p.add_argument('--confirm', action='store_true', default=False, help='Confirm the removal of subproject artifacts')
+ p.set_defaults(subprojects_func=purge)
+
def run(options):
src_dir = os.path.relpath(os.path.realpath(options.sourcedir))
if not os.path.isfile(os.path.join(src_dir, 'meson.build')):