-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.py
executable file
·190 lines (161 loc) · 7.37 KB
/
main.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import glob
from itertools import islice
DEBUG = False
MAX_PADDING = 23
def remove_whitespaces(string):
"""Returns a string completly stripped.
Replaces all whitespaces between chars with only one whitespace,
and removes all trailling whitespaces.
"""
while ' ' in string: string = string.replace(' ', ' ')
return string.strip()
def get_raw_lines(file_lines):
"""Returns a list of all the lines.
Reads all the lines and uses the remove_whitespaces()
for each string, and stores in a list.
"""
raw_lines = []
for line in file_lines:
line = remove_whitespaces(line)
if line != '': raw_lines.append(line)
return raw_lines
def ignore_block(i, lines):
"""Returns a list of lines to ignore when HCL-formatting.
Reads all the lines below the defined string (in the main), and
stores all the line numbers that are inside that block in a list.
"""
child_i = i
lines_to_ignore = [child_i]
bracket_count = 0
for line in islice(lines, i, None):
if '{' in line: bracket_count += 1
if '}' in line: bracket_count -= 1
if bracket_count != 0:
child_i += 1
lines_to_ignore.append(child_i)
else:
break
return lines_to_ignore
if __name__ == "__main__":
files = glob.glob('.' + '/**/*.tf', recursive=True)
for file in files:
if DEBUG: print('Working on [%s] file' % (file))
if DEBUG: print(' 1. Reading file and removing all spaces and indentation')
raw_lines = get_raw_lines(open(file, 'r').readlines())
if DEBUG: print(' 2. Breaking lines')
spaced_lines = []
for i, line in enumerate(raw_lines):
jump_line = 0
# Avoid index errors
if i < (len(raw_lines) - 1):
next_line = raw_lines[i+1]
# Generic (not to break)
if line.endswith('{') or line.endswith('{'):
if next_line.endswith('{') or next_line.endswith('['):
spaced_lines.append(line)
continue
# Custom (not to break)
if not line.startswith('#') and \
not line.strip() == 'locals {' and \
len(next_line) > 1:
# Custom (to break)
if next_line.count('{') > next_line.count('}') and not '=> {' in next_line: jump_line = 1
if next_line.count('[') > next_line.count(']') and not ': [' in next_line: jump_line = 1
if next_line.startswith('#'): jump_line = 1
if line.startswith('}') and not next_line.startswith('}'): jump_line = 1
if line.startswith(']') and not next_line.startswith(']'): jump_line = 1
if jump_line: spaced_lines.append(line + '\n')
else: spaced_lines.append(line)
else: spaced_lines.append(line)
else: spaced_lines.append(line)
if DEBUG: print(' 3. Re-indenting lines')
indented_lines = []
indentation = 0
for i, line in enumerate(spaced_lines):
# Indent down current line
if ('{' in line and '}' in line) or \
(']' in line and '[' in line):
if (line.count('{') < line.count('}')) or \
(line.count('[') < line.count(']')):
indentation -= 1
if ('}' in line and not '{' in line) or \
(']' in line and not '[' in line):
indentation -= 1
# Storing indented and current line
tabbing = ' ' * indentation
indented_line = tabbing + line
indented_lines.append(indented_line)
# Indent up next line
if ('{' in line and '}' in line) or \
(']' in line and '[' in line):
if (line.count('{') > line.count('}')) or \
(line.count('[') > line.count(']')):
indentation += 1
elif ('{' in line and not '}' in line) or \
('[' in line and not ']' in line):
indentation += 1
if DEBUG: print(' 4. Tagging lines not to format with HCL right padding')
lines_to_ignore = []
for i, line in enumerate(indented_lines):
# Break lines
if not line.strip(): lines_to_ignore.append(i)
# Comentaries
if line.startswith('#'): lines_to_ignore.append(i)
# Lines with no equal sign
elif not ' = ' in line: lines_to_ignore.append(i)
# Lines that begin new blocks
elif (line.count('{') > line.count('}')) or \
(line.count('[') > line.count(']')):
lines_to_ignore.append(i)
# Custom lines
elif line == 'variable "region" { default = "us-east-1" }': lines_to_ignore.append(i)
elif line == 'provider "aws" { region = var.region }': lines_to_ignore.append(i)
elif line == 'locals { caller = data.aws_caller_identity.current.arn }': lines_to_ignore.append(i)
# Data block
#if line.startswith('data "') and '{' in line: lines_to_ignore += ignore_block(i, indented_lines)
# Locals block
#if line.startswith('locals {'): lines_to_ignore += ignore_block(i, indented_lines)
lines_to_ignore.sort()
if DEBUG: print(' 5. Grouping blocks of lines')
lines_group = []
group = 0
for i, line in enumerate(indented_lines):
if i in lines_to_ignore:
lines_group.append(-1)
group += 1
else:
lines_group.append(group)
# Discover correct padding
blocks_group = {}
helper = 0
for i, line in enumerate(indented_lines):
# Not ignored lines
if lines_group[i] != -1:
line_len = len(line.split('=', 1)[0].strip())
if not lines_group[i] in blocks_group:
blocks_group[lines_group[i]] = line_len
helper = line_len
else:
if blocks_group[lines_group[i]] != helper:
blocks_group[lines_group[i]] = line_len
helper = line_len
elif line_len > blocks_group[lines_group[i]] and line_len < MAX_PADDING:
blocks_group[lines_group[i]] = line_len
helper = line_len
if DEBUG: print(' 6. Trucating and rewriting file HCL-style')
with open(file, 'w') as formated_file:
formated_file.truncate()
for i, line in enumerate(indented_lines):
if not i in lines_to_ignore:
key_value = line.split('=', 1)
key = key_value[0].rstrip()
key_value.pop(0)
value = ''.join(str(item) for item in key_value)
# HCL-like before '=' padding
indentation = len(key) - len(key.lstrip())
padding = blocks_group[lines_group[i]]
key = key.ljust((indentation + padding), ' ')
formated_file.write('%s =%s\n' % (key, value))
else:
formated_file.write(line + '\n')
if DEBUG: print('Completed!\n')