Last active
November 24, 2017 09:55
-
-
Save sjsakib/55f4ada7035f7190c9f37775c1f1a01b to your computer and use it in GitHub Desktop.
a simple pre-commit git hook
This file contains hidden or 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/python3 | |
import os | |
import datetime | |
from subprocess import check_output | |
# for the first time we'd like to build docs for all the files, | |
# not just the changed files, this line will give us all the files | |
# changed = check_output(['git', 'ls-files']) | |
changed = check_output(['git', 'diff', '--cached', '--name-only']) | |
# check_output return bytes, converting to str and splitting | |
changed = changed.decode('utf-8').split('\n') | |
def get_target(file): | |
"""returns target path to save doc to for a file and also the file extension""" | |
base, ext = os.path.splitext(file) | |
# removing the -v1, -v2 postfix of our file cause we want to save | |
# docs for all the different versions of a solution in a single file | |
base = base.split('-')[0] | |
base = base.lower().replace(' ', '-') # slugifying path | |
file = base + '.md' | |
return os.path.join('docs', file), ext | |
def write_md(code, data, ext): | |
"""receives code, extracted data and extension, return the | |
content to write and the problem name for the link in index""" | |
txt = '' | |
if 'Approach' in data and data['Approach']: | |
txt += '### '+data['Approach'].title()+'\n\n' | |
if 'des' in data: | |
txt += data['des'] + '\n\n' | |
txt += '\n---|---\n' # creating table with other data found in comment | |
for k, v in data.items(): | |
if k not in ['Approach', 'Problem', 'des', 'Author']: | |
txt += (k + ' | ' + v + '\n') | |
tm = datetime.datetime.now().strftime('%d %b %Y %H:%M') | |
txt += 'Commit Time | ' + tm + '\n\n' | |
if ext != '.md': | |
txt += '```' + ext[1:] + '\n' | |
txt += code + '\n' | |
txt += '```\n' | |
else: | |
txt += code | |
return data['Problem'], txt | |
def process_cpp(data, file_name, ext): | |
"""processes cpp files and returns code and extracted data""" | |
lines = data.split('\n') | |
i = 1 | |
data = {} | |
data['des'] = '' | |
while lines[i].startswith(' *'): | |
comment = lines[i][3:] | |
if ':' in comment: | |
comment = comment.split(':') | |
data[comment[0].strip()] = comment[1].strip() | |
else: | |
data['des'] += comment | |
i += 1 | |
# if no comments are found assume the filename to be problem name | |
if not len(data): | |
data['Problem'] = os.path.splitext(file_name)[0] | |
code = '\n'.join(lines[i+1:]) | |
return write_md(code, data, ext) | |
def process_py(data, file_name, ext): | |
"""for processing py files, same as process_cpp""" | |
parts = data.split('"""') | |
try: | |
comments = parts[1].split('\n') | |
except IndexError: | |
return write_md(data, {'Problem': os.path.splitext(file_name)[0]}, ext) | |
code = '"""'.join(parts[2:]) | |
data = {} | |
data['des'] = '' | |
for line in comments: | |
if ':' in line: | |
line = line.split(':') | |
data[line[0].strip()] = line[1].strip() | |
else: | |
data['des'] += line + '\n' | |
return write_md(code, data, ext) | |
def process_data(data, file_name, ext): | |
"""process file contents according to extension, only supports .cpp, .py for now""" | |
if ext == '.py': | |
return process_py(data, file_name, ext) | |
elif ext == '.cpp': | |
return process_cpp(data, file_name, ext) | |
else: | |
return write_md(data, {'Problem': os.path.splitext(file_name)[0]}, ext) | |
cnt = 0 | |
for file in changed: | |
try: | |
if not os.path.exists(file) or file.startswith('docs'): | |
continue | |
with open(file, 'r') as f: | |
data = f.read() | |
target, ext = get_target(file) | |
tar_path, tar_file = os.path.split(target) | |
name, data = process_data(data, tar_file, ext) | |
if not os.path.exists(tar_path): | |
os.makedirs(tar_path) | |
if os.path.exists(target): | |
with open(target, 'a') as f: | |
f.write(data) | |
else: | |
with open(os.path.join(tar_path, 'index.md'), 'a+') as f: | |
to_add = "* [{}]({})\n".format(name, tar_file) | |
f.write(to_add) | |
with open(target, 'w') as f: | |
f.write('# '+name+'\n\n') | |
f.write(data) | |
cnt += 1 | |
except Exception as e: | |
print("While processing -", file) | |
raise e | |
print("Building docs successful...") | |
print("Number of files modified - ", cnt) | |
# now adding all the created files | |
print(check_output(['git', 'add', '*'])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment