From ae318381933dad72b1c938802db39d22d50672da Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Sun, 22 Jun 2014 10:07:49 -0700 Subject: Enable allow_no_value for config parser. - Will be useful for, e.g., mirror lists. - Previously didn't properly override regex used when no-value fields are allowed. --- lib/spack/spack/config.py | 72 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py index 9081a96b7b..00ff4313a2 100644 --- a/lib/spack/spack/config.py +++ b/lib/spack/spack/config.py @@ -83,8 +83,8 @@ like the one shown above. import os import re import inspect -from collections import OrderedDict import ConfigParser as cp +from collections import OrderedDict from llnl.util.lang import memoized @@ -112,7 +112,10 @@ _section_regex = r'^([\w-]*)\s*' \ r'\"([^"]*\)\"$' -def get_config(scope=None): +# Cache of configs -- we memoize this for performance. +_config = {} + +def get_config(scope=None, **kwargs): """Get a Spack configuration object, which can be used to set options. With no arguments, this returns a SpackConfigParser with config @@ -124,13 +127,33 @@ def get_config(scope=None): options from that scope's configuration file are loaded. The caller can set or unset options, then call ``write()`` on the config object to write it back out to the original config file. + + By default, this will cache configurations and return the last + read version of the config file. If the config file is + modified and you need to refresh, call get_config with the + refresh=True keyword argument. This will force all files to be + re-read. """ - if scope is None: - return SpackConfigParser() - elif scope not in _scopes: + refresh = kwargs.get('refresh', False) + if refresh: + _config.clear() + + if scope not in _config: + if scope is None: + _config[scope] = SpackConfigParser([path for path in _scopes.values()]) + elif scope not in _scopes: + raise UnknownConfigurationScopeError(scope) + else: + _config[scope] = SpackConfigParser(_scopes[scope]) + + return _config[scope] + + +def get_filename(scope): + """Get the filename for a particular config scope.""" + if not scope in _scopes: raise UnknownConfigurationScopeError(scope) - else: - return SpackConfigParser(_scopes[scope]) + return _scopes[scope] def _parse_key(key): @@ -197,19 +220,13 @@ class SpackConfigParser(cp.RawConfigParser): """Slightly modified from Python's raw config file parser to accept leading whitespace and preserve comments. """ - # Slightly modified Python option expression. This one allows - # leading whitespace. - OPTCRE = re.compile( - r'\s*(?P