-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.py
150 lines (137 loc) · 4.79 KB
/
build.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#! /bin/usr/env python
# D.J. Bennett
# 19/04/2015
"""
Build docs for a BES-QSIG website
Usage:
python build.py
jekyll build
Then, upload _site/ to gh-pages branch.
"""
# LIBS
import os
import re
import sys
import subprocess
import operator
# GLOBALS
front_matter = """---
layout: doc
authors: {0}
lastchange: {1}
title: {2}
status: {3}
theme: {4}
permalink: {5}
---
"""
# FUNCTIONS
def get_contributions(doc_path, input_dir):
"""Return string of authors and their percentage contributions"""
# read git log
cmd = 'git log --stat {0}'.format(doc_path)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True, stderr=subprocess.PIPE,
cwd=input_dir)
gitlog, _ = process.communicate()
# split into different commits
commits = re.split('commit\s[a-zA-Z0-9]+\n', gitlog)
# get number of changes by name
name_changes = {}
for commit in commits[1:]:
# split into lines
lines = commit.strip().split('\n')
# search first line for author
name_start = re.search('^Author:\s', lines[0]).end()
name_end = re.search('^Author:\s.*\s<', lines[0]).end() - 1
name = lines[0][name_start:name_end].strip()
# search penultimate line for changes to file
changes_start = re.search(doc_path + '\s\|\s', lines[-2]).end()
changes_end = re.search(doc_path + '\s\|\s[0-9]+\s', lines[-2]).end()
changes = float(lines[-2][changes_start:changes_end].strip())
if name in name_changes.keys():
name_changes[name] += changes
else:
name_changes[name] = changes
# convert into rough %
total = sum(name_changes.values())
for name in name_changes.keys():
name_changes[name] = round(name_changes[name]*100/total, 1)
# sort by who made most contributions
sorted_by_changes = sorted(name_changes.items(),
key=operator.itemgetter(1))
sorted_by_changes.reverse()
# unpack
author_string = ''
for e in sorted_by_changes:
author_string += '{0} ({1}%), '.format(e[0], e[1])
return(author_string.strip(', '))
def get_last_change(doc_path, input_dir):
"""Return string of date since last edit"""
# read git log with formatter
cmd = 'git log --pretty=format:"%ad" {0}'.format(doc_path)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True, stderr=subprocess.PIPE,
cwd=input_dir)
gitlog, _ = process.communicate()
# split into different commits
commits = re.split('\n', gitlog)
# take first of the list
last_change = commits[0]
# extract date and year (ignore time)
last_change = last_change[0:9] + ', ' + last_change[20:24]
return(last_change)
def read_doc(doc_path, input_dir):
"""Return strings of front matter and doc text"""
pattern = re.compile('\-\-\-')
with open(os.path.join(input_dir, doc_path), 'rb') as f:
text = f.read()
res = pattern.search(text)
if res:
# there should be two ---, else this will raise an error
text = text[res.end():]
res = pattern.search(text)
text_fm = text[:res.end()]
text = text[res.end():]
doc_fm = {}
for e in text_fm.split('\n'):
if ':' in e:
key, value = e.split(':')
doc_fm[key] = value.strip()
return(doc_fm, text[1:])
def run(input_dir, output_dir):
"""Make docs in _docs_repo/ CGE friendly"""
# get docs
docs = [e for e in os.listdir(input_dir) if re.search('\.md', e)]
docs = [e for e in docs if e != 'README.md']
for doc in docs:
# read doc
doc_fm, doc_text = read_doc(doc, input_dir)
# get metadata
authors = get_contributions(doc, input_dir)
last_change = get_last_change(doc, input_dir)
title = doc_fm['title']
status = doc_fm['status']
theme = doc_fm['theme']
permalink = doc_fm['permalink']
# construct front-matter
new_fm = front_matter.format(authors, last_change, title, status,
theme, permalink)
# combine
new_doc = new_fm + doc_text
# write out
with open(os.path.join(output_dir, doc), 'wb') as f:
f.write(new_doc)
if __name__ == '__main__':
basedir = os.getcwd()[-3:]
if basedir not in ['cge', 'qge']:
sys.exit('Must only be run in cge/ or qge/!')
# sort dirs
input_dir = os.path.join(os.getcwd(), '_docs_repo')
if '_docs_repo' not in os.listdir(os.getcwd()):
sys.exit('No _docs_repo/ found in cwd.')
output_dir = os.path.join(os.getcwd(), '_docs')
if not os.path.isdir(output_dir):
os.mkdir(output_dir)
# run
run(input_dir=input_dir, output_dir=output_dir)