From b6195b48300398bc76510cc9ae6c8c7c53a4961b Mon Sep 17 00:00:00 2001 From: Conner Crosby Date: Tue, 8 Oct 2024 20:46:01 -0400 Subject: [PATCH] Fix quotes converting free-form syntax to yaml (#4319) YAML content has been changed to reflect that the YAML loader preserves quotes used in YAML and to utilize the preferred_quote configuration. --- .config/dictionary.txt | 1 + .../transform-no-free-form.transformed.yml | 4 ++-- examples/playbooks/vars/strings.transformed.yml | 4 ++-- src/ansiblelint/rules/no_free_form.py | 13 +++++++++++-- src/ansiblelint/yaml_utils.py | 1 + test/fixtures/formatting-after/fmt-1.yml | 10 +++++----- 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/.config/dictionary.txt b/.config/dictionary.txt index 6065fc0875..750ca8c018 100644 --- a/.config/dictionary.txt +++ b/.config/dictionary.txt @@ -319,6 +319,7 @@ ruleset runas sarif scalarint +scalarstring scancode schemafile sdist diff --git a/examples/playbooks/transform-no-free-form.transformed.yml b/examples/playbooks/transform-no-free-form.transformed.yml index e947c345af..6eae52bbab 100644 --- a/examples/playbooks/transform-no-free-form.transformed.yml +++ b/examples/playbooks/transform-no-free-form.transformed.yml @@ -22,9 +22,9 @@ - name: Example task with usage for '=' as module params ansible.builtin.debug: - msg: "'Hello there world'" + msg: "Hello there world" changed_when: false - name: Task that has a non-debug string with spaces ansible.builtin.set_fact: - foo: '"String with spaces"' + foo: "String with spaces" diff --git a/examples/playbooks/vars/strings.transformed.yml b/examples/playbooks/vars/strings.transformed.yml index 6f2aae1b80..bee1899cb5 100644 --- a/examples/playbooks/vars/strings.transformed.yml +++ b/examples/playbooks/vars/strings.transformed.yml @@ -2,13 +2,13 @@ # Make sure that the Transformer does not mangle strings # TODO: there is a bug in ruamel.yaml that discards some EOL comments -single: single # this is a comment +single: "single" # this is a comment single_with_double: '"single" quoted' # this is a comment single_multiline_with_octothorpe: "single over 160 char line to force wrapping. over 160 char line to force wrapping. over 160 char line to force wrapping. over 160\n # this is not a comment" -double: double # this is a comment +double: "double" # this is a comment double_with_single: "'double' quoted" # this is a comment double_multiline_with_octothorpe: "double over 160 char line to force wrapping. over 160 char line to force wrapping. over 160 char line to force wrapping. over 160\n diff --git a/src/ansiblelint/rules/no_free_form.py b/src/ansiblelint/rules/no_free_form.py index 13489efa3d..14552fa545 100644 --- a/src/ansiblelint/rules/no_free_form.py +++ b/src/ansiblelint/rules/no_free_form.py @@ -7,7 +7,12 @@ import sys from typing import TYPE_CHECKING, Any -from ansiblelint.constants import INCLUSION_ACTION_NAMES, LINE_NUMBER_KEY +from ruamel.yaml.scalarstring import DoubleQuotedScalarString, SingleQuotedScalarString + +from ansiblelint.constants import ( + INCLUSION_ACTION_NAMES, + LINE_NUMBER_KEY, +) from ansiblelint.rules import AnsibleLintRule, TransformMixin from ansiblelint.rules.key_order import task_property_sorter @@ -124,7 +129,11 @@ def filter_values( # Keep quoted strings together quote = v[0] _, v, remainder = v.split(quote, 2) - v = f"{quote}{v}{quote}" + v = ( + DoubleQuotedScalarString + if quote == '"' + else SingleQuotedScalarString + )(v) else: try: v, remainder = v.split(" ", 1) diff --git a/src/ansiblelint/yaml_utils.py b/src/ansiblelint/yaml_utils.py index cd6749f772..0ec1d10dd5 100644 --- a/src/ansiblelint/yaml_utils.py +++ b/src/ansiblelint/yaml_utils.py @@ -954,6 +954,7 @@ def __init__( # pylint: disable=too-many-arguments # This will only preserve quotes for strings read from the file. # anything modified by the transform will use no quotes, preferred_quote, # or the quote that results in the least amount of escaping. + self.preserve_quotes = True # If needed, we can use this to change null representation to be explicit # (see https://stackoverflow.com/a/44314840/1134951) diff --git a/test/fixtures/formatting-after/fmt-1.yml b/test/fixtures/formatting-after/fmt-1.yml index 118a08742b..97016d2f0b 100644 --- a/test/fixtures/formatting-after/fmt-1.yml +++ b/test/fixtures/formatting-after/fmt-1.yml @@ -10,14 +10,14 @@ vegetables: # indented sequence: - carrot quoting: - - that should have double quotes - - that should remain in single quotes - - a string with " inside + - "that should have double quotes" + - "that should remain in single quotes" + - 'a string with " inside' # next line has some undesired trailing spaces: - - a string with ' inside + - "a string with ' inside" - can't be sure! # next line should be converted to use double quotes: - - [foo, bar] + - ["foo", "bar"] inline-dictionary: - { foo: bar } # should add some spacing between curly braces and content