← Back to team overview

configglue team mailing list archive

[Merge] lp:~bloodearnest/configglue/envvar-defaults into lp:configglue

 

Simon Davy has proposed merging lp:~bloodearnest/configglue/envvar-defaults into lp:configglue.

Commit message:
Fix regression in previous commit for mutliple env vars

Requested reviews:
  Configglue developers (configglue)

For more details, see:
https://code.launchpad.net/~bloodearnest/configglue/envvar-defaults/+merge/162963

Fix regression in previous commit for mutliple env vars
-- 
https://code.launchpad.net/~bloodearnest/configglue/envvar-defaults/+merge/162963
Your team Configglue developers is requested to review the proposed merge of lp:~bloodearnest/configglue/envvar-defaults into lp:configglue.
=== modified file 'configglue/parser.py'
--- configglue/parser.py	2013-05-03 16:26:38 +0000
+++ configglue/parser.py	2013-05-08 12:02:23 +0000
@@ -437,28 +437,29 @@
             return rawval
 
         # interpolate environment variables
-        default = None
-        pattern = rawval
-        match = re.match(r'\${(?P<name>[A-Z_]+)(:-(?P<default>.*))?}', rawval)
-        if match:
+        env = os.environ.copy()
+
+        # substitute simple patterns
+        pattern = re.sub(r'\${([A-Z_]+)}', r'%(\1)s', rawval)
+        pattern = re.sub(r'\$([A-Z_]+)', r'%(\1)s', pattern)
+
+        # handle env vars with defaults
+        env_re = re.compile(r'\${(?P<name>[A-Z_]+):-(?P<default>.*?)}')
+        match = env_re.search(pattern)
+        while match:
             groups = match.groupdict()
-            pattern = '%%(%s)s' % groups['name']
-            if groups['default'] is not None:
-                default = groups['default']
-
-        pattern = re.sub(r'\$([A-Z_]+)', r'%(\1)s', pattern)
+            name = groups['name']
+            pattern = pattern.replace(match.group(), '%%(%s)s' % name)
+            if name not in env and groups['default'] is not None:
+                env[name] = groups['default']
+            match = env_re.search(pattern)
 
         keys = self._extract_interpolation_keys(pattern)
         if not keys:
             # interpolation keys are not valid
             return rawval
 
-        try:
-            return pattern % os.environ
-        except KeyError:
-            if default is not None:
-                return default
-            raise
+        return pattern % env
 
     def _get_default(self, section, option):
         # cater for 'special' sections

=== modified file 'configglue/tests/test_parser.py'
--- configglue/tests/test_parser.py	2013-05-03 16:26:38 +0000
+++ configglue/tests/test_parser.py	2013-05-08 12:02:23 +0000
@@ -286,22 +286,45 @@
     def test_interpolate_environment_with_default_uses_env(self, mock_os):
         mock_os.environ = {'PATH': 'foo'}
         parser = SchemaConfigParser(Schema())
-        result = parser.interpolate_environment("${PATH:-bar}")
-        self.assertEqual(result, 'foo')
+        result = parser.interpolate_environment("X${PATH:-bar}X")
+        self.assertEqual(result, 'XfooX')
 
     @patch('configglue.parser.os')
     def test_interpolate_environment_with_default_uses_default(self, mock_os):
         mock_os.environ = {}
         parser = SchemaConfigParser(Schema())
-        result = parser.interpolate_environment("${PATH:-bar}")
-        self.assertEqual(result, 'bar')
+        result = parser.interpolate_environment("X${PATH:-bar}X")
+        self.assertEqual(result, 'XbarX')
 
     @patch('configglue.parser.os')
     def test_interpolate_environment_with_empty_default(self, mock_os):
         mock_os.environ = {}
         parser = SchemaConfigParser(Schema())
-        result = parser.interpolate_environment("${PATH:-}")
-        self.assertEqual(result, '')
+        result = parser.interpolate_environment("X${PATH:-}X")
+        self.assertEqual(result, 'XX')
+
+    @patch('configglue.parser.os')
+    def test_interpolate_environment_multiple(self, mock_os):
+        mock_os.environ = {'FOO': 'foo', 'BAR': 'bar', 'BAZ': 'baz'}
+        parser = SchemaConfigParser(Schema())
+        result = parser.interpolate_environment(
+            "$FOO, ${BAR}, ${BAZ:-default}")
+        self.assertEqual(result, 'foo, bar, baz')
+
+    @patch('configglue.parser.os')
+    def test_interpolate_environment_multiple_with_default(self, mock_os):
+        mock_os.environ = {'FOO': 'foo', 'BAR': 'bar'}
+        parser = SchemaConfigParser(Schema())
+        result = parser.interpolate_environment(
+            "$FOO, ${BAR}, ${BAZ:-default}")
+        self.assertEqual(result, 'foo, bar, default')
+
+    def test_interpolate_environment_multiple_defaults(self):
+        "Only the first default is used"
+        parser = SchemaConfigParser(Schema())
+        result = parser.interpolate_environment(
+                "${FOO:-default1}, ${FOO:-default2}")
+        self.assertEqual(result, 'default1, default1')
 
     @patch('configglue.parser.os')
     def test_interpolate_environment_in_config(self, mock_os):


Follow ups