Skip to content

Instantly share code, notes, and snippets.

@vainikkaj
Forked from Kenterfie/terradiff
Last active April 29, 2024 15:37
Show Gist options
  • Save vainikkaj/4ccdaacf8491ae4a3774668526e749aa to your computer and use it in GitHub Desktop.
Save vainikkaj/4ccdaacf8491ae4a3774668526e749aa to your computer and use it in GitHub Desktop.
Small python script to make terraform plan outputs for terraform helm_release values better readable
#!/bin/env python3
#
# TERRADIFF
#
# Small script to convert EOT diffs into single line diffs to make them easier to read
#
# How to use
# terraform plan | terradiff
#
import re
import sys
import difflib
from os import isatty
try:
from colorama import Fore, Back, Style, init
init()
except ImportError: # fallback so that the imported classes always exist
class ColorFallback():
__getattr__ = lambda self, name: ''
Fore = Back = Style = ColorFallback()
def color_diff(diffc):
for line in diffc:
if line.startswith('+'):
yield '##[section][ADDED] ' + line
elif line.startswith('-'):
yield '##[command][REMOVED] ' + line
elif line.startswith('^'):
yield '##[debug][CHANGED] ' + line
else:
yield line
def print_color_diff(txt):
new_txt=[]
for line in txt.splitlines():
# print(new_txt)
if line.strip().startswith('+'):
new_txt.append('##[section][+] ' + line)
elif line.strip().startswith('-'):
new_txt.append('##[command][-] ' + line)
elif line.strip().startswith('^'):
new_txt.append('##[debug][+/-] ' + line)
else:
new_txt.append(line)
print('\n'.join(new_txt))
def strip_ansi_codes(s):
"""
Remove ANSI color codes from the string.
"""
return re.sub('\033\\[([0-9]+)(;[0-9]+)*m', '', s)
is_pipe = not isatty(sys.stdin.fileno())
if not is_pipe:
raise SystemExit("No input available. Please use 'command | terradiff'")
input = sys.stdin.read()
# Colored version
r = r'.\[31m(-).\[0m.\[0m (<<-EOT.*?EOT).*?.\[32m(\+).\[0m.\[0m (<<-EOT.*?EOT)'
for match in re.finditer(r, input, re.S):
d = difflib.Differ()
l = match.group(2)
r = match.group(4)
lc = strip_ansi_codes(l)
rc = strip_ansi_codes(r)
diff = d.compare(lc.splitlines(keepends=True), rc.splitlines(keepends=True))
input = input.replace(match.group(0), ''.join(color_diff(diff)))
# Raw version
r = r'(-) (\<\<-EOT.*?EOT).*?(\+) (\<\<-EOT.*?EOT)'
for match in re.finditer(r, input, re.S):
d = difflib.Differ()
diff = d.compare(match.group(2).splitlines(keepends=True), match.group(4).splitlines(keepends=True))
input = input.replace(match.group(0), ''.join(color_diff(diff)))
# print(input)
print_color_diff(input)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment