|
1 | 1 | """Utils to generate rules documentation.""" |
2 | 2 |
|
3 | | -import logging |
4 | | -from collections.abc import Iterable |
5 | | - |
6 | | -from rich import box |
7 | | -from rich.console import RenderableType, group |
8 | | -from rich.markdown import Markdown |
9 | | -from rich.table import Table |
10 | | - |
11 | 3 | from ansiblelint.config import PROFILES |
12 | 4 | from ansiblelint.constants import RULE_DOC_URL |
13 | 5 | from ansiblelint.rules import RulesCollection, TransformMixin |
14 | 6 |
|
15 | | -DOC_HEADER = """ |
16 | | -# Default Rules |
17 | | -
|
18 | | -(lint_default_rules)= |
19 | | -
|
20 | | -Below you can see the list of default rules Ansible Lint use to evaluate playbooks and roles: |
21 | | -
|
22 | | -""" |
23 | 7 |
|
24 | | -_logger = logging.getLogger(__name__) |
25 | | - |
26 | | - |
27 | | -def rules_as_str(rules: RulesCollection) -> RenderableType: |
| 8 | +def rules_as_str(rules: RulesCollection) -> str: |
28 | 9 | """Return rules as string.""" |
29 | | - table = Table(show_header=False, header_style="title", box=box.SIMPLE) |
| 10 | + result = "" |
30 | 11 | for rule in rules.alphabetical(): |
31 | 12 | if issubclass(rule.__class__, TransformMixin): |
32 | 13 | rule.tags.insert(0, "autofix") |
33 | | - tag = f"[dim] ({', '.join(rule.tags)})[/dim]" if rule.tags else "" |
34 | | - table.add_row( |
35 | | - f"[link={RULE_DOC_URL}{rule.id}/]{rule.id}[/link]", |
36 | | - rule.shortdesc + tag, |
37 | | - ) |
38 | | - return table |
| 14 | + tag = f"{','.join(rule.tags)}" if rule.tags else "" |
| 15 | + result += f"- [repr.url][link={RULE_DOC_URL}{rule.id}/]{rule.id}[/link][/] {rule.shortdesc}\n[dim] tags:{tag}[/dim]" |
39 | 16 |
|
| 17 | + if rule.version_changed and rule.version_changed != "historic": |
| 18 | + result += f"[dim] modified:{rule.version_changed}[/]" |
40 | 19 |
|
41 | | -def rules_as_md(rules: RulesCollection) -> str: |
42 | | - """Return md documentation for a list of rules.""" |
43 | | - result = DOC_HEADER |
44 | | - |
45 | | - for rule in rules.alphabetical(): |
46 | | - # because title == rule.id we get the desired labels for free |
47 | | - # and we do not have to insert `(target_header)=` |
48 | | - title = f"{rule.id}" |
49 | | - |
50 | | - if rule.help: |
51 | | - if not rule.help.startswith(f"# {rule.id}"): # pragma: no cover |
52 | | - msg = f"Rule {rule.__class__} markdown help does not start with `# {rule.id}` header.\n{rule.help}" |
53 | | - raise RuntimeError(msg) |
54 | | - result += f"\n\n{rule.help}" |
55 | | - else: |
56 | | - description = rule.description |
57 | | - if rule.link: |
58 | | - description += f" [more]({rule.link})" |
59 | | - |
60 | | - result += f"\n\n## {title}\n\n**{rule.shortdesc}**\n\n{description}" |
61 | | - |
62 | | - # Safety net for preventing us from adding autofix to rules and |
63 | | - # forgetting to mention it inside their documentation. |
64 | | - if "autofix" in rule.tags and "autofix" not in rule.description: |
65 | | - msg = f"Rule {rule.id} is invalid because it has 'autofix' tag but this ability is not documented in its description." |
66 | | - raise RuntimeError(msg) |
67 | | - |
| 20 | + result += " \n" |
68 | 21 | return result |
69 | 22 |
|
70 | 23 |
|
71 | | -@group() |
72 | | -def rules_as_rich(rules: RulesCollection) -> Iterable[Table]: |
73 | | - """Print documentation for a list of rules, returns empty string.""" |
74 | | - width = max(16, *[len(rule.id) for rule in rules]) |
75 | | - for rule in rules.alphabetical(): |
76 | | - table = Table(show_header=True, header_style="title", box=box.MINIMAL) |
77 | | - table.add_column(rule.id, style="dim", width=width) |
78 | | - table.add_column(Markdown(rule.shortdesc)) |
79 | | - |
80 | | - description = rule.help or rule.description |
81 | | - if rule.link: |
82 | | - description += f" [(more)]({rule.link})" |
83 | | - table.add_row("description", Markdown(description)) |
84 | | - if rule.version_changed: |
85 | | - table.add_row("version_changed", rule.version_changed) |
86 | | - if rule.tags: |
87 | | - table.add_row("tags", ", ".join(rule.tags)) |
88 | | - if rule.severity: |
89 | | - table.add_row("severity", rule.severity) |
90 | | - yield table |
91 | | - |
92 | | - |
93 | 24 | def profiles_as_md(*, header: bool = False, docs_url: str = RULE_DOC_URL) -> str: |
94 | 25 | """Return markdown representation of supported profiles.""" |
95 | 26 | result = "" |
@@ -127,8 +58,3 @@ def profiles_as_md(*, header: bool = False, docs_url: str = RULE_DOC_URL) -> str |
127 | 58 |
|
128 | 59 | result += "\n" |
129 | 60 | return result |
130 | | - |
131 | | - |
132 | | -def profiles_as_rich() -> Markdown: |
133 | | - """Return rich representation of supported profiles.""" |
134 | | - return Markdown(profiles_as_md()) |
0 commit comments