forked from sqlfluff/sqlfluff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate-rule-docs.py
104 lines (88 loc) · 3.61 KB
/
generate-rule-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
"""Generate rule documentation automatically."""
from collections import defaultdict
from pathlib import Path
from sqlfluff.core.plugin.host import get_plugin_manager
base_path = Path(__file__).parent.absolute()
##########################################
# Generate rule documentation dynamically.
##########################################
autogen_header = """..
NOTE: This file is generated by the conf.py script.
Don't edit this by hand
"""
table_header = f"""
+{'-' * 42}+{'-' * 50}+{'-' * 30}+{'-' * 20}+
|{'Bundle' : <42}|{'Rule Name' : <50}|{'Code' : <30}|{'Aliases' : <20}|
+{'=' * 42}+{'=' * 50}+{'=' * 30}+{'=' * 20}+
"""
# Extract all the rules.
print("Rule Docs Generation: Reading Rules...")
rule_bundles = defaultdict(list)
for plugin_rules in get_plugin_manager().hook.get_rules():
for rule in plugin_rules:
_bundle_name = rule.name.split(".")[0]
rule_bundles[_bundle_name].append(rule)
# Write them into the table. Bundle by bundle.
print("Rule Docs Generation: Writing Rule Table...")
with open(base_path / "source/partials/rule_table.rst", "w", encoding="utf8") as f:
f.write(autogen_header)
f.write(table_header)
for bundle in sorted(rule_bundles.keys()):
# Set the bundle name to the ref.
_bundle_name = f":ref:`bundle_{bundle}`"
for idx, rule in enumerate(rule_bundles[bundle]):
step = 1 # The number of aliases per line.
aliases = ", ".join(rule.aliases[:step]) + (
"," if len(rule.aliases) > step else ""
)
name_ref = f":sqlfluff:ref:`{rule.name}`"
code_ref = f":sqlfluff:ref:`{rule.code}`"
f.write(
f"| {_bundle_name : <40} | {name_ref : <48} "
f"| {code_ref : <28} | {aliases : <18} |\n"
)
j = 1
while True:
if not rule.aliases[j:]:
break
aliases = ", ".join(rule.aliases[j : j + step]) + (
"," if len(rule.aliases[j:]) > step else ""
)
f.write(f"|{' ' * 42}|{' ' * 50}|{' ' * 30}| {aliases : <18} |\n")
j += step
if idx + 1 < len(rule_bundles[bundle]):
f.write(f"|{' ' * 42}+{'-' * 50}+{'-' * 30}+{'-' * 20}+\n")
else:
f.write(f"+{'-' * 42}+{'-' * 50}+{'-' * 30}+{'-' * 20}+\n")
# Unset the bundle name so we don't repeat it.
_bundle_name = ""
f.write("\n\n")
# Write each of the summary files.
print("Rule Docs Generation: Writing Rule Summaries...")
with open(base_path / "source/partials/rule_summaries.rst", "w", encoding="utf8") as f:
f.write(autogen_header)
for bundle in sorted(rule_bundles.keys()):
if "sql" in bundle:
# This accounts for things like "TSQL"
header_name = bundle.upper()
else:
header_name = bundle.capitalize()
# Write the bundle header.
f.write(
f".. _bundle_{bundle}:\n\n"
f"{header_name} bundle\n"
f"{'-' * (len(bundle) + 7)}\n\n"
)
for rule in rule_bundles[bundle]:
f.write(
f".. sqlfluff:rule:: {rule.code}\n"
f" {rule.name}\n\n"
)
# Separate off the heading so we can bold it.
heading, _, doc_body = rule.__doc__.partition("\n")
underline_char = '"'
f.write(f" {heading}\n")
f.write(f" {underline_char * len(heading)}\n\n")
f.write(" " + doc_body)
f.write("\n\n")
print("Rule Docs Generation: Done")