From d2da48c06371abe5c1df1fcf8eea00d6f664ac34 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Sat, 5 Jul 2025 18:25:29 -0700 Subject: [PATCH] apply support for YamlProvider.escaped_semicolons=false --- octodns/provider/yaml.py | 5 +++++ tests/test_octodns_provider_yaml.py | 22 ++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/octodns/provider/yaml.py b/octodns/provider/yaml.py index 6fa318c..5761da2 100644 --- a/octodns/provider/yaml.py +++ b/octodns/provider/yaml.py @@ -420,6 +420,11 @@ class YamlProvider(BaseProvider): if record.ttl == self.default_ttl: # ttl is the default, we don't need to store it del d['ttl'] + if not self.escaped_semicolons and record._type in ('SPF', 'TXT'): + if 'value' in d: + d['value'] = d['value'].replace('\\;', ';') + if 'values' in d: + d['values'] = [v.replace('\\;', ';') for v in d['values']] # we want to output the utf-8 version of the name data[record.decoded_name].append(d) diff --git a/tests/test_octodns_provider_yaml.py b/tests/test_octodns_provider_yaml.py index f60f741..61c1e14 100644 --- a/tests/test_octodns_provider_yaml.py +++ b/tests/test_octodns_provider_yaml.py @@ -494,9 +494,9 @@ xn--dj-kia8a: two.values, ) - zone = Zone('escaped.semis.', []) + escaped = Zone('escaped.semis.', []) with self.assertRaises(ValidationError) as ctx: - source.populate(zone) + source.populate(escaped) self.assertEqual( [ 'double escaped ; in "This has a semi-colon\\\\; that is escaped."' @@ -504,6 +504,24 @@ xn--dj-kia8a: ctx.exception.reasons, ) + with TemporaryDirectory() as td: + # Add some subdirs to make sure that it can create them + target = YamlProvider( + 'target', td.dirname, escaped_semicolons=False + ) + yaml_file = join(td.dirname, 'unescaped.semis.yaml') + + plan = target.plan(zone) + target.apply(plan) + + with open(yaml_file) as fh: + content = fh.read() + self.assertTrue('value: This has a semi-colon; that' in content) + self.assertTrue( + "- This has a semi-colon too; that isn't escaped." in content + ) + self.assertTrue('- ;' in content) + class TestSplitYamlProvider(TestCase): def test_list_all_yaml_files(self):