summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd Gamblin <gamblin2@llnl.gov>2021-04-08 07:37:16 -0700
committerGitHub <noreply@github.com>2021-04-08 16:37:16 +0200
commit19b6d3589a285031e410aa08e09655c60f5e17a4 (patch)
treea1f932b563d12c51b2c2cf38e26a3a3488a7acc2 /lib
parentf27fefc3c1fc26f1c6aad1d1a125a522078ba779 (diff)
downloadspack-19b6d3589a285031e410aa08e09655c60f5e17a4.tar.gz
spack-19b6d3589a285031e410aa08e09655c60f5e17a4.tar.bz2
spack-19b6d3589a285031e410aa08e09655c60f5e17a4.tar.xz
spack-19b6d3589a285031e410aa08e09655c60f5e17a4.zip
bugfix: `spack config blame` should print all lines of config (#22598)
* bugfix: fix representation of null in spack_yaml output Nulls were previously printed differently by `spack config blame config` and `spack config get config`. Fix this in the `spack_yaml` dumpers. * bugfix: `spack config blame` should print all lines of config `spack config blame` was not printing all lines of configuration because there were no annotations for empty lines in the YAML dump output. Fix this by removing empty lines.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/test/util/spack_yaml.py28
-rw-r--r--lib/spack/spack/util/spack_yaml.py23
2 files changed, 44 insertions, 7 deletions
diff --git a/lib/spack/spack/test/util/spack_yaml.py b/lib/spack/spack/test/util/spack_yaml.py
index 530226ad8d..34a923093f 100644
--- a/lib/spack/spack/test/util/spack_yaml.py
+++ b/lib/spack/spack/test/util/spack_yaml.py
@@ -65,3 +65,31 @@ def test_config_blame_with_override(config):
check_blame('verify_ssl', config_file, 13)
check_blame('checksum', config_file, 14)
check_blame('dirty', config_file, 15)
+
+
+def test_config_blame_defaults():
+ """check blame for an element from an override scope"""
+ files = {}
+
+ def get_file_lines(filename):
+ if filename not in files:
+ with open(filename, "r") as f:
+ files[filename] = [""] + f.read().split("\n")
+ return files[filename]
+
+ config_blame = config_cmd("blame", "config")
+ for line in config_blame.split("\n"):
+ # currently checking only simple lines with dict keys
+ match = re.match(r"^([^:]+):(\d+)\s+([^:]+):\s+(.*)", line)
+
+ # check that matches are on the lines they say they are
+ if match:
+ filename, line, key, val = match.groups()
+ line = int(line)
+
+ if val.lower() in ("true", "false"):
+ val = val.lower()
+
+ lines = get_file_lines(filename)
+ assert key in lines[line]
+ assert val in lines[line]
diff --git a/lib/spack/spack/util/spack_yaml.py b/lib/spack/spack/util/spack_yaml.py
index e27c48860b..24eea88b77 100644
--- a/lib/spack/spack/util/spack_yaml.py
+++ b/lib/spack/spack/util/spack_yaml.py
@@ -13,6 +13,7 @@
"""
import ctypes
+import re
import sys
from typing import List # novm
@@ -185,6 +186,12 @@ class OrderedLineDumper(RoundTripDumper):
"""Make the dumper NEVER print YAML aliases."""
return True
+ def represent_data(self, data):
+ result = super(OrderedLineDumper, self).represent_data(data)
+ if data is None:
+ result.value = syaml_str("null")
+ return result
+
def represent_str(self, data):
if hasattr(data, 'override') and data.override:
data = data + ':'
@@ -262,19 +269,18 @@ class LineAnnotationDumper(OrderedLineDumper):
def represent_data(self, data):
"""Force syaml_str to be passed through with marks."""
result = super(LineAnnotationDumper, self).represent_data(data)
- if isinstance(result.value, string_types):
+ if data is None:
+ result.value = syaml_str("null")
+ elif isinstance(result.value, string_types):
result.value = syaml_str(data)
if markable(result.value):
mark(result.value, data)
return result
- def write_stream_start(self):
- super(LineAnnotationDumper, self).write_stream_start()
- _annotations.append(colorize('@K{---}'))
-
def write_line_break(self):
super(LineAnnotationDumper, self).write_line_break()
- if not self.saved:
+ if self.saved is None:
+ _annotations.append(colorize('@K{---}'))
return
# append annotations at the end of each line
@@ -322,7 +328,10 @@ def dump_annotated(data, stream=None, *args, **kwargs):
sio = StringIO()
yaml.dump(data, sio, *args, **kwargs)
- lines = sio.getvalue().rstrip().split('\n')
+
+ # write_line_break() is not called by YAML for empty lines, so we
+ # skip empty lines here with \n+.
+ lines = re.split(r"\n+", sio.getvalue().rstrip())
getvalue = None
if stream is None: