Add support for nested "overrides" scopes.
This commit is contained in:
parent
b07460ab5f
commit
87cdfa2c25
2 changed files with 72 additions and 2 deletions
|
@ -32,6 +32,7 @@
|
|||
|
||||
import copy
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import multiprocessing
|
||||
from contextlib import contextmanager
|
||||
|
@ -354,6 +355,15 @@ def highest_precedence_scope(self):
|
|||
"""Non-internal scope with highest precedence."""
|
||||
return next(reversed(self.file_scopes), None)
|
||||
|
||||
def matching_scopes(self, reg_expr):
|
||||
"""
|
||||
List of all scopes whose names match the provided regular expression.
|
||||
|
||||
For example, matching_scopes(r'^command') will return all scopes
|
||||
whose names begin with `command`.
|
||||
"""
|
||||
return [s for s in self.scopes.values() if re.search(reg_expr, s.name)]
|
||||
|
||||
def _validate_scope(self, scope):
|
||||
"""Ensure that scope is valid in this configuration.
|
||||
|
||||
|
@ -539,13 +549,25 @@ def override(path_or_scope, value=None):
|
|||
an internal config scope for it and push/pop that scope.
|
||||
|
||||
"""
|
||||
base_name = 'overrides-'
|
||||
if isinstance(path_or_scope, ConfigScope):
|
||||
overrides = path_or_scope
|
||||
config.push_scope(path_or_scope)
|
||||
else:
|
||||
overrides = InternalConfigScope('overrides')
|
||||
# Ensure the new override gets a unique scope name
|
||||
current_overrides = [s.name for s in
|
||||
config.matching_scopes(r'^{0}'.format(base_name))]
|
||||
num_overrides = len(current_overrides)
|
||||
while True:
|
||||
scope_name = '{0}{1}'.format(base_name, num_overrides)
|
||||
if scope_name in current_overrides:
|
||||
num_overrides += 1
|
||||
else:
|
||||
break
|
||||
|
||||
overrides = InternalConfigScope(scope_name)
|
||||
config.push_scope(overrides)
|
||||
config.set(path_or_scope, value, scope='overrides')
|
||||
config.set(path_or_scope, value, scope=scope_name)
|
||||
|
||||
yield config
|
||||
|
||||
|
|
|
@ -627,6 +627,54 @@ def test_add_command_line_scopes(tmpdir, mutable_config):
|
|||
spack.config._add_command_line_scopes(mutable_config, [str(tmpdir)])
|
||||
|
||||
|
||||
@pytest.mark.nomockstage
|
||||
def test_nested_override():
|
||||
"""Ensure proper scope naming of nested overrides."""
|
||||
# WARNING: Base name must match that used in `config.py`s `override()`.
|
||||
base_name = 'overrides-'
|
||||
|
||||
def _check_scopes(num_expected, debug_values):
|
||||
scope_names = [s.name for s in spack.config.config.scopes.values()]
|
||||
|
||||
for i in range(num_expected):
|
||||
name = '{0}{1}'.format(base_name, i)
|
||||
assert name in scope_names
|
||||
|
||||
data = spack.config.config.get_config('config', name)
|
||||
assert data['debug'] == debug_values[i]
|
||||
|
||||
# Check results from single and nested override
|
||||
with spack.config.override('config:debug', True):
|
||||
with spack.config.override('config:debug', False):
|
||||
_check_scopes(2, [True, False])
|
||||
|
||||
_check_scopes(1, [True])
|
||||
|
||||
|
||||
@pytest.mark.nomockstage
|
||||
def test_alternate_override(monkeypatch):
|
||||
"""Ensure proper scope naming of override when conflict present."""
|
||||
# WARNING: Base name must match that used in `config.py`s `override()`.
|
||||
base_name = 'overrides-'
|
||||
|
||||
def _matching_scopes(regexpr):
|
||||
return [spack.config.InternalConfigScope('{0}1'.format(base_name))]
|
||||
|
||||
# Check that the alternate naming works
|
||||
monkeypatch.setattr(spack.config.config, 'matching_scopes',
|
||||
_matching_scopes)
|
||||
|
||||
with spack.config.override('config:debug', False):
|
||||
name = '{0}2'.format(base_name)
|
||||
|
||||
scope_names = [s.name for s in spack.config.config.scopes.values() if
|
||||
s.name.startswith(base_name)]
|
||||
assert name in scope_names
|
||||
|
||||
data = spack.config.config.get_config('config', name)
|
||||
assert data['debug'] is False
|
||||
|
||||
|
||||
def test_immutable_scope(tmpdir):
|
||||
config_yaml = str(tmpdir.join('config.yaml'))
|
||||
with open(config_yaml, 'w') as f:
|
||||
|
|
Loading…
Reference in a new issue