Skip to content
Snippets Groups Projects
Commit 76d18e3a authored by Todd Gamblin's avatar Todd Gamblin
Browse files

bugfix: fix config merge order for OrderdDicts

The logic in `config.py` merges lists correctly so that list elements
from higher-precedence config files come first, but the way we merge
`dict` elements reverses the precedence.

Since `mirrors.yaml` relies on `OrderedDict` for precedence, this bug
causes mirrors in lower-precedence config scopes to be checked before
higher-precedence scopes.

We should probably convert `mirrors.yaml` to use a list at some point,
but in the meantie here's a fix for `OrderedDict`.

- [x] ensuring that keys are ordered correctly in `OrderedDict` by
  re-inserting keys from the destination `dict` after adding the keys from
  the source `dict`.

Assuming a default spack configuration, if we run this:

```console
$ spack mirror add foo https://bar.com
```

Results before this change:

```console
$ spack config blame mirrors
---                                                          mirrors:
/Users/gamblin2/src/spack/etc/spack/defaults/mirrors.yaml:2    spack-public: https://spack-llnl-mirror.s3-us-west-2.amazonaws.com/
/Users/gamblin2/.spack/mirrors.yaml:2                          foo: https://bar.com
```

Results after:

```console
$ spack config blame mirrors
---                                                          mirrors:
/Users/gamblin2/.spack/mirrors.yaml:2                          foo: https://bar.com
/Users/gamblin2/src/spack/etc/spack/defaults/mirrors.yaml:2    spack-public: https://spack-llnl-mirror.s3-us-west-2.amazonaws.com/
```
parent 665e5ce0
No related tags found
No related merge requests found
...@@ -944,6 +944,10 @@ def they_are(t): ...@@ -944,6 +944,10 @@ def they_are(t):
# track keys for marking # track keys for marking
key_marks = {} key_marks = {}
# track this to ensure that source items come *before* dest in
# iteration order with OrderdDicts
dest_keys = [dk for dk in dest.keys() if dk not in source]
for sk, sv in iteritems(source): for sk, sv in iteritems(source):
if _override(sk) or sk not in dest: if _override(sk) or sk not in dest:
# if sk ended with ::, or if it's new, completely override # if sk ended with ::, or if it's new, completely override
...@@ -958,6 +962,12 @@ def they_are(t): ...@@ -958,6 +962,12 @@ def they_are(t):
# to copy mark information on source keys to dest. # to copy mark information on source keys to dest.
key_marks[sk] = sk key_marks[sk] = sk
# ensure that dest keys come after source
for dk in dest_keys:
value = dest[dk]
del dest[dk]
dest[dk] = value
# ensure that keys are marked in the destination. The # ensure that keys are marked in the destination. The
# key_marks dict ensures we can get the actual source key # key_marks dict ensures we can get the actual source key
# objects from dest keys # objects from dest keys
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment