forked from facebook/buck2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
docs.py
executable file
·123 lines (101 loc) · 3.54 KB
/
docs.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
#!/usr/bin/env python3
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.
"""
Generate API documentation for the website.
"""
import argparse
import os
import subprocess
import tempfile
from pathlib import Path
def read_file(path):
with open(path, "r") as f:
return f.read()
def write_file(path, contents):
with open(path, "w") as f:
f.write(contents)
def buck_command(args):
if args.prod:
return "buck2"
elif args.cargo:
return "cargo run --bin=buck2 --"
else:
return "./buck2.sh"
# Given the path to the documentation, e.g. native/bxl/analysis_result
# produce a new name which is the destination, e.g. bxl/analysis_result
def doc_name(x):
if x.startswith("native/bxl/"):
return x[7:] # drop the native
elif x.endswith("/rules.bzl"):
return "rules"
elif x.endswith("/function"):
# Uninteresting docs we'd rather not have generated
return None
elif x.startswith("native/standard/") or x.startswith("native/extension/"):
return "starlark/" + x.split("/")[-1]
elif x.startswith("native/"):
return "build/" + x[7:]
else:
raise RuntimeError("Unknown name: " + x)
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument(
"--prod",
action="store_true",
default=False,
help="Whether to use the production `buck2` binary",
)
parser.add_argument(
"--cargo",
action="store_true",
default=False,
help="Whethern to use a `cargo` built binary.",
)
args = parser.parse_args()
# Change to buck2 directory
buck2_dir = Path(__file__).parent.absolute()
os.chdir(str(buck2_dir))
# Clear the docs folder first so that if we change the names of any
# objects, we'll remove old docs
for x in Path("docs").rglob("*.generated.md"):
os.remove(x)
# Copy the starlark docs over. docusaurus does not handle upward path traversal very well.
for x in Path("starlark-rust/docs").glob("*.md"):
name = Path(x).stem
prefix = "---\nid: " + name + "\n---\n"
write_file(
"docs/developers/starlark/" + name + ".generated.md", prefix + read_file(x)
)
with tempfile.TemporaryDirectory() as tmp:
# Actually generate the docs
print("Running Buck...")
subprocess.run(
buck_command(args)
+ " docs starlark --format=markdown_files --markdown-files-destination-dir="
+ tmp
+ " --builtins prelude//docs:rules.bzl",
shell=True,
check=True,
)
for orig in Path(tmp).rglob("*.md"):
src = read_file(orig)
path = os.path.relpath(orig, tmp)
if path.endswith(".md"):
path = path[:-3]
name = doc_name(path)
if name is None:
continue
prefix = "---\nid: " + name.rsplit("/")[-1] + "\n---\n"
if name == "rules":
prefix += "# Rules\n\nThese rules are available as standard in Buck2.\n"
src = "\n".join(src.splitlines()[1:])
dest = "docs/api/" + name + ".generated.md"
os.makedirs(Path(dest).parent, exist_ok=True)
write_file(dest, prefix + src)
if __name__ == "__main__":
main()