Skip to content

Instantly share code, notes, and snippets.

@sjsakib
Last active November 24, 2017 09:55
Show Gist options
  • Save sjsakib/55f4ada7035f7190c9f37775c1f1a01b to your computer and use it in GitHub Desktop.
Save sjsakib/55f4ada7035f7190c9f37775c1f1a01b to your computer and use it in GitHub Desktop.
a simple pre-commit git hook
#!/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