Skip to content

Commit e970f58

Browse files
committed
Add scripts to move annotations and compare prow job yamls
1 parent 1c101ae commit e970f58

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed

experiment/compare-yaml.py

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2020 The Kubernetes Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""Recursive YAML comparator
18+
19+
This script allow the user to compare two directories containing
20+
YAML files in the same folder structure.
21+
22+
Usage: ./compare-yaml.py path1 path2
23+
24+
It will walk through all files in path1 and compare them with the same file
25+
found in path2. Comparison is semantic and not affected by the order of lists.
26+
"""
27+
28+
import operator
29+
import os
30+
import sys
31+
32+
import yaml
33+
34+
35+
def loadfile(f):
36+
"""Loads a YAML file containing several documents into a list of objects
37+
38+
:param f: string containing the path to the file to load
39+
:return: list of loaded objects
40+
"""
41+
try:
42+
return list(yaml.safe_load_all(open(f)))
43+
except Exception as e:
44+
print('Exception caught loading', f, e)
45+
raise
46+
47+
48+
def compare(f1, left, right):
49+
"""Compares the same filename from two path roots and prints the difference to stdout
50+
51+
:param f1: full path to the first file
52+
:param left: root of f1 path to construct relative path
53+
:param right: second root to deduct f2 path
54+
:return: None
55+
"""
56+
f2 = os.path.join(right, os.path.relpath(f1, left))
57+
if not os.path.isfile(f2):
58+
print('Cannot find', f2)
59+
return
60+
d1s = loadfile(f1)
61+
d2s = loadfile(f2)
62+
if not all(map(operator.eq, d1s, d2s)):
63+
print('meld', f1, f2)
64+
65+
66+
def main():
67+
if len(sys.argv) != 3:
68+
sys.exit('Provide path1 and path2')
69+
left = sys.argv[1]
70+
right = sys.argv[2]
71+
for root, _, files in os.walk(left):
72+
for name in files:
73+
f = os.path.join(root, name)
74+
if not os.path.isfile(f):
75+
print('Skipping', f)
76+
continue
77+
if f.endswith('.yaml'):
78+
compare(f, left, right)
79+
80+
81+
if __name__ == "__main__":
82+
main()

experiment/move-annotations.py

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2020 The Kubernetes Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""ProwJob annotations relocator
18+
19+
This script allows the user to alter ProwJobs syntax by relocating
20+
names and annotations to the top of the YAML elements for clarity.
21+
22+
Only those two fields are relocated to improve diff readability and
23+
the document itself should be unchanged semantically (you can use the
24+
compare-yaml.py script to ensure that).
25+
26+
Usage: ./move-annotations.py path
27+
28+
It will walk through all files with .yaml extension found under path
29+
and modify them in-place.
30+
"""
31+
32+
import os
33+
import sys
34+
35+
import ruamel.yaml
36+
37+
yaml = ruamel.yaml.YAML()
38+
yaml.preserve_quotes = True
39+
40+
41+
def move_annotations(f):
42+
"""Modifies a YAML ProwJob file in-place by moving name and annotations
43+
to the top of the spec elements.
44+
45+
:param f:
46+
:return:
47+
"""
48+
files = list(yaml.load_all(open(f)))
49+
# pylint: disable=R1702
50+
for lvl1 in files:
51+
for lvl2 in lvl1.values():
52+
if isinstance(lvl2, ruamel.yaml.comments.CommentedSeq):
53+
for job in lvl2:
54+
if not 'annotations' in job:
55+
continue
56+
job.move_to_end('annotations', last=False)
57+
job.move_to_end('name', last=False)
58+
elif isinstance(lvl2, ruamel.yaml.comments.CommentedMap):
59+
for lvl3 in lvl2.values():
60+
if isinstance(lvl3, bool):
61+
continue
62+
for job in lvl3:
63+
if not 'annotations' in job:
64+
continue
65+
job.move_to_end('annotations', last=False)
66+
job.move_to_end('name', last=False)
67+
else:
68+
print('skipping', lvl2)
69+
yaml.dump_all(files, open(f, 'w'))
70+
71+
72+
def main():
73+
if len(sys.argv) != 2:
74+
sys.exit('Provide path to jobs')
75+
for root, _, files in os.walk(sys.argv[1]):
76+
for name in files:
77+
f = os.path.join(root, name)
78+
if not os.path.isfile(f):
79+
print('Skipping non file', f)
80+
continue
81+
if f.endswith('.yaml'):
82+
try:
83+
move_annotations(f)
84+
except Exception as e:
85+
print('Caught exception processing', f, e)
86+
raise
87+
88+
89+
if __name__ == "__main__":
90+
main()

0 commit comments

Comments
 (0)