fix buildcache create for environments with uninstalled root specs (#17859)

* Handle uninstalled rootspecs in buildcache

- Do not parse specs / find matching specs when in an environment and no
package string is provided
- Error only when a spec.yaml or spec string are not installed. In an
environment it is fine when the root spec does not exist.
- When iterating through the matched specs, simply skip uninstalled
packages
This commit is contained in:
Harmen Stoppels 2020-08-13 18:59:20 +02:00 committed by GitHub
parent d2f56830f1
commit d6587ea365
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -239,8 +239,9 @@ def find_matching_specs(pkgs, allow_multiple_matches=False, env=None):
concretized specs given from cli concretized specs given from cli
Args: Args:
specs: list of specs to be matched against installed packages pkgs (string): spec to be matched against installed packages
allow_multiple_matches : if True multiple matches are admitted allow_multiple_matches (bool): if True multiple matches are admitted
env (Environment): active environment, or ``None`` if there is not one
Return: Return:
list of specs list of specs
@ -332,26 +333,25 @@ def _createtarball(env, spec_yaml=None, packages=None, add_spec=True,
signing_key=None, force=False, make_relative=False, signing_key=None, force=False, make_relative=False,
unsigned=False, allow_root=False, rebuild_index=False): unsigned=False, allow_root=False, rebuild_index=False):
if spec_yaml: if spec_yaml:
packages = set()
with open(spec_yaml, 'r') as fd: with open(spec_yaml, 'r') as fd:
yaml_text = fd.read() yaml_text = fd.read()
tty.debug('createtarball read spec yaml:') tty.debug('createtarball read spec yaml:')
tty.debug(yaml_text) tty.debug(yaml_text)
s = Spec.from_yaml(yaml_text) s = Spec.from_yaml(yaml_text)
packages.add('/{0}'.format(s.dag_hash())) package = '/{0}'.format(s.dag_hash())
matches = find_matching_specs(package, env=env)
elif packages: elif packages:
packages = packages matches = find_matching_specs(packages, env=env)
elif env: elif env:
packages = env.concretized_user_specs matches = [env.specs_by_hash[h] for h in env.concretized_order]
else: else:
tty.die("build cache file creation requires at least one" + tty.die("build cache file creation requires at least one" +
" installed package spec, an activate environment," + " installed package spec, an active environment," +
" or else a path to a yaml file containing a spec" + " or else a path to a yaml file containing a spec" +
" to install") " to install")
pkgs = set(packages)
specs = set() specs = set()
mirror = spack.mirror.MirrorCollection().lookup(output_location) mirror = spack.mirror.MirrorCollection().lookup(output_location)
@ -360,8 +360,6 @@ def _createtarball(env, spec_yaml=None, packages=None, add_spec=True,
msg = 'Buildcache files will be output to %s/build_cache' % outdir msg = 'Buildcache files will be output to %s/build_cache' % outdir
tty.msg(msg) tty.msg(msg)
matches = find_matching_specs(pkgs, env=env)
if matches: if matches:
tty.debug('Found at least one matching spec') tty.debug('Found at least one matching spec')
@ -371,11 +369,16 @@ def _createtarball(env, spec_yaml=None, packages=None, add_spec=True,
tty.debug('skipping external or virtual spec %s' % tty.debug('skipping external or virtual spec %s' %
match.format()) match.format())
else: else:
if add_spec: lookup = spack.store.db.query_one(match)
if not add_spec:
tty.debug('skipping matching root spec %s' % match.format())
elif lookup is None:
tty.debug('skipping uninstalled matching spec %s' %
match.format())
else:
tty.debug('adding matching spec %s' % match.format()) tty.debug('adding matching spec %s' % match.format())
specs.add(match) specs.add(match)
else:
tty.debug('skipping matching spec %s' % match.format())
if not add_deps: if not add_deps:
continue continue
@ -388,9 +391,14 @@ def _createtarball(env, spec_yaml=None, packages=None, add_spec=True,
if d == 0: if d == 0:
continue continue
lookup = spack.store.db.query_one(node)
if node.external or node.virtual: if node.external or node.virtual:
tty.debug('skipping external or virtual dependency %s' % tty.debug('skipping external or virtual dependency %s' %
node.format()) node.format())
elif lookup is None:
tty.debug('skipping uninstalled depenendency %s' %
node.format())
else: else:
tty.debug('adding dependency %s' % node.format()) tty.debug('adding dependency %s' % node.format())
specs.add(node) specs.add(node)