-
Notifications
You must be signed in to change notification settings - Fork 140
/
yaml_dumper.py
128 lines (85 loc) · 3.41 KB
/
yaml_dumper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"""
Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
A copy of the License is located at
http://aws.amazon.com/apache2.0/
or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
"""
import six
from cfn_clean.yaml_dumper import CleanCfnYamlDumper
from cfn_tools.literal import LiteralString
from cfn_tools.odict import ODict
from cfn_tools.yaml_dumper import CfnYamlDumper
from cfn_tools._config import config
TAG_STR = "tag:yaml.org,2002:str"
TAG_MAP = "tag:yaml.org,2002:map"
CONVERTED_SUFFIXES = ["Ref", "Condition"]
FN_PREFIX = "Fn::"
# Maximum length of a string before switching to angle-bracket-style representation
STR_MAX_LENGTH_QUOTED = config.max_col_width
# Maximum number of newlines a string can have before switching to pipe-style representation
STR_MAX_LINES_QUOTED = 10
class Dumper(CfnYamlDumper):
"""
The standard dumper
"""
class CleanDumper(CleanCfnYamlDumper):
"""
Cleans up strings
"""
class LongDumper(CfnYamlDumper):
"""
Preserves long-form function syntax
"""
class LongCleanDumper(CleanCfnYamlDumper):
"""
Preserves long-form function syntax
"""
def literal_unicode_representer(dumper, value):
return dumper.represent_scalar(TAG_STR, value, style='|')
def string_representer(dumper, value):
if sum(1 for nl in value if nl in ('\n', '\r')) >= STR_MAX_LINES_QUOTED:
return dumper.represent_scalar(TAG_STR, value, style="|")
if len(value) >= STR_MAX_LENGTH_QUOTED and '\n' not in value:
return dumper.represent_scalar(TAG_STR, value, style=">")
if value.startswith("0"):
return dumper.represent_scalar(TAG_STR, value, style="'")
return dumper.represent_scalar(TAG_STR, value)
def fn_representer(dumper, fn_name, value):
tag = "!{}".format(fn_name)
if tag == "!GetAtt" and isinstance(value, list):
value = ".".join(value)
if isinstance(value, list):
return dumper.represent_sequence(tag, value)
if isinstance(value, dict):
return dumper.represent_mapping(tag, value)
return dumper.represent_scalar(tag, value)
def map_representer(dumper, value):
"""
Deal with !Ref style function format and OrderedDict
"""
value = ODict(value.items())
if len(value.keys()) == 1:
key = list(value.keys())[0]
if key in CONVERTED_SUFFIXES:
return fn_representer(dumper, key, value[key])
if key.startswith(FN_PREFIX):
return fn_representer(dumper, key[4:], value[key])
return dumper.represent_mapping(TAG_MAP, value, flow_style=False)
# Customise our dumpers
Dumper.add_representer(ODict, map_representer)
Dumper.add_representer(six.text_type, string_representer)
Dumper.add_representer(LiteralString, literal_unicode_representer)
CleanDumper.add_representer(LiteralString, literal_unicode_representer)
CleanDumper.add_representer(ODict, map_representer)
def get_dumper(clean_up=False, long_form=False):
if clean_up:
if long_form:
return LongCleanDumper
return CleanDumper
if long_form:
return LongDumper
return Dumper