comment_out_module_versionss.py (132 lines of code) (raw):
import os
import re
import sys
from enum import Enum
# list of extensions to replace
# DEFAULT_REPLACE_EXTENSIONS = None
# example: uncomment next line to only replace *.c, *.h, and/or *.txt
# e.g. DEFAULT_REPLACE_EXTENSIONS = (".c", ".h", ".txt")
# TBD: this script has to be integrated with localize_terraform_modules.py - it will be done sometime
# for now just run it after
DEFAULT_REPLACE_EXTENSIONS = (".tf")
## pat_replace = list( ([re.compile(one_re_find_repl[0]),one_re_find_repl[1]] for one_re_find_repl in regex_find_replace))
re_match_module = r'^[^\r\n\S]*module[^\r\n\S]+"[^\r\n"]+"[^\r\n\S]*\{[^\r\n\S]*$'
pat_match_module = re.compile(re_match_module)
re_match_version = r'^([^\r\n\S]*)(version[^\r\n\S]*=[^\r\n\S]*"[^\r\n\S]*[<>~=\d\.]+[^\r\n\S]*"[^\r\n]*)$'
re_repl_version = r'\1## localized \2'
pat_match_version = re.compile(re_match_version)
re_match_source = r'^[^\r\n\S]*source[^\r\n\S]*=[^\r\n\S]*"[\./]+(terraform|Google)[^\r\n"]+"[^\r\n\S]*$'
pat_match_source = re.compile(re_match_source)
re_match_count = r'^[^\r\n\S]*(count|for_each)[^\r\n\S]+[^\r\n"]+$'
pat_match_count = re.compile(re_match_count)
re_match_empty = r'^[^\r\n\S]*$'
pat_match_empty = re.compile(re_match_empty)
num_replacements = 0
num_patched_files = 0
num_scanned_files = 0
def try_to_replace(fname, replace_extensions=DEFAULT_REPLACE_EXTENSIONS):
if replace_extensions:
return fname.lower().endswith(replace_extensions)
return True
class Parse_State(Enum):
Scanning = 0
ModuleStart = 1
InModule = 2
ModuleEnd = 3
##def file_replace(fname, pat, s_after):
def file_replace(fname):
global num_replacements, num_patched_files, num_scanned_files
# first, see if the pattern is even in the file.
with open(fname) as f:
lines = f.readlines()
f.close()
num_scanned_files += 1
patch_applied=0
parse_state = Parse_State.Scanning
for line_index in range(len(lines)):
line = lines[line_index]
if parse_state == Parse_State.Scanning and re.search(pat_match_module,line):
parse_state = Parse_State.ModuleStart
elif parse_state == Parse_State.ModuleStart or parse_state == Parse_State.InModule:
if re.search(pat_match_version,line):
repl_line = re.sub(pat_match_version,re_repl_version,line)
lines[line_index] = repl_line
patch_applied += 1
num_replacements += 1
print("replacing:" + line + " with:\n"+ repl_line + " in file:" + fname)
elif re.search(pat_match_source,line) or re.search(pat_match_count,line) or re.search(pat_match_empty,line):
parse_state = Parse_State.InModule
else:
parse_state = Parse_State.Scanning
if patch_applied > 0:
num_patched_files += 1
out_fname = fname + ".tmp"
out = open(out_fname, "w")
for line in lines:
out.write(line)
out.close()
os.remove(fname)
os.rename(out_fname, fname)
def file_replace_mod(fname):
global num_replacements, num_patched_files, num_scanned_files
# first, see if the pattern is even in the file.
with open(fname) as f:
lines = f.readlines()
f.close()
num_scanned_files += 1
patch_applied=0
start_line_index = 0
end_line_range = len(lines)
while start_line_index < end_line_range:
module_block_found = False
version_search_index_start = start_line_index
version_search_index_end = end_line_range
for line_index in range(start_line_index, end_line_range):
# search module declaration
line = lines[line_index]
if re.search(pat_match_module,line):
# module block start found, determine module block end
module_block_found = True
version_search_index_start = line_index + 1
indent_level = 0
for line_index_tmp in range(line_index,end_line_range):
line = lines[line_index_tmp]
count_open_bracket = line.count("{")
count_close_bracket = line.count("}")
indent_level += count_open_bracket - count_close_bracket
if indent_level == 0:
version_search_index_end = line_index_tmp
break
# if module start line exit loop will restart with new start line
break
# no more module blocks
if not module_block_found:
break
source_attribute_found = False
for line_index_tmp in range(version_search_index_start,version_search_index_end):
line = lines[line_index_tmp]
if re.search(pat_match_source,line):
source_attribute_found = True
break
if source_attribute_found:
for line_index_tmp in range(version_search_index_start,version_search_index_end):
line = lines[line_index_tmp]
if re.search(pat_match_version,line):
repl_line = re.sub(pat_match_version,re_repl_version,line)
lines[line_index_tmp] = repl_line
patch_applied += 1
num_replacements += 1
print("replacing:" + line + " with:\n"+ repl_line + " in file:" + fname)
break
# restart the for loop after each module block
start_line_index = version_search_index_end + 1
if patch_applied > 0:
num_patched_files += 1
out_fname = fname + ".tmp"
out = open(out_fname, "w")
for line in lines:
out.write(line)
out.close()
os.remove(fname)
os.rename(out_fname, fname)
def mass_replace(root_dir, crt_dir, replace_extensions=DEFAULT_REPLACE_EXTENSIONS):
## print("crt_dir="+crt_dir+"\n")
for dirpath, dirnames, filenames in os.walk(os.path.abspath(crt_dir)):
for fname in filenames:
if try_to_replace(fname, replace_extensions):
fullname = os.path.join(dirpath, fname)
file_replace_mod(fullname)
for dirname in dirnames:
mass_replace(root_dir,os.path.join(crt_dir,dirname))
def main(root_dir):
# root_dir = (r'C:\Users\romma05\Documents\ZA-GCP-v3-TEF\terraform-example-foundation').replace(os.sep,'/')
mass_replace(root_dir,root_dir)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: localize_terraform_modules.py <root_dir>\n")
exit()
main(sys.argv[1])
print("Replaced {} instances in {} files out of {} scanned files".format(num_replacements,num_patched_files,num_scanned_files))
## sys.exit(1)
##mass_replace(sys.argv[1])