This repository has been archived by the owner on Sep 11, 2024. It is now read-only.
forked from sqlfluff/sqlfluff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate-rule-docs.py
112 lines (95 loc) · 3.89 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
105
106
107
108
109
110
111
112
"""Generate rule documentation automatically."""
import json
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)
rule_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)
rule_list.append((rule.code, rule.name))
# Write them into a json file for use by redirects.
print("Rule Docs Generation: Writing Rule JSON...")
with open(base_path / "source/_partials/rule_list.json", "w", encoding="utf8") as f:
json.dump(rule_list, f)
# 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")