-
Notifications
You must be signed in to change notification settings - Fork 346
/
Copy pathyaml_to_json.py
executable file
·128 lines (107 loc) · 4.09 KB
/
yaml_to_json.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
#!/usr/bin/env python3
# vim:ts=4:sts=4:sw=4:et
# args: ../bash-tools/.gitlab-ci.yml
#
# Author: Hari Sekhon
# Date: 2020-08-18 01:17:56 +0100 (Tue, 18 Aug 2020)
#
# https://github.com/HariSekhon/DevOps-Python-tools
#
# License: see accompanying Hari Sekhon LICENSE file
#
# If you're using my code you're welcome to connect with me on LinkedIn and optionally send me feedback
# to help improve or steer this or other code I publish
#
# https://www.linkedin.com/in/HariSekhon
#
"""
Tool to convert YAML to JSON
Reads any given files as YAML and prints the equivalent JSON to stdout for piping or redirecting to a file.
Directories if given are detected and recursed, processing all files in the directory tree ending in a
.yml / .yaml suffix.
Works like a standard unix filter program - if no files are passed as arguments or '-' is passed then reads from
standard input.
Written to convert .gitlab-ci.yml files to JSON for inputting to the GitLab API for validation
(see gitlab_validate_ci_yml.sh in the DevOps-Bash-tools repo)
See also:
yaml2json.sh - https://github.com/HariSekhon/DevOps-Bash-tools
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
#from __future__ import unicode_literals
import json
import os
import re
import sys
import yaml
libdir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'pylib'))
sys.path.append(libdir)
try:
# pylint: disable=wrong-import-position
from harisekhon.utils import die, ERRORS, log, log_option
from harisekhon import CLI
except ImportError as _:
print('module import failed: %s' % _, file=sys.stderr)
print("Did you remember to build the project by running 'make'?", file=sys.stderr)
print("Alternatively perhaps you tried to copy this program out without it's adjacent libraries?", file=sys.stderr)
sys.exit(4)
__author__ = 'Hari Sekhon'
__version__ = '0.2.0'
class YamlToJson(CLI):
def __init__(self):
# Python 2.x
super(YamlToJson, self).__init__()
# Python 3.x
# super().__init__()
self.re_yaml_suffix = re.compile(r'.*\.ya?ml$', re.I)
@staticmethod
def yaml_to_json(content, filepath=None):
try:
_ = yaml.load(content, Loader=yaml.FullLoader)
except (KeyError, ValueError) as _:
file_detail = ''
if filepath is not None:
file_detail = ' in file \'{0}\''.format(filepath)
die("Failed to parse YAML{0}: {1}".format(file_detail, _))
return json.dumps(_, sys.stdout, indent=4)
def run(self):
if not self.args:
self.args.append('-')
for arg in self.args:
if arg == '-':
continue
if not os.path.exists(arg):
print("'%s' not found" % arg)
sys.exit(ERRORS['WARNING'])
if os.path.isfile(arg):
log_option('file', arg)
elif os.path.isdir(arg):
log_option('directory', arg)
else:
die("path '%s' could not be determined as either a file or directory" % arg)
for arg in self.args:
self.process_path(arg)
def process_path(self, path):
if path == '-' or os.path.isfile(path):
self.process_file(path)
elif os.path.isdir(path):
for root, _, files in os.walk(path):
for filename in files:
filepath = os.path.join(root, filename)
if self.re_yaml_suffix.match(filepath):
self.process_file(filepath)
else:
die("failed to determine if path '%s' is a file or directory" % path)
def process_file(self, filepath):
log.debug('processing filepath \'%s\'', filepath)
if filepath == '-':
filepath = '<STDIN>'
if filepath == '<STDIN>':
print(self.yaml_to_json(sys.stdin.read()))
else:
with open(filepath) as _:
content = _.read()
print(self.yaml_to_json(content, filepath=filepath))
if __name__ == '__main__':
YamlToJson().main()