Просмотр исходного кода

Make sure y/n values are quoted in serialized output

Signed-off-by: Joffrey F <[email protected]>
Joffrey F 8 лет назад
Родитель
Сommit
d94fa5428e
2 измененных файлов с 32 добавлено и 1 удалено
  1. 14 1
      compose/config/serialize.py
  2. 18 0
      tests/unit/config/config_test.py

+ 14 - 1
compose/config/serialize.py

@@ -21,11 +21,23 @@ def serialize_dict_type(dumper, data):
     return dumper.represent_dict(data.repr())
 
 
+def serialize_string(dumper, data):
+    """ Ensure boolean-like strings are quoted in the output """
+    representer = dumper.represent_str if six.PY3 else dumper.represent_unicode
+    if data.lower() in ('y', 'n', 'yes', 'no', 'on', 'off', 'true', 'false'):
+        # Empirically only y/n appears to be an issue, but this might change
+        # depending on which PyYaml version is being used. Err on safe side.
+        return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"')
+    return representer(data)
+
+
 yaml.SafeDumper.add_representer(types.VolumeFromSpec, serialize_config_type)
 yaml.SafeDumper.add_representer(types.VolumeSpec, serialize_config_type)
 yaml.SafeDumper.add_representer(types.ServiceSecret, serialize_dict_type)
 yaml.SafeDumper.add_representer(types.ServiceConfig, serialize_dict_type)
 yaml.SafeDumper.add_representer(types.ServicePort, serialize_dict_type)
+yaml.SafeDumper.add_representer(str, serialize_string)
+yaml.SafeDumper.add_representer(six.text_type, serialize_string)
 
 
 def denormalize_config(config, image_digests=None):
@@ -58,7 +70,8 @@ def serialize_config(config, image_digests=None):
         denormalize_config(config, image_digests),
         default_flow_style=False,
         indent=2,
-        width=80)
+        width=80
+    )
 
 
 def serialize_ns_time_value(value):

+ 18 - 0
tests/unit/config/config_test.py

@@ -4163,3 +4163,21 @@ class SerializeTest(unittest.TestCase):
         assert secret_sort(serialized_service['configs']) == secret_sort(service_dict['configs'])
         assert 'configs' in serialized_config
         assert serialized_config['configs']['two'] == configs_dict['two']
+
+    def test_serialize_bool_string(self):
+        cfg = {
+            'version': '2.2',
+            'services': {
+                'web': {
+                    'image': 'example/web',
+                    'command': 'true',
+                    'environment': {'FOO': 'Y', 'BAR': 'on'}
+                }
+            }
+        }
+        config_dict = config.load(build_config_details(cfg))
+
+        serialized_config = serialize_config(config_dict)
+        assert 'command: "true"\n' in serialized_config
+        assert 'FOO: "Y"\n' in serialized_config
+        assert 'BAR: "on"\n' in serialized_config