Răsfoiți Sursa

Fix escaped environment variable in configuration (#546).

Reviewed-on: https://projects.torsion.org/borgmatic-collective/borgmatic/pulls/549
Dan Helfman 3 ani în urmă
părinte
comite
c664c6b17b
2 a modificat fișierele cu 23 adăugiri și 3 ștergeri
  1. 7 3
      borgmatic/config/environment.py
  2. 16 0
      tests/unit/config/test_environment.py

+ 7 - 3
borgmatic/config/environment.py

@@ -1,7 +1,7 @@
 import os
 import re
 
-_VARIABLE_PATTERN = re.compile(r'(?<!\\)\$\{(?P<name>[A-Za-z0-9_]+)((:?-)(?P<default>[^}]+))?\}')
+_VARIABLE_PATTERN = re.compile(r'(?P<escape>\\)?(?P<variable>\$\{(?P<name>[A-Za-z0-9_]+)((:?-)(?P<default>[^}]+))?\})')
 
 
 def _resolve_string(matcher):
@@ -9,10 +9,14 @@ def _resolve_string(matcher):
     Get the value from environment given a matcher containing a name and an optional default value.
     If the variable is not defined in environment and no default value is provided, an Error is raised.
     '''
-    name, default = matcher.group("name"), matcher.group("default")
+    if matcher.group('escape') is not None:
+        # in case of escaped envvar, unescape it
+        return matcher.group('variable')
+    # resolve the env var
+    name, default = matcher.group('name'), matcher.group('default')
     out = os.getenv(name, default=default)
     if out is None:
-        raise ValueError("Cannot find variable ${name} in environment".format(name=name))
+        raise ValueError('Cannot find variable ${name} in environment'.format(name=name))
     return out
 
 

+ 16 - 0
tests/unit/config/test_environment.py

@@ -16,6 +16,20 @@ def test_env_braces(monkeypatch):
     module.resolve_env_variables(config)
     assert config == {'key': 'Hello foo'}
 
+def test_env_multi(monkeypatch):
+    monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo')
+    monkeypatch.setenv('MY_CUSTOM_VALUE2', 'bar')
+    config = {'key': 'Hello ${MY_CUSTOM_VALUE}${MY_CUSTOM_VALUE2}'}
+    module.resolve_env_variables(config)
+    assert config == {'key': 'Hello foobar'}
+
+def test_env_escape(monkeypatch):
+    monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo')
+    monkeypatch.setenv('MY_CUSTOM_VALUE2', 'bar')
+    config = {'key': r'Hello ${MY_CUSTOM_VALUE} \${MY_CUSTOM_VALUE}'}
+    module.resolve_env_variables(config)
+    assert config == {'key': r'Hello foo ${MY_CUSTOM_VALUE}'}
+
 
 def test_env_default_value(monkeypatch):
     monkeypatch.delenv('MY_CUSTOM_VALUE', raising=False)
@@ -41,6 +55,7 @@ def test_env_full(monkeypatch):
             'anotherdict': {
                 'key': 'My ${MY_CUSTOM_VALUE} here',
                 'other': '${MY_CUSTOM_VALUE}',
+                'escaped': r'\${MY_CUSTOM_VALUE}',
                 'list': [
                     '/home/${MY_CUSTOM_VALUE}/.local',
                     '/var/log/',
@@ -62,6 +77,7 @@ def test_env_full(monkeypatch):
             'anotherdict': {
                 'key': 'My foo here',
                 'other': 'foo',
+                'escaped': '${MY_CUSTOM_VALUE}',
                 'list': ['/home/foo/.local', '/var/log/', '/home/bar/.config'],
             },
         },