Last active
January 25, 2016 18:39
-
-
Save Xowap/62a5e12f36de80cffdc9 to your computer and use it in GitHub Desktop.
Replace SSL certificates in all files and keep indentation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# vim: fileencoding=utf-8 tw=100 expandtab ts=4 sw=4 : | |
# | |
# ssh_replacer | |
# (c) 2015 ActivKonnect | |
from sys import argv, exit, stderr | |
from re import compile | |
from os import walk, path | |
import json | |
WHITESPACE_RE = compile(r'^([ \t]*)([^\r\n]*)([\r\n]*)') | |
class IndentedString(str): | |
def __new__(cls, obj, *args, **kwargs): | |
real_str = str(obj) | |
m = WHITESPACE_RE.match(real_str) | |
clean_str = super(IndentedString, cls).__new__(cls, m.group(2), *args, **kwargs) | |
clean_str.real_str = real_str | |
clean_str.indent = m.group(1) | |
clean_str.eol = m.group(3) | |
return clean_str | |
def read_file(file_name): | |
with open(file_name) as f: | |
return [IndentedString(x) for x in f.readlines()] | |
def list_files(dir_name): | |
if path.isdir(dir_name): | |
for root, dirs, files in walk(dir_name): | |
for file_name in sorted(files): | |
yield path.join(root, file_name) | |
else: | |
yield dir_name | |
def find(haystack, needle): | |
progress = 0 | |
for i, line in enumerate(haystack): | |
if line == needle[progress]: | |
progress += 1 | |
else: | |
progress = 0 | |
if progress == len(needle): | |
return i - progress + 1 | |
def replace(src, old, new): | |
pos = find(src, old) | |
if pos is not None: | |
indent = src[pos].indent | |
eol = src[pos].eol | |
last_eol = src[pos + len(old) - 1].eol | |
formatted_new = [indent + x + (eol if i != len(new) - 1 else last_eol) | |
for i, x in enumerate(new)] | |
return True, src[0:pos] + formatted_new + src[pos + len(old):] | |
else: | |
return False, src | |
def get_real_str(string): | |
return getattr(string, 'real_str', string) | |
def main(target_dir, old, new): | |
old_f = read_file(old) | |
new_f = read_file(new) | |
for file_name in list_files(target_dir): | |
try: | |
file_content = read_file(file_name) | |
replaced, new_content = replace(file_content, old_f, new_f) | |
if replaced: | |
print('### {}'.format(file_name)) | |
with open(file_name, 'w') as f: | |
f.write(''.join(get_real_str(x) for x in new_content)) | |
except UnicodeDecodeError: | |
pass | |
if __name__ == '__main__': | |
if len(argv) != 4: | |
print('Usage: python3 {} <target_dir> <old> <new>'.format(argv[0]), file=stderr) | |
exit(1) | |
main(*argv[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment