/
gen_readme.py
executable file
·214 lines (178 loc) · 7.06 KB
/
gen_readme.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/usr/bin/env python3
"""Generate the dockerfiles from a jinja template."""
import os
import logging
from pathlib import Path
from jinja2 import Environment, FileSystemLoader
from markupsafe import Markup
import yaml
log = logging.getLogger(__name__)
class DisplayablePath(object):
"""Utility to print file folders as a tree."""
display_filename_prefix_middle = '├──'
display_filename_prefix_last = '└──'
display_parent_prefix_middle = ' '
display_parent_prefix_last = '│ '
def __init__(self, path, parent_path, is_last):
self.path = Path(str(path))
self.parent = parent_path
self.is_last = is_last
if self.parent:
self.depth = self.parent.depth + 1
else:
self.depth = 0
@classmethod
def make_tree(cls, root, parent=None, is_last=False, criteria=None):
"""Make the tree as a path."""
root = Path(str(root))
criteria = criteria or cls._default_criteria
displayable_root = cls(root, parent, is_last)
yield displayable_root
children = sorted(list(path
for path in root.iterdir()
if criteria(path)),
key=lambda s: str(s).lower())
count = 1
for path in children:
is_last = count == len(children)
if path.is_dir():
yield from cls.make_tree(path,
parent=displayable_root,
is_last=is_last,
criteria=criteria)
else:
yield cls(path, displayable_root, is_last)
count += 1
@ classmethod
def _default_criteria(cls, path):
"""Default criteria includes everything."""
return True
@ property
def displayname(self):
"""Pretty format the file name."""
if self.path.is_dir():
return self.path.name + '/'
return self.path.name
def displayable(self):
"""Get the name with tree prefixes."""
if self.parent is None:
return self.displayname
_filename_prefix = (self.display_filename_prefix_last
if self.is_last
else self.display_filename_prefix_middle)
parts = ['{!s} {!s}'.format(_filename_prefix,
self.displayname)]
parent = self.parent
while parent and parent.parent is not None:
parts.append(self.display_parent_prefix_middle
if parent.is_last
else self.display_parent_prefix_last)
parent = parent.parent
return ''.join(reversed(parts))
class GenerateExampleReadme():
"""Generate example radme for a folder."""
def __init__(self, readme_template):
self.readme_template = readme_template
self.home_dir = os.getcwd()
def include_input(self, path):
"""The files to expand as input examples."""
include_list = ['.py', '.c', '.litcoffee']
return any(extension in path.displayname for extension in include_list)
def include_output(self, path):
"""The files to expand as output examples."""
include_list = ['.grepout']
return any(extension in path.displayname for extension in include_list)
def get_file_info(self, path):
"""Returns a dictionary of file properties."""
return {
# get the name
"name": path.displayname,
# get the type
"type": path.path.suffix,
# get the path
"path": str(path.path),
# get stem of file name
"stem": path.path.stem
}
def create(self, title, folder):
"""Create the readme file."""
log.info("Generating readme for {}".format(folder))
# mkdocs_config
mkdocs_config = os.path.join(folder, "mkdocs-test.yml")
# input tree
display_tree = []
input_files = []
output_files = []
os.system("cp {0}/mkdocs-test.yml {0}/mkdocs.yml".format(folder))
# Get input tree
def input_criteria(path):
"""The files to include in the input."""
ignore_list = ['site', 'mkdocs-test.yml', '__pycache__']
return not any(extension in path.name for extension in ignore_list)
paths = DisplayablePath.make_tree(
Path(folder), criteria=input_criteria)
for path in paths:
# get all of the grepouts
if self.include_output(path):
output_files.append(self.get_file_info(path))
continue
# get the source files
if self.include_input(path):
input_files.append(self.get_file_info(path))
# create the tree
display_tree.append(path.displayable())
input_tree = "\n".join(display_tree)
# run mkdocs_simple_gen
os.chdir(folder)
os.system("mkdocs_simple_gen --build")
os.chdir(self.home_dir)
# output tree
display_tree = []
site_folder = os.path.join(folder, "site/")
def output_criteria(path):
"""The files to include in the output."""
ignore_list = ['css', 'fonts', 'img', 'js', 'search', "xml", "404"]
return not any(extension in path.name for extension in ignore_list)
paths = DisplayablePath.make_tree(
Path(site_folder), criteria=output_criteria)
for path in paths:
display_tree.append(path.displayable())
output_tree = "\n".join(display_tree)
# write the readme
readme_output = self.readme_template.render(
{
"title": title,
"mkdocs_config": mkdocs_config,
"input_tree": input_tree,
"input_files": input_files,
"output_tree": output_tree,
"output_files": output_files
}
)
readme_file = folder + "/README.md"
readme_out = open(readme_file, "w")
readme_out.write(readme_output)
readme_out.close()
# cleanup
os.system("rm -rf {0}/site {0}/mkdocs.yml".format(folder))
def generate(*args, **kwargs):
"""Generate all of the readmes"""
file_loader = FileSystemLoader('.')
env = Environment(loader=file_loader)
def include_file(name):
"""Function to help includes without applying further macros."""
return Markup(file_loader.get_source(env, name)[0])
env.globals['include_file'] = include_file
readme_template = env.get_template('examples/README.md.jinja')
# Load .pages for titles and filenames
with open("examples/.pages", 'r') as stream:
try:
example_docs = yaml.load(stream, yaml.Loader)
except yaml.YAMLError as exc:
print(exc)
raise
for item in example_docs["nav"]:
for title, folder in item.items():
GenerateExampleReadme(readme_template).create(title, folder)
if __name__ == "__main__":
generate()