# ensure compatability with Spack v0.18.0 try: from spack.package_base import PackageStillNeededError except: from spack.package import PackageStillNeededError needed = set() # keep packages that are part of an environment for e in spack.environment.all_environments(): needed.update(e.all_hashes()) # also keep packages that provide compilers (and their dependencies) for c in spack.compilers.all_compiler_specs(): pkg_spec = spack.compilers.pkg_spec_for_compiler(c) needed.update([dep.dag_hash() for pkg in spack.store.db.query(pkg_spec) for dep in pkg.traverse()]) installed = {spec.dag_hash(): spec for spec in spack.store.db.query()} to_remove = set(installed) - needed # this will try to uninstall ANY package that is not part of an environment # including test dependencies # for a list of all the packages that will be uninstalled: print('The following packages will be uninstalled:') print('\n'.join(sorted([installed[h].short_spec+' ('+h+')' for h in to_remove]))) # iteratively uninstall packages with no dependents while to_remove: # print('New iteration') for hash in to_remove.copy(): spec = installed[hash] try: spec.package.do_uninstall() to_remove.discard(hash) except PackageStillNeededError: pass # print('Not ready to remove', spec.short_spec, 'in this iteration')