diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2021-08-06 17:31:27 -0700 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2021-08-09 01:42:07 -0700 |
commit | 7ddd6ad4614316143b8af7e13a9668e22b8dabe7 (patch) | |
tree | b49f9edbdff57c409d7e2749f9d307edc9d83a22 /lib/spack/llnl/util/tty | |
parent | 29098a1e07ba68c4e0eb85ad2cdff27478495222 (diff) | |
download | spack-7ddd6ad4614316143b8af7e13a9668e22b8dabe7.tar.gz spack-7ddd6ad4614316143b8af7e13a9668e22b8dabe7.tar.bz2 spack-7ddd6ad4614316143b8af7e13a9668e22b8dabe7.tar.xz spack-7ddd6ad4614316143b8af7e13a9668e22b8dabe7.zip |
installation: filter padding from all `tty` output
This is both a bugfix and a generalization of #25168. In #25168, we attempted to filter padding
*just* from the debug output of `spack.util.executable.Executable` objects. It turns out we got it
wrong -- filtering the command line string instead of the arg list resulted in output like this:
```
==> [2021-08-05-21:34:19.918576] ["'", '/', 'b', 'i', 'n', '/', 't', 'a', 'r', "'", ' ', "'", '-', 'o', 'x', 'f', "'", ' ', "'", '/', 't', 'm', 'p', '/', 'r', 'o', 'o', 't', '/', 's', 'p', 'a', 'c', 'k', '-', 's', 't', 'a', 'g', 'e', '/', 's', 'p', 'a', 'c', 'k', '-', 's', 't', 'a', 'g', 'e', '-', 'p', 'a', 't', 'c', 'h', 'e', 'l', 'f', '-', '0', '.', '1', '3', '-', 'w', 'p', 'h', 'p', 't', 'l', 'h', 'w', 'u', 's', 'e', 'i', 'a', '4', 'k', 'p', 'g', 'y', 'd', 'q', 'l', 'l', 'i', '2', '4', 'q', 'b', '5', '5', 'q', 'u', '4', '/', 'p', 'a', 't', 'c', 'h', 'e', 'l', 'f', '-', '0', '.', '1', '3', '.', 't', 'a', 'r', '.', 'b', 'z', '2', "'"]
```
Additionally, plenty of builds output padded paths in other plcaes -- e.g., not just command
arguments, but in other `tty` messages via `llnl.util.filesystem` and other places. `Executable`
isn't really the right place for this.
This PR reverts the changes to `Executable` and moves the filtering into `llnl.util.tty`. There is
now a context manager there that you can use to install a filter for all output.
`spack.installer.build_process()` now uses this context manager to make `tty` do path filtering
when padding is enabled.
- [x] revert filtering in `Executable`
- [x] add ability for `tty` to filter output
- [x] install output filter in `build_process()`
- [x] tests
Diffstat (limited to 'lib/spack/llnl/util/tty')
-rw-r--r-- | lib/spack/llnl/util/tty/__init__.py | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/lib/spack/llnl/util/tty/__init__.py b/lib/spack/llnl/util/tty/__init__.py index 987e226d5d..ca3b5c4b8d 100644 --- a/lib/spack/llnl/util/tty/__init__.py +++ b/lib/spack/llnl/util/tty/__init__.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals +import contextlib import fcntl import os import struct @@ -28,6 +29,7 @@ _timestamp = False _msg_enabled = True _warn_enabled = True _error_enabled = True +_output_filter = lambda s: s indent = " " @@ -90,6 +92,18 @@ def error_enabled(): return _error_enabled +@contextlib.contextmanager +def output_filter(filter_fn): + """Context manager that applies a filter to all output.""" + global _output_filter + saved_filter = _output_filter + try: + _output_filter = filter_fn + yield + finally: + _output_filter = saved_filter + + class SuppressOutput: """Class for disabling output in a scope using 'with' keyword""" @@ -166,13 +180,23 @@ def msg(message, *args, **kwargs): if _stacktrace: st_text = process_stacktrace(2) if newline: - cprint("@*b{%s==>} %s%s" % ( - st_text, get_timestamp(), cescape(message))) + cprint( + "@*b{%s==>} %s%s" % ( + st_text, + get_timestamp(), + cescape(_output_filter(message)) + ) + ) else: - cwrite("@*b{%s==>} %s%s" % ( - st_text, get_timestamp(), cescape(message))) + cwrite( + "@*b{%s==>} %s%s" % ( + st_text, + get_timestamp(), + cescape(_output_filter(message)) + ) + ) for arg in args: - print(indent + six.text_type(arg)) + print(indent + _output_filter(six.text_type(arg))) def info(message, *args, **kwargs): @@ -188,18 +212,29 @@ def info(message, *args, **kwargs): st_text = "" if _stacktrace: st_text = process_stacktrace(st_countback) - cprint("@%s{%s==>} %s%s" % ( - format, st_text, get_timestamp(), cescape(six.text_type(message)) - ), stream=stream) + cprint( + "@%s{%s==>} %s%s" % ( + format, + st_text, + get_timestamp(), + cescape(_output_filter(six.text_type(message))) + ), + stream=stream + ) for arg in args: if wrap: lines = textwrap.wrap( - six.text_type(arg), initial_indent=indent, - subsequent_indent=indent, break_long_words=break_long_words) + _output_filter(six.text_type(arg)), + initial_indent=indent, + subsequent_indent=indent, + break_long_words=break_long_words + ) for line in lines: stream.write(line + '\n') else: - stream.write(indent + six.text_type(arg) + '\n') + stream.write( + indent + _output_filter(six.text_type(arg)) + '\n' + ) def verbose(message, *args, **kwargs): |