-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathbuild-docs-examples.py
127 lines (99 loc) · 3.1 KB
/
build-docs-examples.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
import os
from glob import glob
import subprocess
from hashlib import sha256
from convtools.contrib.tables import Table
from convtools import conversion as c
DOCS_ROOT = "./docs"
RAW_EXAMPLES_DIR = os.path.join(DOCS_ROOT, "examples-raw")
MD_EXAMPLES_DIRNAME = os.path.join(DOCS_ROOT, "examples-md")
LAST_BUILD_LOG = os.path.join(MD_EXAMPLES_DIRNAME, ".last_build.csv")
_ensured_dirs = set()
def ensure_dir(file_path):
dir_to_ensure = os.path.dirname(file_path)
if dir_to_ensure in _ensured_dirs:
return file_path
_ensured_dirs.add(dir_to_ensure)
os.makedirs(dir_to_ensure, exist_ok=True)
return file_path
def get_md_path_to_include(file_path):
return os.path.relpath(file_path, DOCS_ROOT)
def get_raw_examples():
yield from glob(os.path.join(RAW_EXAMPLES_DIR, "**/*.py"), recursive=True)
def indent_lines(s, indent):
return "\n".join(f"{indent}{line}" for line in s.splitlines())
def write_md_example(raw_example_path, output):
md_example_path = (
"%s.md"
% raw_example_path.replace(
RAW_EXAMPLES_DIR, MD_EXAMPLES_DIRNAME
).rsplit(".", 1)[0]
)
with open(raw_example_path, "r") as f_in:
if output:
new_content = f"""/// tab | convtools
new: true
```python
{f_in.read()}
```
///
/// tab | debug stdout
```python
{output}
```
{{ data-search-exclude }}
///
"""
else:
new_content = f"""```python
{f_in.read()}
```
"""
result = subprocess.run(
["sha256sum", md_example_path], capture_output=True
)
if result.returncode == 0:
output = result.stdout.decode("utf-8")
if (
output
and output.split(" ", 1)[0]
== sha256(new_content.encode("utf-8")).hexdigest()
):
print(
f"CHECKED EXAMPLE: {get_md_path_to_include(md_example_path)}"
)
return
with open(ensure_dir(md_example_path), "w") as f_out:
f_out.write(new_content)
print(f"BUILT EXAMPLE : {get_md_path_to_include(md_example_path)}")
def build_example(path):
result = subprocess.run(["python", path], capture_output=True)
if result.returncode != 0:
raise AssertionError(f"failed for {path}")
write_md_example(
raw_example_path=path, output=result.stdout.decode("utf-8")
)
def build_examples():
if os.path.exists(LAST_BUILD_LOG):
path_to_last_build_time = {
row["path"]: row["mtime"]
for row in Table.from_csv(LAST_BUILD_LOG, header=True)
.update(mtime=c.col("mtime").as_type(float))
.into_iter_rows(dict)
}
else:
path_to_last_build_time = {}
logs = []
for path in get_raw_examples():
mtime = os.path.getmtime(path)
logs.append({"path": path, "mtime": mtime})
if (
path in path_to_last_build_time
and mtime <= path_to_last_build_time[path]
):
print(f"UP TO DATE: {path}")
continue
build_example(path)
Table.from_rows(logs).into_csv(ensure_dir(LAST_BUILD_LOG))
if __name__ == "__main__":
build_examples()