track whether a package was installed "explicitly"
Adds a new attribute in the database to track whether a package was installed explicitly or not, where explicitly is the user running `spack install <package>` and implicitly is it being installed as a dependency. It also adds arguments to `spack find` to find these packages such that it should be possible to query the packages that were installed implicitly and are not currently depended upon any longer.
This commit is contained in:
parent
53df9fbb4f
commit
4acdfeae61
@ -57,6 +57,12 @@ def setup_parser(subparser):
|
||||
'-L', '--very-long', action='store_true',
|
||||
help='Show dependency hashes as well as versions.')
|
||||
|
||||
subparser.add_argument(
|
||||
'-e', '--explicit', action='store_true',
|
||||
help='Show only specs that were installed explicitly')
|
||||
subparser.add_argument(
|
||||
'-E', '--implicit', action='store_true',
|
||||
help='Show only specs that were installed as dependencies')
|
||||
subparser.add_argument(
|
||||
'-u', '--unknown', action='store_true',
|
||||
help='Show only specs Spack does not have a package for.')
|
||||
@ -163,7 +169,14 @@ def find(parser, args):
|
||||
installed = any
|
||||
if args.unknown:
|
||||
known = False
|
||||
q_args = { 'installed' : installed, 'known' : known }
|
||||
|
||||
explicit = None
|
||||
if args.explicit:
|
||||
explicit = False
|
||||
if args.implicit:
|
||||
explicit = True
|
||||
|
||||
q_args = { 'installed' : installed, 'known' : known, "explicit" : explicit }
|
||||
|
||||
# Get all the specs the user asked for
|
||||
if not query_specs:
|
||||
|
@ -78,4 +78,5 @@ def install(parser, args):
|
||||
ignore_deps=args.ignore_deps,
|
||||
make_jobs=args.jobs,
|
||||
verbose=args.verbose,
|
||||
fake=args.fake)
|
||||
fake=args.fake,
|
||||
explicit=True)
|
||||
|
@ -92,22 +92,24 @@ class InstallRecord(object):
|
||||
dependents left.
|
||||
|
||||
"""
|
||||
def __init__(self, spec, path, installed, ref_count=0):
|
||||
def __init__(self, spec, path, installed, ref_count=0, explicit=False):
|
||||
self.spec = spec
|
||||
self.path = str(path)
|
||||
self.installed = bool(installed)
|
||||
self.ref_count = ref_count
|
||||
self.explicit = explicit
|
||||
|
||||
def to_dict(self):
|
||||
return { 'spec' : self.spec.to_node_dict(),
|
||||
'path' : self.path,
|
||||
'installed' : self.installed,
|
||||
'ref_count' : self.ref_count }
|
||||
'ref_count' : self.ref_count,
|
||||
'explicit' : self.explicit }
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, spec, dictionary):
|
||||
d = dictionary
|
||||
return InstallRecord(spec, d['path'], d['installed'], d['ref_count'])
|
||||
return InstallRecord(spec, d['path'], d['installed'], d['ref_count'], d.get('explicit', False))
|
||||
|
||||
|
||||
class Database(object):
|
||||
@ -370,7 +372,7 @@ def _read(self):
|
||||
self.reindex(spack.install_layout)
|
||||
|
||||
|
||||
def _add(self, spec, path, directory_layout=None):
|
||||
def _add(self, spec, path, directory_layout=None, explicit=False):
|
||||
"""Add an install record for spec at path to the database.
|
||||
|
||||
This assumes that the spec is not already installed. It
|
||||
@ -392,7 +394,7 @@ def _add(self, spec, path, directory_layout=None):
|
||||
rec.path = path
|
||||
|
||||
else:
|
||||
self._data[key] = InstallRecord(spec, path, True)
|
||||
self._data[key] = InstallRecord(spec, path, True, explicit=explicit)
|
||||
for dep in spec.dependencies.values():
|
||||
self._increment_ref_count(dep, directory_layout)
|
||||
|
||||
@ -415,7 +417,7 @@ def _increment_ref_count(self, spec, directory_layout=None):
|
||||
self._data[key].ref_count += 1
|
||||
|
||||
@_autospec
|
||||
def add(self, spec, path):
|
||||
def add(self, spec, path, explicit=False):
|
||||
"""Add spec at path to database, locking and reading DB to sync.
|
||||
|
||||
``add()`` will lock and read from the DB on disk.
|
||||
@ -424,7 +426,7 @@ def add(self, spec, path):
|
||||
# TODO: ensure that spec is concrete?
|
||||
# Entire add is transactional.
|
||||
with self.write_transaction():
|
||||
self._add(spec, path)
|
||||
self._add(spec, path, explicit=explicit)
|
||||
|
||||
|
||||
def _get_matching_spec_key(self, spec, **kwargs):
|
||||
@ -513,7 +515,7 @@ def installed_extensions_for(self, extendee_spec):
|
||||
# TODO: conditional way to do this instead of catching exceptions
|
||||
|
||||
|
||||
def query(self, query_spec=any, known=any, installed=True):
|
||||
def query(self, query_spec=any, known=any, installed=True, explicit=any):
|
||||
"""Run a query on the database.
|
||||
|
||||
``query_spec``
|
||||
@ -553,6 +555,8 @@ def query(self, query_spec=any, known=any, installed=True):
|
||||
for key, rec in self._data.items():
|
||||
if installed is not any and rec.installed != installed:
|
||||
continue
|
||||
if explicit is not any and rec.explicit != explicit:
|
||||
continue
|
||||
if known is not any and spack.repo.exists(rec.spec.name) != known:
|
||||
continue
|
||||
if query_spec is any or rec.spec.satisfies(query_spec):
|
||||
|
@ -857,7 +857,8 @@ def do_install(self,
|
||||
skip_patch=False,
|
||||
verbose=False,
|
||||
make_jobs=None,
|
||||
fake=False):
|
||||
fake=False,
|
||||
explicit=False):
|
||||
"""Called by commands to install a package and its dependencies.
|
||||
|
||||
Package implementations should override install() to describe
|
||||
@ -995,7 +996,7 @@ def build_process():
|
||||
|
||||
# note: PARENT of the build process adds the new package to
|
||||
# the database, so that we don't need to re-read from file.
|
||||
spack.installed_db.add(self.spec, self.prefix)
|
||||
spack.installed_db.add(self.spec, self.prefix, explicit=explicit)
|
||||
|
||||
def sanity_check_prefix(self):
|
||||
"""This function checks whether install succeeded."""
|
||||
|
Loading…
Reference in New Issue
Block a user