def concretize_variants(self, spec): """If the spec already has variants filled in, return. Otherwise, add the user preferences from packages.yaml or the default variants from the package specification. """ changed = False preferred_variants = PackagePrefs.preferred_variants(spec.name) pkg_cls = spec.package_class for name, entry in pkg_cls.variants.items(): variant, when = entry var = spec.variants.get(name, None) if var and '*' in var: # remove variant wildcard before concretizing # wildcard cannot be combined with other variables in a # multivalue variant, a concrete variant cannot have the value # wildcard, and a wildcard does not constrain a variant spec.variants.pop(name) if name not in spec.variants and any( spec.satisfies(w) for w in when): changed = True if name in preferred_variants: spec.variants[name] = preferred_variants.get(name) else: spec.variants[name] = variant.make_default() if name in spec.variants and not any( spec.satisfies(w) for w in when): raise vt.InvalidVariantForSpecError(name, when, spec) return changed
def match_downloaded_specs(pkgs, allow_multiple_matches=False, force=False, other_arch=False): """Returns a list of specs matching the not necessarily concretized specs given from cli Args: specs: list of specs to be matched against buildcaches on mirror allow_multiple_matches : if True multiple matches are admitted Return: list of specs """ # List of specs that match expressions given via command line specs_from_cli = [] has_errors = False try: specs = bindist.update_cache_and_get_specs() except bindist.FetchCacheError as e: tty.error(e) if not other_arch: arch = spack.spec.Spec.default_arch() specs = [s for s in specs if s.satisfies(arch)] for pkg in pkgs: matches = [] tty.msg("buildcache spec(s) matching %s \n" % pkg) for spec in sorted(specs): if pkg.startswith('/'): pkghash = pkg.replace('/', '') if spec.dag_hash().startswith(pkghash): matches.append(spec) else: if spec.satisfies(pkg): matches.append(spec) # For each pkg provided, make sure it refers to only one package. # Fail and ask user to be unambiguous if it doesn't if not allow_multiple_matches and len(matches) > 1: tty.error('%s matches multiple downloaded packages:' % pkg) for match in matches: tty.msg('"%s"' % match.format()) has_errors = True # No downloaded package matches the query if len(matches) == 0: tty.error('%s does not match any downloaded packages.' % pkg) has_errors = True specs_from_cli.extend(matches) if has_errors: tty.die('use one of the matching specs above') return specs_from_cli
def test_dev_build_env_dependency(tmpdir, mock_packages, install_mockery, mock_fetch, mutable_mock_env_path): """ Test non-root specs in an environment are properly marked for dev builds. """ # setup dev-build-test-install package for dev build build_dir = tmpdir.mkdir('build') spec = spack.spec.Spec('[email protected]') dep_spec = spack.spec.Spec('dev-build-test-install') with build_dir.as_cwd(): dep_pkg_cls = spack.repo.path.get_pkg_class(dep_spec.name) with open(dep_pkg_cls.filename, 'w') as f: f.write(dep_pkg_cls.original_string) # setup environment envdir = tmpdir.mkdir('env') with envdir.as_cwd(): with open('spack.yaml', 'w') as f: f.write("""\ env: specs: - [email protected] develop: dev-build-test-install: spec: [email protected] path: %s """ % os.path.relpath(str(build_dir), start=str(envdir))) env('create', 'test', './spack.yaml') with ev.read('test'): # concretize in the environment to get the dev build info # equivalent to setting dev_build and dev_path variants # on all specs above spec.concretize() dep_spec.concretize() install() # Ensure that both specs installed properly assert dep_spec.package.filename in os.listdir(dep_spec.prefix) assert os.path.exists(spec.prefix) # Ensure variants set properly; ensure build_dir is absolute and normalized for dep in (dep_spec, spec['dev-build-test-install']): assert dep.satisfies('dev_path=%s' % build_dir) assert spec.satisfies('^dev_path=*')
def match_downloaded_specs(pkgs, allow_multiple_matches=False, force=False): """Returns a list of specs matching the not necessarily concretized specs given from cli Args: specs: list of specs to be matched against buildcaches on mirror allow_multiple_matches : if True multiple matches are admitted Return: list of specs """ # List of specs that match expressions given via command line specs_from_cli = [] has_errors = False specs = bindist.get_specs(force) for pkg in pkgs: matches = [] tty.msg("buildcache spec(s) matching %s \n" % pkg) for spec in sorted(specs): if pkg.startswith('/'): pkghash = pkg.replace('/', '') if spec.dag_hash().startswith(pkghash): matches.append(spec) else: if spec.satisfies(pkg): matches.append(spec) # For each pkg provided, make sure it refers to only one package. # Fail and ask user to be unambiguous if it doesn't if not allow_multiple_matches and len(matches) > 1: tty.error('%s matches multiple downloaded packages:' % pkg) for match in matches: tty.msg('"%s"' % match.format()) has_errors = True # No downloaded package matches the query if len(matches) == 0: tty.error('%s does not match any downloaded packages.' % pkg) has_errors = True specs_from_cli.extend(matches) if has_errors: tty.die('use one of the matching specs above') return specs_from_cli
def find(parser, args): def hasher(): return collections.defaultdict(hasher) query_specs = [] if args.query_specs: query_specs = spack.cmd.parse_specs(args.query_specs, normalize=True) # Make a dict with specs keyed by architecture and compiler. index = hasher() for spec in packages.installed_package_specs(): if query_specs and not any(spec.satisfies(q) for q in query_specs): continue if spec.compiler not in index[spec.architecture]: index[spec.architecture][spec.compiler] = [] index[spec.architecture][spec.compiler].append(spec) # Traverse the index and print out each package for architecture in index: print hline(architecture, "=", spack.spec.architecture_color) for compiler in index[architecture]: print hline(compiler, "-", spack.spec.compiler_color) specs = index[architecture][compiler] specs.sort() abbreviated = [s.format('$_$@$+$#', color=True) for s in specs] if args.paths: # Print one spec per line along with prefix path width = max(len(s) for s in abbreviated) width += 2 format = " %-{}s%s".format(width) for abbrv, spec in zip(abbreviated, specs): print format % (abbrv, spec.package.prefix) elif args.full_specs: for spec in specs: print spec.tree(indent=4, format='$_$@$+', color=True), else: for abbrv in abbreviated: print " %s" % abbrv
def listspecs(args): """list binary packages available from mirrors""" specs = bindist.get_specs(args.force) if args.packages: pkgs = set(args.packages) for pkg in pkgs: tty.msg("buildcache spec(s) matching " + "%s and commands to install them" % pkgs) for spec in sorted(specs): if spec.satisfies(pkg): tty.msg('Enter\nspack buildcache install /%s\n' % spec.dag_hash(7) + ' to install "%s"' % spec.format()) else: tty.msg("buildcache specs and commands to install them") for spec in sorted(specs): tty.msg('Enter\nspack buildcache install /%s\n' % spec.dag_hash(7) + ' to install "%s"' % spec.format())