8000 --write: Avoid line-wrapping YAML flow objects (#2022) · ansible/ansible-lint@6e99861 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6e99861

Browse files
cognifloydssbarnea
andauthored
--write: Avoid line-wrapping YAML flow objects (#2022)
Co-authored-by: Sorin Sbarnea <ssbarnea@redhat.com>
1 parent 93d7c09 commit 6e99861

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

src/ansiblelint/yaml_utils.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Utility helpers to simplify working with yaml-based data."""
2+
# pylint: disable=too-many-lines
23
import functools
34
import logging
45
import os
@@ -20,7 +21,7 @@
2021
)
2122

2223
import ruamel.yaml.events
23-
from ruamel.yaml.comments import CommentedMap, CommentedSeq
24+
from ruamel.yaml.comments import CommentedMap, CommentedSeq, Format
2425
from ruamel.yaml.constructor import RoundTripConstructor
2526
from ruamel.yaml.emitter import Emitter, ScalarAnalysis
2627

@@ -886,13 +887,58 @@ def loads(self, stream: str) -> Any:
886887
def dumps(self, data: Any) -> str:
887888
"""Dump YAML document to string (including its preamble_comment)."""
888889
preamble_comment: Optional[str] = getattr(data, "preamble_comment", None)
890+
self._prevent_wrapping_flow_style(data)
889891
with StringIO() as stream:
890892
if preamble_comment:
891893
stream.write(preamble_comment)
892894
self.dump(data, stream)
893895
text = stream.getvalue()
894896
return self._post_process_yaml(text)
895897

898+
def _prevent_wrapping_flow_style(self, data: Any) -> None:
899+
if not isinstance(data, (CommentedMap, CommentedSeq)):
900+
return
901+
for key, value, parent_path in nested_items_path(data):
902+
if not isinstance(value, (CommentedMap, CommentedSeq)):
903+
continue
904+
fa: Format = value.fa # pylint: disable=invalid-name
905+
if fa.flow_style():
906+
predicted_indent = self._predict_indent_length(parent_path, key)
907+
predicted_width = len(str(value))
908+
if predicted_indent + predicted_width > self.width:
909+
# this flow-style map will probably get line-wrapped,
910+
# so, switch it to block style to avoid the line wrap.
911+
fa.set_block_style()
912+
913+
def _predict_indent_length(
914+
self, parent_path: List[Union[str, int]], key: Any
915+
) -> int:
916+
indent = 0
917+
918+
# each parent_key type tells us what the indent is for the next level.
919+
for parent_key in parent_path:
920+
if isinstance(parent_key, int) and indent == 0:
921+
# root level is a sequence
922+
indent += self.sequence_dash_offset
923+
elif isinstance(parent_key, int):
924+
# next level is a sequence
925+
indent += cast(int, self.sequence_indent)
926+
elif isinstance(parent_key, str):
927+
# next level is a map
928+
indent += cast(int, self.map_indent)
929+
930+
if isinstance(key, int) and indent == 0:
931+
# flow map is an item in a root-level sequence
932+
indent += self.sequence_dash_offset
933+
elif isinstance(key, int) and indent > 0:
934+
# flow map is in a sequence
935+
indent += cast(int, self.sequence_indent)
936+
elif isinstance(key, str):
937+
# flow map is in a map
938+
indent += len(key + ": ")
939+
940+
return indent
941+
896942
# ruamel.yaml only preserves empty (no whitespace) blank lines
897943
# (ie "/n/n" becomes "/n/n" but "/n /n" becomes "/n").
898944
# So, we need to identify whitespace-only lines to drop spaces before reading.

0 commit comments

Comments
 (0)
0