-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
Copy pathyaml-format.py
executable file
·87 lines (69 loc) · 2.69 KB
/
yaml-format.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
#!/usr/bin/env python
"""JSON file formatter (without prettier)."""
import sys
from pathlib import Path
from textwrap import dedent
# To allow this script to be executed from other directories
sys.path.insert(0, str(Path(__file__).absolute().parent.parent))
import re
from io import StringIO
from typing import Any, Dict, Type
# We use ruamel.yaml for parsing yaml files because it can preserve comments
from ruamel.yaml import YAML
from ruamel.yaml.error import YAMLError
from bin._file_formatter import FileFormatter
yaml = YAML()
# We have pyyaml (5.4) to parse our yamls in this repo,
# and pyyaml uses Yaml 1.1
yaml.version = (1, 1) # type: ignore
YAML_VERSION_COMMENT_REGEX = r"^%YAML [0-9.]+\n-+\n"
class YAMLFormatter(FileFormatter):
@staticmethod
def description() -> str:
return "YAML file formatter"
def format_str(self, input_str: str) -> str:
"""Opinionated format YAML file."""
obj = yaml.load(input_str)
if self.args.add_test_metadata:
self._add_test_metadata(obj)
out_stream = StringIO()
yaml.dump(
obj,
stream=out_stream,
)
# ruamel.yaml tends to add 2 empty lines at the bottom of the dump
formatted = re.sub(r"\n+$", "\n", out_stream.getvalue())
# ruamel adds yaml version at the beginning of the output file
# and we don't really want those, so if no yaml version
# is specified in the original file, remove it from the output file.
if not re.match(YAML_VERSION_COMMENT_REGEX, input_str):
return re.sub(YAML_VERSION_COMMENT_REGEX, "", formatted)
return formatted
@staticmethod
def _add_test_metadata(obj: Dict[str, Any]) -> None:
metadata = obj.get("Metadata", {})
if not metadata:
metadata = obj["Metadata"] = {}
sam_transform_test_value = metadata.get("SamTransformTest")
if sam_transform_test_value is not None and sam_transform_test_value is not True:
raise ValueError(f"Unexpected Metadata.SamTransformTest value {sam_transform_test_value}")
metadata["SamTransformTest"] = True
@staticmethod
def decode_exception() -> Type[Exception]:
return YAMLError
@staticmethod
def file_extension() -> str:
return ".yaml"
@classmethod
def config_additional_args(cls) -> None:
cls.arg_parser.add_argument(
"--add-test-metadata",
action="store_true",
help=dedent(
"""\
Add the testing metadata to yaml file if it doesn't exist:
"Metadata: SamTransformTest: true" """
),
)
if __name__ == "__main__":
YAMLFormatter.main()