Add --color=[always|never|auto] argument; fix color when piping (#3013)
* Disable spec colorization when redirecting stdout and add command line flag to re-enable * Add command line `--color` flag to control output colorization * Add options to `llnl.util.tty.color` to allow color to be auto/always/never * Add `Spec.cformat()` function to be used when `format()` should have auto-coloring
This commit is contained in:
parent
f3c70c235c
commit
1c7e5724d9
@ -80,6 +80,7 @@
|
|||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
|
||||||
class ColorParseError(Exception):
|
class ColorParseError(Exception):
|
||||||
@ -107,15 +108,62 @@ def __init__(self, message):
|
|||||||
# Regex to be used for color formatting
|
# Regex to be used for color formatting
|
||||||
color_re = r'@(?:@|\.|([*_])?([a-zA-Z])?(?:{((?:[^}]|}})*)})?)'
|
color_re = r'@(?:@|\.|([*_])?([a-zA-Z])?(?:{((?:[^}]|}})*)})?)'
|
||||||
|
|
||||||
|
# Mapping from color arguments to values for tty.set_color
|
||||||
|
color_when_values = {
|
||||||
|
'always': True,
|
||||||
|
'auto': None,
|
||||||
|
'never': False
|
||||||
|
}
|
||||||
|
|
||||||
# Force color even if stdout is not a tty.
|
# Force color; None: Only color if stdout is a tty
|
||||||
_force_color = False
|
# True: Always colorize output, False: Never colorize output
|
||||||
|
_force_color = None
|
||||||
|
|
||||||
|
|
||||||
|
def _color_when_value(when):
|
||||||
|
"""Raise a ValueError for an invalid color setting.
|
||||||
|
|
||||||
|
Valid values are 'always', 'never', and 'auto', or equivalently,
|
||||||
|
True, False, and None.
|
||||||
|
"""
|
||||||
|
if when in color_when_values:
|
||||||
|
return color_when_values[when]
|
||||||
|
elif when not in color_when_values.values():
|
||||||
|
raise ValueError('Invalid color setting: %s' % when)
|
||||||
|
return when
|
||||||
|
|
||||||
|
|
||||||
|
def get_color_when():
|
||||||
|
"""Return whether commands should print color or not."""
|
||||||
|
if _force_color is not None:
|
||||||
|
return _force_color
|
||||||
|
return sys.stdout.isatty()
|
||||||
|
|
||||||
|
|
||||||
|
def set_color_when(when):
|
||||||
|
"""Set when color should be applied. Options are:
|
||||||
|
|
||||||
|
* True or 'always': always print color
|
||||||
|
* False or 'never': never print color
|
||||||
|
* None or 'auto': only print color if sys.stdout is a tty.
|
||||||
|
"""
|
||||||
|
global _force_color
|
||||||
|
_force_color = _color_when_value(when)
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def color_when(value):
|
||||||
|
"""Context manager to temporarily use a particular color setting."""
|
||||||
|
old_value = value
|
||||||
|
set_color(value)
|
||||||
|
yield
|
||||||
|
set_color(old_value)
|
||||||
|
|
||||||
|
|
||||||
class match_to_ansi(object):
|
class match_to_ansi(object):
|
||||||
|
|
||||||
def __init__(self, color=True):
|
def __init__(self, color=True):
|
||||||
self.color = color
|
self.color = _color_when_value(color)
|
||||||
|
|
||||||
def escape(self, s):
|
def escape(self, s):
|
||||||
"""Returns a TTY escape sequence for a color"""
|
"""Returns a TTY escape sequence for a color"""
|
||||||
@ -166,7 +214,7 @@ def colorize(string, **kwargs):
|
|||||||
color (bool): If False, output will be plain text without control
|
color (bool): If False, output will be plain text without control
|
||||||
codes, for output to non-console devices.
|
codes, for output to non-console devices.
|
||||||
"""
|
"""
|
||||||
color = kwargs.get('color', True)
|
color = _color_when_value(kwargs.get('color', get_color_when()))
|
||||||
return re.sub(color_re, match_to_ansi(color), string)
|
return re.sub(color_re, match_to_ansi(color), string)
|
||||||
|
|
||||||
|
|
||||||
@ -188,7 +236,7 @@ def cwrite(string, stream=sys.stdout, color=None):
|
|||||||
then it will be set based on stream.isatty().
|
then it will be set based on stream.isatty().
|
||||||
"""
|
"""
|
||||||
if color is None:
|
if color is None:
|
||||||
color = stream.isatty() or _force_color
|
color = get_color_when()
|
||||||
stream.write(colorize(string, color=color))
|
stream.write(colorize(string, color=color))
|
||||||
|
|
||||||
|
|
||||||
@ -217,7 +265,7 @@ def write(self, string, **kwargs):
|
|||||||
if raw:
|
if raw:
|
||||||
color = True
|
color = True
|
||||||
else:
|
else:
|
||||||
color = self._stream.isatty() or _force_color
|
color = get_color_when()
|
||||||
raw_write(colorize(string, color=color))
|
raw_write(colorize(string, color=color))
|
||||||
|
|
||||||
def writelines(self, sequence, **kwargs):
|
def writelines(self, sequence, **kwargs):
|
||||||
|
@ -154,9 +154,8 @@ def disambiguate_spec(spec):
|
|||||||
elif len(matching_specs) > 1:
|
elif len(matching_specs) > 1:
|
||||||
args = ["%s matches multiple packages." % spec,
|
args = ["%s matches multiple packages." % spec,
|
||||||
"Matching packages:"]
|
"Matching packages:"]
|
||||||
color = sys.stdout.isatty()
|
args += [colorize(" @K{%s} " % s.dag_hash(7)) +
|
||||||
args += [colorize(" @K{%s} " % s.dag_hash(7), color=color) +
|
s.cformat('$_$@$%@$=') for s in matching_specs]
|
||||||
s.format('$_$@$%@$=', color=color) for s in matching_specs]
|
|
||||||
args += ["Use a more specific spec."]
|
args += ["Use a more specific spec."]
|
||||||
tty.die(*args)
|
tty.die(*args)
|
||||||
|
|
||||||
@ -200,7 +199,7 @@ def display_specs(specs, **kwargs):
|
|||||||
specs = index[(architecture, compiler)]
|
specs = index[(architecture, compiler)]
|
||||||
specs.sort()
|
specs.sort()
|
||||||
|
|
||||||
abbreviated = [s.format(format_string, color=True) for s in specs]
|
abbreviated = [s.cformat(format_string) for s in specs]
|
||||||
if mode == 'paths':
|
if mode == 'paths':
|
||||||
# Print one spec per line along with prefix path
|
# Print one spec per line along with prefix path
|
||||||
width = max(len(s) for s in abbreviated)
|
width = max(len(s) for s in abbreviated)
|
||||||
@ -215,7 +214,6 @@ def display_specs(specs, **kwargs):
|
|||||||
for spec in specs:
|
for spec in specs:
|
||||||
print(spec.tree(
|
print(spec.tree(
|
||||||
format=format_string,
|
format=format_string,
|
||||||
color=True,
|
|
||||||
indent=4,
|
indent=4,
|
||||||
prefix=(lambda s: gray_hash(s, hlen)) if hashes else None))
|
prefix=(lambda s: gray_hash(s, hlen)) if hashes else None))
|
||||||
|
|
||||||
@ -227,7 +225,7 @@ def fmt(s):
|
|||||||
string = ""
|
string = ""
|
||||||
if hashes:
|
if hashes:
|
||||||
string += gray_hash(s, hlen) + ' '
|
string += gray_hash(s, hlen) + ' '
|
||||||
string += s.format('$-%s$@%s' % (nfmt, vfmt), color=True)
|
string += s.cformat('$-%s$@%s' % (nfmt, vfmt))
|
||||||
|
|
||||||
return string
|
return string
|
||||||
|
|
||||||
@ -237,7 +235,7 @@ def fmt(s):
|
|||||||
for spec in specs:
|
for spec in specs:
|
||||||
# Print the hash if necessary
|
# Print the hash if necessary
|
||||||
hsh = gray_hash(spec, hlen) + ' ' if hashes else ''
|
hsh = gray_hash(spec, hlen) + ' ' if hashes else ''
|
||||||
print(hsh + spec.format(format_string, color=True) + '\n')
|
print(hsh + spec.cformat(format_string) + '\n')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
|
@ -47,7 +47,7 @@ def dependents(parser, args):
|
|||||||
tty.die("spack dependents takes only one spec.")
|
tty.die("spack dependents takes only one spec.")
|
||||||
spec = spack.cmd.disambiguate_spec(specs[0])
|
spec = spack.cmd.disambiguate_spec(specs[0])
|
||||||
|
|
||||||
tty.msg("Dependents of %s" % spec.format('$_$@$%@$/', color=True))
|
tty.msg("Dependents of %s" % spec.cformat('$_$@$%@$/'))
|
||||||
deps = spack.store.db.installed_dependents(spec)
|
deps = spack.store.db.installed_dependents(spec)
|
||||||
if deps:
|
if deps:
|
||||||
spack.cmd.display_specs(deps)
|
spack.cmd.display_specs(deps)
|
||||||
|
@ -213,7 +213,7 @@ def mirror_create(args):
|
|||||||
" %-4d failed to fetch." % e)
|
" %-4d failed to fetch." % e)
|
||||||
if error:
|
if error:
|
||||||
tty.error("Failed downloads:")
|
tty.error("Failed downloads:")
|
||||||
colify(s.format("$_$@") for s in error)
|
colify(s.cformat("$_$@") for s in error)
|
||||||
|
|
||||||
|
|
||||||
def mirror(parser, args):
|
def mirror(parser, args):
|
||||||
|
@ -236,7 +236,8 @@ def refresh(mtype, specs, args):
|
|||||||
if len(writer_list) > 1:
|
if len(writer_list) > 1:
|
||||||
message += '\nfile: {0}\n'.format(filename)
|
message += '\nfile: {0}\n'.format(filename)
|
||||||
for x in writer_list:
|
for x in writer_list:
|
||||||
message += 'spec: {0}\n'.format(x.spec.format(color=True))
|
message += 'spec: {0}\n'.format(x.spec.format())
|
||||||
|
|
||||||
tty.error(message)
|
tty.error(message)
|
||||||
tty.error('Operation aborted')
|
tty.error('Operation aborted')
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
@ -269,7 +270,7 @@ def module(parser, args):
|
|||||||
"and this is not allowed in this context")
|
"and this is not allowed in this context")
|
||||||
tty.error(message.format(query=constraint))
|
tty.error(message.format(query=constraint))
|
||||||
for s in specs:
|
for s in specs:
|
||||||
sys.stderr.write(s.format(color=True) + '\n')
|
sys.stderr.write(s.cformat() + '\n')
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
except NoMatch:
|
except NoMatch:
|
||||||
message = ("the constraint '{query}' matches no package, "
|
message = ("the constraint '{query}' matches no package, "
|
||||||
|
@ -60,8 +60,7 @@ def setup_parser(subparser):
|
|||||||
|
|
||||||
def spec(parser, args):
|
def spec(parser, args):
|
||||||
name_fmt = '$.' if args.namespaces else '$_'
|
name_fmt = '$.' if args.namespaces else '$_'
|
||||||
kwargs = {'color': True,
|
kwargs = {'cover': args.cover,
|
||||||
'cover': args.cover,
|
|
||||||
'format': name_fmt + '$@$%@+$+$=',
|
'format': name_fmt + '$@$%@+$+$=',
|
||||||
'hashes': args.long or args.very_long,
|
'hashes': args.long or args.very_long,
|
||||||
'hashlen': None if args.very_long else 7,
|
'hashlen': None if args.very_long else 7,
|
||||||
|
@ -180,8 +180,7 @@ def get_uninstall_list(args):
|
|||||||
has_error = False
|
has_error = False
|
||||||
if dependent_list and not args.dependents and not args.force:
|
if dependent_list and not args.dependents and not args.force:
|
||||||
for spec, lst in dependent_list.items():
|
for spec, lst in dependent_list.items():
|
||||||
tty.error('Will not uninstall {0}'.format(
|
tty.error("Will not uninstall %s" % spec.cformat("$_$@$%@$/"))
|
||||||
spec.format("$_$@$%@$/", color=True)))
|
|
||||||
print('')
|
print('')
|
||||||
print('The following packages depend on it:')
|
print('The following packages depend on it:')
|
||||||
spack.cmd.display_specs(lst, **display_args)
|
spack.cmd.display_specs(lst, **display_args)
|
||||||
|
@ -288,7 +288,7 @@ def _assign_dependencies(self, hash_key, installs, data):
|
|||||||
if dhash not in data:
|
if dhash not in data:
|
||||||
tty.warn("Missing dependency not in database: ",
|
tty.warn("Missing dependency not in database: ",
|
||||||
"%s needs %s-%s" % (
|
"%s needs %s-%s" % (
|
||||||
spec.format('$_$/'), dname, dhash[:7]))
|
spec.cformat('$_$/'), dname, dhash[:7]))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
child = data[dhash].spec
|
child = data[dhash].spec
|
||||||
@ -440,8 +440,7 @@ def _read_suppress_error():
|
|||||||
# just to be conservative in case a command like
|
# just to be conservative in case a command like
|
||||||
# "autoremove" is run by the user after a reindex.
|
# "autoremove" is run by the user after a reindex.
|
||||||
tty.debug(
|
tty.debug(
|
||||||
'RECONSTRUCTING FROM SPEC.YAML: {0}'.format(spec)
|
'RECONSTRUCTING FROM SPEC.YAML: {0}'.format(spec))
|
||||||
)
|
|
||||||
explicit = True
|
explicit = True
|
||||||
if old_data is not None:
|
if old_data is not None:
|
||||||
old_info = old_data.get(spec.dag_hash())
|
old_info = old_data.get(spec.dag_hash())
|
||||||
@ -467,8 +466,7 @@ def _read_suppress_error():
|
|||||||
# installed compilers or externally installed
|
# installed compilers or externally installed
|
||||||
# applications.
|
# applications.
|
||||||
tty.debug(
|
tty.debug(
|
||||||
'RECONSTRUCTING FROM OLD DB: {0}'.format(entry.spec)
|
'RECONSTRUCTING FROM OLD DB: {0}'.format(entry.spec))
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
layout = spack.store.layout
|
layout = spack.store.layout
|
||||||
if entry.spec.external:
|
if entry.spec.external:
|
||||||
|
@ -168,7 +168,9 @@ def __init__(self, root, **kwargs):
|
|||||||
self.metadata_dir = kwargs.get('metadata_dir', '.spack')
|
self.metadata_dir = kwargs.get('metadata_dir', '.spack')
|
||||||
self.hash_len = kwargs.get('hash_len')
|
self.hash_len = kwargs.get('hash_len')
|
||||||
self.path_scheme = kwargs.get('path_scheme') or (
|
self.path_scheme = kwargs.get('path_scheme') or (
|
||||||
"${ARCHITECTURE}/${COMPILERNAME}-${COMPILERVER}/${PACKAGE}-${VERSION}-${HASH}") # NOQA: E501
|
"${ARCHITECTURE}/"
|
||||||
|
"${COMPILERNAME}-${COMPILERVER}/"
|
||||||
|
"${PACKAGE}-${VERSION}-${HASH}")
|
||||||
if self.hash_len is not None:
|
if self.hash_len is not None:
|
||||||
if re.search('\${HASH:\d+}', self.path_scheme):
|
if re.search('\${HASH:\d+}', self.path_scheme):
|
||||||
raise InvalidDirectoryLayoutParametersError(
|
raise InvalidDirectoryLayoutParametersError(
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
# control top-level spack options shown in basic vs. advanced help
|
# control top-level spack options shown in basic vs. advanced help
|
||||||
options_by_level = {
|
options_by_level = {
|
||||||
'short': 'hkV',
|
'short': ['h', 'k', 'V', 'color'],
|
||||||
'long': 'all'
|
'long': 'all'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,6 +280,9 @@ def make_argument_parser():
|
|||||||
|
|
||||||
parser.add_argument('-h', '--help', action='store_true',
|
parser.add_argument('-h', '--help', action='store_true',
|
||||||
help="show this help message and exit")
|
help="show this help message and exit")
|
||||||
|
parser.add_argument('--color', action='store', default='auto',
|
||||||
|
choices=('always', 'never', 'auto'),
|
||||||
|
help="when to colorize output; default is auto")
|
||||||
parser.add_argument('-d', '--debug', action='store_true',
|
parser.add_argument('-d', '--debug', action='store_true',
|
||||||
help="write out debug logs during compile")
|
help="write out debug logs during compile")
|
||||||
parser.add_argument('-D', '--pdb', action='store_true',
|
parser.add_argument('-D', '--pdb', action='store_true',
|
||||||
@ -325,6 +328,9 @@ def setup_main_options(args):
|
|||||||
tty.warn("You asked for --insecure. Will NOT check SSL certificates.")
|
tty.warn("You asked for --insecure. Will NOT check SSL certificates.")
|
||||||
spack.insecure = True
|
spack.insecure = True
|
||||||
|
|
||||||
|
# when to use color (takes always, auto, or never)
|
||||||
|
tty.color.set_color_when(args.color)
|
||||||
|
|
||||||
|
|
||||||
def allows_unknown_args(command):
|
def allows_unknown_args(command):
|
||||||
"""Implements really simple argument injection for unknown arguments.
|
"""Implements really simple argument injection for unknown arguments.
|
||||||
|
@ -224,14 +224,14 @@ def add_single_spec(spec, mirror_root, categories, **kwargs):
|
|||||||
# create a subdirectory for the current package@version
|
# create a subdirectory for the current package@version
|
||||||
archive_path = os.path.abspath(join_path(
|
archive_path = os.path.abspath(join_path(
|
||||||
mirror_root, mirror_archive_path(spec, fetcher)))
|
mirror_root, mirror_archive_path(spec, fetcher)))
|
||||||
name = spec.format("$_$@")
|
name = spec.cformat("$_$@")
|
||||||
else:
|
else:
|
||||||
resource = stage.resource
|
resource = stage.resource
|
||||||
archive_path = os.path.abspath(join_path(
|
archive_path = os.path.abspath(join_path(
|
||||||
mirror_root,
|
mirror_root,
|
||||||
mirror_archive_path(spec, fetcher, resource.name)))
|
mirror_archive_path(spec, fetcher, resource.name)))
|
||||||
name = "{resource} ({pkg}).".format(
|
name = "{resource} ({pkg}).".format(
|
||||||
resource=resource.name, pkg=spec.format("$_$@"))
|
resource=resource.name, pkg=spec.cformat("$_$@"))
|
||||||
subdir = os.path.dirname(archive_path)
|
subdir = os.path.dirname(archive_path)
|
||||||
mkdirp(subdir)
|
mkdirp(subdir)
|
||||||
|
|
||||||
@ -258,8 +258,8 @@ def add_single_spec(spec, mirror_root, categories, **kwargs):
|
|||||||
if spack.debug:
|
if spack.debug:
|
||||||
sys.excepthook(*sys.exc_info())
|
sys.excepthook(*sys.exc_info())
|
||||||
else:
|
else:
|
||||||
tty.warn("Error while fetching %s"
|
tty.warn(
|
||||||
% spec.format('$_$@'), e.message)
|
"Error while fetching %s" % spec.cformat('$_$@'), e.message)
|
||||||
categories['error'].append(spec)
|
categories['error'].append(spec)
|
||||||
|
|
||||||
|
|
||||||
|
@ -905,7 +905,7 @@ def do_fetch(self, mirror_only=False):
|
|||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
if spack.do_checksum and self.version not in self.versions:
|
if spack.do_checksum and self.version not in self.versions:
|
||||||
tty.warn("There is no checksum on file to fetch %s safely." %
|
tty.warn("There is no checksum on file to fetch %s safely." %
|
||||||
self.spec.format('$_$@'))
|
self.spec.cformat('$_$@'))
|
||||||
|
|
||||||
# Ask the user whether to skip the checksum if we're
|
# Ask the user whether to skip the checksum if we're
|
||||||
# interactive, but just fail if non-interactive.
|
# interactive, but just fail if non-interactive.
|
||||||
@ -1649,8 +1649,9 @@ def do_activate(self, force=False):
|
|||||||
self.extendee_spec.package.activate(self, **self.extendee_args)
|
self.extendee_spec.package.activate(self, **self.extendee_args)
|
||||||
|
|
||||||
spack.store.layout.add_extension(self.extendee_spec, self.spec)
|
spack.store.layout.add_extension(self.extendee_spec, self.spec)
|
||||||
tty.msg("Activated extension %s for %s" %
|
tty.msg(
|
||||||
(self.spec.short_spec, self.extendee_spec.format("$_$@$+$%@")))
|
"Activated extension %s for %s" %
|
||||||
|
(self.spec.short_spec, self.extendee_spec.cformat("$_$@$+$%@")))
|
||||||
|
|
||||||
def dependency_activations(self):
|
def dependency_activations(self):
|
||||||
return (spec for spec in self.spec.traverse(root=False, deptype='run')
|
return (spec for spec in self.spec.traverse(root=False, deptype='run')
|
||||||
@ -1708,8 +1709,9 @@ def do_deactivate(self, **kwargs):
|
|||||||
spack.store.layout.remove_extension(
|
spack.store.layout.remove_extension(
|
||||||
self.extendee_spec, self.spec)
|
self.extendee_spec, self.spec)
|
||||||
|
|
||||||
tty.msg("Deactivated extension %s for %s" %
|
tty.msg(
|
||||||
(self.spec.short_spec, self.extendee_spec.format("$_$@$+$%@")))
|
"Deactivated extension %s for %s" %
|
||||||
|
(self.spec.short_spec, self.extendee_spec.cformat("$_$@$+$%@")))
|
||||||
|
|
||||||
def deactivate(self, extension, **kwargs):
|
def deactivate(self, extension, **kwargs):
|
||||||
"""Unlinks all files from extension out of this package's install dir.
|
"""Unlinks all files from extension out of this package's install dir.
|
||||||
|
@ -108,6 +108,10 @@
|
|||||||
from six import string_types
|
from six import string_types
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
|
|
||||||
|
from llnl.util.filesystem import find_headers, find_libraries, is_exe
|
||||||
|
from llnl.util.lang import *
|
||||||
|
from llnl.util.tty.color import *
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.architecture
|
import spack.architecture
|
||||||
import spack.compilers as compilers
|
import spack.compilers as compilers
|
||||||
@ -117,9 +121,6 @@
|
|||||||
import spack.util.spack_json as sjson
|
import spack.util.spack_json as sjson
|
||||||
import spack.util.spack_yaml as syaml
|
import spack.util.spack_yaml as syaml
|
||||||
|
|
||||||
from llnl.util.filesystem import find_headers, find_libraries, is_exe
|
|
||||||
from llnl.util.lang import *
|
|
||||||
from llnl.util.tty.color import *
|
|
||||||
from spack.util.module_cmd import get_path_from_module, load_module
|
from spack.util.module_cmd import get_path_from_module, load_module
|
||||||
from spack.error import SpecError, UnsatisfiableSpecError
|
from spack.error import SpecError, UnsatisfiableSpecError
|
||||||
from spack.provider_index import ProviderIndex
|
from spack.provider_index import ProviderIndex
|
||||||
@ -1363,9 +1364,8 @@ def short_spec(self):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def cshort_spec(self):
|
def cshort_spec(self):
|
||||||
"""Returns a version of the spec with the dependencies hashed
|
"""Returns an auto-colorized version of ``self.short_spec``."""
|
||||||
instead of completely enumerated."""
|
return self.cformat('$_$@$%@$+$=$/')
|
||||||
return self.format('$_$@$%@$+$=$/', color=True)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def prefix(self):
|
def prefix(self):
|
||||||
@ -2852,6 +2852,12 @@ def write(s, c):
|
|||||||
result = out.getvalue()
|
result = out.getvalue()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def cformat(self, *args, **kwargs):
|
||||||
|
"""Same as format, but color defaults to auto instead of False."""
|
||||||
|
kwargs = kwargs.copy()
|
||||||
|
kwargs.setdefault('color', None)
|
||||||
|
return self.format(*args, **kwargs)
|
||||||
|
|
||||||
def dep_string(self):
|
def dep_string(self):
|
||||||
return ''.join("^" + dep.format() for dep in self.sorted_deps())
|
return ''.join("^" + dep.format() for dep in self.sorted_deps())
|
||||||
|
|
||||||
@ -2882,7 +2888,7 @@ def _installed_explicitly(self):
|
|||||||
def tree(self, **kwargs):
|
def tree(self, **kwargs):
|
||||||
"""Prints out this spec and its dependencies, tree-formatted
|
"""Prints out this spec and its dependencies, tree-formatted
|
||||||
with indentation."""
|
with indentation."""
|
||||||
color = kwargs.pop('color', False)
|
color = kwargs.pop('color', get_color_when())
|
||||||
depth = kwargs.pop('depth', False)
|
depth = kwargs.pop('depth', False)
|
||||||
hashes = kwargs.pop('hashes', False)
|
hashes = kwargs.pop('hashes', False)
|
||||||
hlen = kwargs.pop('hashlen', None)
|
hlen = kwargs.pop('hashlen', None)
|
||||||
|
@ -115,7 +115,8 @@ function _spack {
|
|||||||
if $list_options
|
if $list_options
|
||||||
then
|
then
|
||||||
compgen -W "-h --help -d --debug -D --pdb -k --insecure -m --mock -p
|
compgen -W "-h --help -d --debug -D --pdb -k --insecure -m --mock -p
|
||||||
--profile -v --verbose -s --stacktrace -V --version" -- "$cur"
|
--profile -v --verbose -s --stacktrace -V --version
|
||||||
|
--color --color=always --color=auto --color=never" -- "$cur"
|
||||||
else
|
else
|
||||||
compgen -W "$(_subcommands)" -- "$cur"
|
compgen -W "$(_subcommands)" -- "$cur"
|
||||||
fi
|
fi
|
||||||
|
Loading…
Reference in New Issue
Block a user