def spec(parser, args): name_fmt = '{namespace}.{name}' if args.namespaces else '{name}' fmt = '{@version}{%compiler}{compiler_flags}{variants}{arch=architecture}' install_status_fn = spack.spec.Spec.install_status kwargs = { 'cover': args.cover, 'format': name_fmt + fmt, 'hashlen': None if args.very_long else 7, 'show_types': args.types, 'status_fn': install_status_fn if args.install_status else None } if not args.specs: tty.die("spack spec requires at least one spec") for spec in spack.cmd.parse_specs(args.specs): # With -y, just print YAML to output. if args.yaml: if spec.name in spack.repo.path or spec.virtual: spec.concretize() # use write because to_yaml already has a newline. sys.stdout.write(spec.to_yaml()) continue kwargs['hashes'] = False # Always False for input spec print("Input spec") print("--------------------------------") print(spec.tree(**kwargs)) kwargs['hashes'] = args.long or args.very_long print("Concretized") print("--------------------------------") spec.concretize() print(spec.tree(**kwargs))
def display_specs(specs, **kwargs): mode = kwargs.get('mode', 'short') hashes = kwargs.get('long', False) namespace = kwargs.get('namespace', False) hlen = 7 if kwargs.get('very_long', False): hashes = True hlen = None # Make a dict with specs keyed by architecture and compiler. index = index_by(specs, ('architecture', 'compiler')) # Traverse the index and print out each package for i, (architecture, compiler) in enumerate(sorted(index)): if i > 0: print header = "%s{%s} / %s{%s}" % ( spack.spec.architecture_color, architecture, spack.spec.compiler_color, compiler) tty.hline(colorize(header), char='-') specs = index[(architecture,compiler)] specs.sort() nfmt = '.' if namespace else '_' abbreviated = [s.format('$%s$@$+' % nfmt, color=True) for s in specs] if mode == 'paths': # Print one spec per line along with prefix path width = max(len(s) for s in abbreviated) width += 2 format = " %%-%ds%%s" % width for abbrv, spec in zip(abbreviated, specs): if hashes: print gray_hash(spec, hlen), print format % (abbrv, spec.prefix) elif mode == 'deps': for spec in specs: print spec.tree( format='$%s$@$+' % nfmt, color=True, indent=4, prefix=(lambda s: gray_hash(s, hlen)) if hashes else None) elif mode == 'short': def fmt(s): string = "" if hashes: string += gray_hash(s, hlen) + ' ' string += s.format('$-%s$@$+' % nfmt, color=True) return string colify(fmt(s) for s in specs) else: raise ValueError( "Invalid mode for display_specs: %s. Must be one of (paths, deps, short)." % mode)
def find(parser, args): # Filter out specs that don't exist. query_specs = spack.cmd.parse_specs(args.query_specs) query_specs, nonexisting = partition_list( query_specs, lambda s: spack.db.exists(s.name)) if nonexisting: msg = "No such package%s: " % ('s' if len(nonexisting) > 1 else '') msg += ", ".join(s.name for s in nonexisting) tty.msg(msg) if not query_specs: return specs = [ s for s in spack.db.installed_package_specs() if not query_specs or any(s.satisfies(q) for q in query_specs) ] # Make a dict with specs keyed by architecture and compiler. index = index_by(specs, 'architecture', 'compiler') # Traverse the index and print out each package for architecture in index: tty.hline(architecture, char='=', color=spack.spec.architecture_color) for compiler in index[architecture]: tty.hline(compiler, char='-', color=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.prefix) elif args.full_specs: for spec in specs: print spec.tree(indent=4, format='$_$@$+', color=True), else: max_len = max([len(s.name) for s in specs]) max_len += 4 for spec in specs: format = '$-' + str(max_len) + '_$@$+$#' print " " + spec.format(format, color=True)
def spec(parser, args): name_fmt = '{namespace}.{name}' if args.namespaces else '{name}' fmt = '{@version}{%compiler}{compiler_flags}{variants}{arch=architecture}' install_status_fn = spack.spec.Spec.install_status tree_kwargs = { 'cover': args.cover, 'format': name_fmt + fmt, 'hashlen': None if args.very_long else 7, 'show_types': args.types, 'status_fn': install_status_fn if args.install_status else None } # use a read transaction if we are getting install status for every # spec in the DAG. This avoids repeatedly querying the DB. tree_context = nullcontext if args.install_status: tree_context = spack.store.db.read_transaction if not args.specs: tty.die("spack spec requires at least one spec") concretize_kwargs = {'reuse': args.reuse} for spec in spack.cmd.parse_specs(args.specs): # With -y, just print YAML to output. if args.format: if spec.name in spack.repo.path or spec.virtual: spec.concretize(**concretize_kwargs) # The user can specify the hash type to use hash_type = getattr(ht, args.hash_type) if args.format == 'yaml': # use write because to_yaml already has a newline. sys.stdout.write(spec.to_yaml(hash=hash_type)) else: print(spec.to_json(hash=hash_type)) continue with tree_context(): tree_kwargs['hashes'] = False # Always False for input spec print("Input spec") print("--------------------------------") print(spec.tree(**tree_kwargs)) tree_kwargs['hashes'] = args.long or args.very_long print("Concretized") print("--------------------------------") spec.concretize(**concretize_kwargs) print(spec.tree(**tree_kwargs))
def find(parser, args): # Filter out specs that don't exist. query_specs = spack.cmd.parse_specs(args.query_specs) query_specs, nonexisting = partition_list( query_specs, lambda s: spack.db.exists(s.name)) if nonexisting: msg = "No such package%s: " % ('s' if len(nonexisting) > 1 else '') msg += ", ".join(s.name for s in nonexisting) tty.msg(msg) if not query_specs: return specs = [s for s in spack.db.installed_package_specs() if not query_specs or any(s.satisfies(q) for q in query_specs)] # Make a dict with specs keyed by architecture and compiler. index = index_by(specs, 'architecture', 'compiler') # Traverse the index and print out each package for architecture in index: tty.hline(architecture, char='=', color=spack.spec.architecture_color) for compiler in index[architecture]: tty.hline(compiler, char='-', color=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: max_len = max([len(s.name) for s in specs]) max_len += 4 for spec in specs: format = '$-' + str(max_len) + '_$@$+$#' print " " + spec.format(format, color=True)
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 display_specs(specs, **kwargs): mode = kwargs.get('mode', 'short') # Make a dict with specs keyed by architecture and compiler. index = index_by(specs, ('architecture', 'compiler')) # Traverse the index and print out each package for i, (architecture, compiler) in enumerate(sorted(index)): if i > 0: print header = "%s{%s} / %s{%s}" % (spack.spec.architecture_color, architecture, spack.spec.compiler_color, compiler) tty.hline(colorize(header), char='-') specs = index[(architecture, compiler)] specs.sort() abbreviated = [s.format('$_$@$+', color=True) for s in specs] if mode == '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.prefix) elif mode == 'deps': for spec in specs: print spec.tree(indent=4, format='$_$@$+$#', color=True), elif mode in ('short', 'long'): fmt = '$-_$@$+' if mode == 'long': fmt += '$#' colify(s.format(fmt, color=True) for s in specs) else: raise ValueError( "Invalid mode for display_specs: %s. Must be one of (paths, deps, short)." % mode)
def display_specs(specs, **kwargs): mode = kwargs.get('mode', 'short') # Make a dict with specs keyed by architecture and compiler. index = index_by(specs, ('architecture', 'compiler')) # Traverse the index and print out each package for i, (architecture, compiler) in enumerate(sorted(index)): if i > 0: print header = "%s{%s} / %s{%s}" % ( spack.spec.architecture_color, architecture, spack.spec.compiler_color, compiler) tty.hline(colorize(header), char='-') specs = index[(architecture,compiler)] specs.sort() abbreviated = [s.format('$_$@$+', color=True) for s in specs] if mode == '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.prefix) elif mode == 'deps': for spec in specs: print spec.tree(indent=4, format='$_$@$+$#', color=True), elif mode in ('short', 'long'): fmt = '$-_$@$+' if mode == 'long': fmt += '$#' colify(s.format(fmt, color=True) for s in specs) else: raise ValueError( "Invalid mode for display_specs: %s. Must be one of (paths, deps, short)." % mode)
def preview_fn(args): """analyze an installed spec and reports whether executables and libraries are relocatable """ constraints = spack.cmd.parse_specs(args.specs) specs = spack.store.find(constraints, multiple=True) # Cycle over the specs that match for spec in specs: print("Relocatable nodes") print("--------------------------------") print(spec.tree(status_fn=spack.relocate.is_relocatable))
def preview(args): """Print a status tree of the selected specs that shows which nodes are relocatable and which might not be. Args: args: command line arguments """ specs = find_matching_specs(args.specs, allow_multiple_matches=True) # Cycle over the specs that match for spec in specs: print("Relocatable nodes") print("--------------------------------") print(spec.tree(status_fn=spack.relocate.is_relocatable))
def print_spec_tree(dev_packages, specs): # Print the minimum number of spec trees starting with a package # for development such that all packages for development # (including additional ones) are shown in at least one tree. spec_names_to_print = set() specs_to_print_dict = {} all_to_print = set() for spec in specs: for p in dev_packages: if p in spec and p not in all_to_print: flat_dependencies = spec[p].flat_dependencies().keys() # Print the largest tree(s) only, avoiding # duplication of development packages. spec_names_to_print.difference_update(flat_dependencies) all_to_print.update(flat_dependencies) spec_names_to_print.add(p) specs_to_print_dict[p] = spec[p] tty.msg('Development package spec trees: \n{0}'.\ format('\n'.join([spec.tree(cover='nodes', format='{name}{@version}{%compiler}{compiler_flags}{variants}{arch=architecture}', hashlen=7, show_types=True, status_fn=spack.spec.Spec.install_status) for spec in [specs_to_print_dict[p] for p in spec_names_to_print]])))
def display_specs(specs, **kwargs): mode = kwargs.get('mode', 'short') hashes = kwargs.get('long', False) namespace = kwargs.get('namespace', False) flags = kwargs.get('show_flags', False) variants = kwargs.get('variants', False) hlen = 7 if kwargs.get('very_long', False): hashes = True hlen = None nfmt = '.' if namespace else '_' ffmt = '$%+' if flags else '' vfmt = '$+' if variants else '' format_string = '$%s$@%s%s' % (nfmt, ffmt, vfmt) # Make a dict with specs keyed by architecture and compiler. index = index_by(specs, ('architecture', 'compiler')) # Traverse the index and print out each package for i, (architecture, compiler) in enumerate(sorted(index)): if i > 0: print header = "%s{%s} / %s{%s}" % (spack.spec.architecture_color, architecture, spack.spec.compiler_color, compiler) tty.hline(colorize(header), char='-') specs = index[(architecture, compiler)] specs.sort() abbreviated = [s.format(format_string, color=True) for s in specs] if mode == 'paths': # Print one spec per line along with prefix path width = max(len(s) for s in abbreviated) width += 2 format = " %%-%ds%%s" % width for abbrv, spec in zip(abbreviated, specs): prefix = gray_hash(spec, hlen) if hashes else '' print prefix + (format % (abbrv, spec.prefix)) elif mode == 'deps': for spec in specs: print(spec.tree( format=format_string, color=True, indent=4, prefix=(lambda s: gray_hash(s, hlen)) if hashes else None)) elif mode == 'short': # Print columns of output if not printing flags if not flags: def fmt(s): string = "" if hashes: string += gray_hash(s, hlen) + ' ' string += s.format('$-%s$@%s' % (nfmt, vfmt), color=True) return string colify(fmt(s) for s in specs) # Print one entry per line if including flags else: for spec in specs: # Print the hash if necessary hsh = gray_hash(spec, hlen) + ' ' if hashes else '' print(hsh + spec.format(format_string, color=True) + '\n') else: raise ValueError( "Invalid mode for display_specs: %s. Must be one of (paths," "deps, short)." % mode)
def display_specs(specs, **kwargs): mode = kwargs.get('mode', 'short') hashes = kwargs.get('long', False) namespace = kwargs.get('namespace', False) hlen = 7 if kwargs.get('very_long', False): hashes = True hlen = None nfmt = '.' if namespace else '_' format_string = '$%s$@$+' % nfmt flags = kwargs.get('show_flags', False) if flags: format_string = '$%s$@$%%+$+' % nfmt # Make a dict with specs keyed by architecture and compiler. index = index_by(specs, ('architecture', 'compiler')) # Traverse the index and print out each package for i, (architecture, compiler) in enumerate(sorted(index)): if i > 0: print header = "%s{%s} / %s{%s}" % (spack.spec.architecture_color, architecture, spack.spec.compiler_color, compiler) tty.hline(colorize(header), char='-') specs = index[(architecture, compiler)] specs.sort() abbreviated = [s.format(format_string, color=True) for s in specs] if mode == 'paths': # Print one spec per line along with prefix path width = max(len(s) for s in abbreviated) width += 2 format = " %%-%ds%%s" % width for abbrv, spec in zip(abbreviated, specs): if hashes: print(gray_hash(spec, hlen), ) print(format % (abbrv, spec.prefix)) elif mode == 'deps': for spec in specs: print( spec.tree(format=format_string, color=True, indent=4, prefix=(lambda s: gray_hash(s, hlen)) if hashes else None)) elif mode == 'short': # Print columns of output if not printing flags if not flags: def fmt(s): string = "" if hashes: string += gray_hash(s, hlen) + ' ' string += s.format('$-%s$@$+' % nfmt, color=True) return string colify(fmt(s) for s in specs) # Print one entry per line if including flags else: for spec in specs: # Print the hash if necessary hsh = gray_hash(spec, hlen) + ' ' if hashes else '' print(hsh + spec.format(format_string, color=True) + '\n') else: raise ValueError( "Invalid mode for display_specs: %s. Must be one of (paths," "deps, short)." % mode) # NOQA: ignore=E501
def _tree_to_display(spec): return spec.tree(recurse_dependencies=True, status_fn=spack.spec.Spec.install_status, hashlen=7, hashes=True)
def display_specs(specs, args=None, **kwargs): """Display human readable specs with customizable formatting. Prints the supplied specs to the screen, formatted according to the arguments provided. Specs are grouped by architecture and compiler, and columnized if possible. There are three possible "modes": * ``short`` (default): short specs with name and version, columnized * ``paths``: Two columns: one for specs, one for paths * ``deps``: Dependency-tree style, like ``spack spec``; can get long Options can add more information to the default display. Options can be provided either as keyword arguments or as an argparse namespace. Keyword arguments take precedence over settings in the argparse namespace. Args: specs (list of spack.spec.Spec): the specs to display args (optional argparse.Namespace): namespace containing formatting arguments Keyword Args: mode (str): Either 'short', 'paths', or 'deps' long (bool): Display short hashes with specs very_long (bool): Display full hashes with specs (supersedes ``long``) namespace (bool): Print namespaces along with names show_flags (bool): Show compiler flags with specs variants (bool): Show variants with specs """ def get_arg(name, default=None): """Prefer kwargs, then args, then default.""" if name in kwargs: return kwargs.get(name) elif args is not None: return getattr(args, name, default) else: return default mode = get_arg('mode', 'short') hashes = get_arg('long', False) namespace = get_arg('namespace', False) flags = get_arg('show_flags', False) full_compiler = get_arg('show_full_compiler', False) variants = get_arg('variants', False) hlen = 7 if get_arg('very_long', False): hashes = True hlen = None nfmt = '.' if namespace else '_' ffmt = '' if full_compiler or flags: ffmt += '$%' if full_compiler: ffmt += '@' ffmt += '+' vfmt = '$+' if variants else '' format_string = '$%s$@%s%s' % (nfmt, ffmt, vfmt) # Make a dict with specs keyed by architecture and compiler. index = index_by(specs, ('architecture', 'compiler')) # Traverse the index and print out each package for i, (architecture, compiler) in enumerate(sorted(index)): if i > 0: print() header = "%s{%s} / %s{%s}" % (spack.spec.architecture_color, architecture, spack.spec.compiler_color, compiler) tty.hline(colorize(header), char='-') specs = index[(architecture, compiler)] specs.sort() abbreviated = [s.cformat(format_string) for s in specs] if mode == 'paths': # Print one spec per line along with prefix path width = max(len(s) for s in abbreviated) width += 2 format = " %%-%ds%%s" % width for abbrv, spec in zip(abbreviated, specs): prefix = gray_hash(spec, hlen) if hashes else '' print(prefix + (format % (abbrv, spec.prefix))) elif mode == 'deps': for spec in specs: print( spec.tree(format=format_string, indent=4, prefix=(lambda s: gray_hash(s, hlen)) if hashes else None)) elif mode == 'short': # Print columns of output if not printing flags if not flags and not full_compiler: def fmt(s): string = "" if hashes: string += gray_hash(s, hlen) + ' ' string += s.cformat('$-%s$@%s' % (nfmt, vfmt)) return string colify(fmt(s) for s in specs) # Print one entry per line if including flags else: for spec in specs: # Print the hash if necessary hsh = gray_hash(spec, hlen) + ' ' if hashes else '' print(hsh + spec.cformat(format_string) + '\n') else: raise ValueError( "Invalid mode for display_specs: %s. Must be one of (paths," "deps, short)." % mode)
def init(parser, args): global spackdev_base # Verbosity tty.set_verbose(args.verbose) if 'SPACKDEV_BASE' in os.environ: if args.force: tty.warn( 'spack dev init: (force) removing existing SPACKDEV_* from current environment.' ) for x in [x for x in os.environ if x.startswith('SPACKDEV_')]: del os.environ[x] else: tty.die( 'spack dev init: current environment is already aware of a SpackDev environment ({0})' .format(os.environ['SPACKDEV_BASE'])) if args.base_dir: if os.path.isdir(args.base_dir) or \ os.path.exists(os.path.abspath(os.path.dirname(args.base_dir))): spackdev_base = os.path.abspath(args.base_dir) else: tty.die( 'spack dev init: {0} is not a directory or its parent does not exist.' .format(args.base_dir)) try: if (not os.path.exists(spackdev_base)): os.mkdir(spackdev_base) os.chdir(spackdev_base) except OSError: tty.die( 'spack dev init: unable to make or change directory to {0}'.format( spackdev_base)) # Save for posterity os.environ['SPACKDEV_BASE'] = spackdev_base requested = args.packages dag_filename = args.dag_file build_system = Build_system(args.generator, args.override_generator) os.environ['SPACKDEV_GENERATOR'] = build_system.cmake_generator if os.listdir(spackdev_base): if args.force: tty.warn( 'spack dev init: (force) using non-empty directory {0}'.format( spackdev_base)) if (os.path.exists('spackdev-aux') or os.path.exists('build') or os.path.exists('install') or os.path.exists('tmp')): if args.force: tty.warn( 'spack dev init: (force) removing existing spackdev-aux, build and install directories from {0}' .format(spackdev_base)) for wd in ('spackdev-aux', 'build', 'install', 'tmp'): shutil.rmtree(wd, ignore_errors=True) else: tty.die( 'spack dev init: cannot re-init (spackdev-aux/build/install/tmp directories exist)' ) else: tty.die('spack dev init: refusing to use non-empty directory {0}'. format(spackdev_base)) os.mkdir('spackdev-aux') filesystem.mkdirp('srcs') tty.msg('requested packages: {0}{1}'.\ format(', '.join(requested), ' from install tree as specified in {0}'.format(dag_filename) if dag_filename else '')) specs = extract_specs(dag_filename if dag_filename else requested) additional = get_additional(requested, specs) if additional: tty.msg('additional inter-dependent packages: ' + ' '.join(additional)) dev_packages = requested + additional if args.print_spec_tree: tty.msg('Full spec tree: \n{0}'.\ format('\n'.join([spec.tree(cover='nodes', format='{name}{@version}{%compiler}{compiler_flags}{variants}{arch=architecture}', hashlen=7, show_types=True, status_fn=spack.spec.Spec.install_status) for spec in specs]))) if args.print_spec_tree == 'exit': sys.exit(1) dep_specs = write_package_info(requested, additional, specs) package_specs = {} for package in dev_packages: spec = dev.cmd.get_package_spec(package, specs) if spec: package_specs[package] = spec[package] else: tty.die("Unable to find spec for specified package {0}".\ format(package)) if not args.no_stage: tty.msg('stage sources for {0}'.format(dev_packages)) dev.cmd.stage_packages(dev_packages, package_specs) if not args.no_dependencies: tty.msg('install dependencies') dev.cmd.install_dependencies(dev_packages=dev_packages, dep_specs=dep_specs) tty.msg('create wrapper scripts') path_fixer = create_environment(dev_packages, package_specs) tty.msg('generate top level CMakeLists.txt') write_cmakelists(dev_packages, package_specs, build_system, path_fixer) tty.msg('create and initialize build area') create_build_area(build_system, args) tty.msg('initialization of {0} complete;'.format(spackdev_base)) tty.msg('source {0} to begin.'.format( os.path.join(spackdev_base, dev.spackdev_aux_subdir, 'env.sh')))
def display_specs(specs, args=None, **kwargs): """Display human readable specs with customizable formatting. Prints the supplied specs to the screen, formatted according to the arguments provided. Specs are grouped by architecture and compiler, and columnized if possible. There are three possible "modes": * ``short`` (default): short specs with name and version, columnized * ``paths``: Two columns: one for specs, one for paths * ``deps``: Dependency-tree style, like ``spack spec``; can get long Options can add more information to the default display. Options can be provided either as keyword arguments or as an argparse namespace. Keyword arguments take precedence over settings in the argparse namespace. Args: specs (list of spack.spec.Spec): the specs to display args (optional argparse.Namespace): namespace containing formatting arguments Keyword Args: mode (str): Either 'short', 'paths', or 'deps' long (bool): Display short hashes with specs very_long (bool): Display full hashes with specs (supersedes ``long``) namespace (bool): Print namespaces along with names show_flags (bool): Show compiler flags with specs variants (bool): Show variants with specs indent (int): indent each line this much decorators (dict): dictionary mappng specs to decorators header_callback (function): called at start of arch/compiler sections all_headers (bool): show headers even when arch/compiler aren't defined """ def get_arg(name, default=None): """Prefer kwargs, then args, then default.""" if name in kwargs: return kwargs.get(name) elif args is not None: return getattr(args, name, default) else: return default mode = get_arg('mode', 'short') hashes = get_arg('long', False) namespace = get_arg('namespace', False) flags = get_arg('show_flags', False) full_compiler = get_arg('show_full_compiler', False) variants = get_arg('variants', False) all_headers = get_arg('all_headers', False) decorator = get_arg('decorator', None) if decorator is None: decorator = lambda s, f: f indent = get_arg('indent', 0) ispace = indent * ' ' hlen = 7 if get_arg('very_long', False): hashes = True hlen = None nfmt = '{fullpackage}' if namespace else '{package}' ffmt = '' if full_compiler or flags: ffmt += '$%' if full_compiler: ffmt += '@' ffmt += '+' vfmt = '$+' if variants else '' format_string = '$%s$@%s%s' % (nfmt, ffmt, vfmt) # Make a dict with specs keyed by architecture and compiler. index = index_by(specs, ('architecture', 'compiler')) transform = {'package': decorator, 'fullpackage': decorator} # Traverse the index and print out each package for i, (architecture, compiler) in enumerate(sorted(index)): if i > 0: print() header = "%s{%s} / %s{%s}" % (spack.spec.architecture_color, architecture if architecture else 'no arch', spack.spec.compiler_color, compiler if compiler else 'no compiler') # Sometimes we want to display specs that are not yet concretized. # If they don't have a compiler / architecture attached to them, # then skip the header if all_headers or (architecture is not None or compiler is not None): sys.stdout.write(ispace) tty.hline(colorize(header), char='-') specs = index[(architecture, compiler)] specs.sort() if mode == 'paths': # Print one spec per line along with prefix path abbreviated = [ s.cformat(format_string, transform=transform) for s in specs ] width = max(len(s) for s in abbreviated) width += 2 for abbrv, spec in zip(abbreviated, specs): # optional hash prefix for paths h = gray_hash(spec, hlen) if hashes else '' # only show prefix for concrete specs prefix = spec.prefix if spec.concrete else '' # print it all out at once fmt = "%%s%%s %%-%ds%%s" % width print(fmt % (ispace, h, abbrv, prefix)) elif mode == 'deps': for spec in specs: print( spec.tree(format=format_string, indent=4, prefix=(lambda s: gray_hash(s, hlen)) if hashes else None)) elif mode == 'short': def fmt(s): string = "" if hashes: string += gray_hash(s, hlen) + ' ' string += s.cformat('$%s$@%s' % (nfmt, vfmt), transform=transform) return string if not flags and not full_compiler: # Print columns of output if not printing flags colify((fmt(s) for s in specs), indent=indent) else: # Print one entry per line if including flags for spec in specs: # Print the hash if necessary hsh = gray_hash(spec, hlen) + ' ' if hashes else '' print(ispace + hsh + spec.cformat(format_string, transform=transform)) else: raise ValueError( "Invalid mode for display_specs: %s. Must be one of (paths," "deps, short)." % mode)
def display_specs(specs, args=None, **kwargs): """Display human readable specs with customizable formatting. Prints the supplied specs to the screen, formatted according to the arguments provided. Specs are grouped by architecture and compiler, and columnized if possible. There are three possible "modes": * ``short`` (default): short specs with name and version, columnized * ``paths``: Two columns: one for specs, one for paths * ``deps``: Dependency-tree style, like ``spack spec``; can get long Options can add more information to the default display. Options can be provided either as keyword arguments or as an argparse namespace. Keyword arguments take precedence over settings in the argparse namespace. Args: specs (list of spack.spec.Spec): the specs to display args (optional argparse.Namespace): namespace containing formatting arguments Keyword Args: mode (str): Either 'short', 'paths', or 'deps' long (bool): Display short hashes with specs very_long (bool): Display full hashes with specs (supersedes ``long``) namespace (bool): Print namespaces along with names show_flags (bool): Show compiler flags with specs variants (bool): Show variants with specs """ def get_arg(name, default=None): """Prefer kwargs, then args, then default.""" if name in kwargs: return kwargs.get(name) elif args is not None: return getattr(args, name, default) else: return default mode = get_arg('mode', 'short') hashes = get_arg('long', False) namespace = get_arg('namespace', False) flags = get_arg('show_flags', False) full_compiler = get_arg('show_full_compiler', False) variants = get_arg('variants', False) hlen = 7 if get_arg('very_long', False): hashes = True hlen = None nfmt = '.' if namespace else '_' ffmt = '' if full_compiler or flags: ffmt += '$%' if full_compiler: ffmt += '@' ffmt += '+' vfmt = '$+' if variants else '' format_string = '$%s$@%s%s' % (nfmt, ffmt, vfmt) # Make a dict with specs keyed by architecture and compiler. index = index_by(specs, ('architecture', 'compiler')) # Traverse the index and print out each package for i, (architecture, compiler) in enumerate(sorted(index)): if i > 0: print() header = "%s{%s} / %s{%s}" % (spack.spec.architecture_color, architecture, spack.spec.compiler_color, compiler) # Sometimes we want to display specs that are not yet concretized. # If they don't have a compiler / architecture attached to them, # then skip the header if architecture is not None or compiler is not None: tty.hline(colorize(header), char='-') specs = index[(architecture, compiler)] specs.sort() abbreviated = [s.cformat(format_string) for s in specs] if mode == 'paths': # Print one spec per line along with prefix path width = max(len(s) for s in abbreviated) width += 2 format = " %%-%ds%%s" % width for abbrv, spec in zip(abbreviated, specs): prefix = gray_hash(spec, hlen) if hashes else '' print(prefix + (format % (abbrv, spec.prefix))) elif mode == 'deps': for spec in specs: print(spec.tree( format=format_string, indent=4, prefix=(lambda s: gray_hash(s, hlen)) if hashes else None)) elif mode == 'short': # Print columns of output if not printing flags if not flags and not full_compiler: def fmt(s): string = "" if hashes: string += gray_hash(s, hlen) + ' ' string += s.cformat('$-%s$@%s' % (nfmt, vfmt)) return string colify(fmt(s) for s in specs) # Print one entry per line if including flags else: for spec in specs: # Print the hash if necessary hsh = gray_hash(spec, hlen) + ' ' if hashes else '' print(hsh + spec.cformat(format_string) + '\n') else: raise ValueError( "Invalid mode for display_specs: %s. Must be one of (paths," "deps, short)." % mode)