Skip to content

Commit 64c4e39

Browse files
authored
Remove formatting options for listing rules (#4432)
1 parent c5817c2 commit 64c4e39

File tree

5 files changed

+18
-103
lines changed

5 files changed

+18
-103
lines changed

src/ansiblelint/__main__.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
from ansible_compat.prerun import get_cache_dir
3636
from filelock import BaseFileLock, FileLock, Timeout
37+
from rich.markdown import Markdown
3738
from rich.markup import escape
3839

3940
from ansiblelint.constants import RC, SKIP_SCHEMA_UPDATE
@@ -72,8 +73,6 @@
7273
if TYPE_CHECKING:
7374
# RulesCollection must be imported lazily or ansible gets imported too early.
7475

75-
from collections.abc import Callable
76-
7776
from ansiblelint.rules import RulesCollection
7877
from ansiblelint.runner import LintResult
7978

@@ -166,17 +165,11 @@ def initialize_options(arguments: list[str] | None = None) -> BaseFileLock | Non
166165
def _do_list(rules: RulesCollection) -> int:
167166
# On purpose lazy-imports to avoid pre-loading Ansible
168167
# pylint: disable=import-outside-toplevel
169-
from ansiblelint.generate_docs import rules_as_md, rules_as_rich, rules_as_str
168+
from ansiblelint.generate_docs import rules_as_str
170169

171170
if options.list_rules:
172-
_rule_format_map: dict[str, Callable[..., Any]] = {
173-
"brief": rules_as_str,
174-
"full": rules_as_rich,
175-
"md": rules_as_md,
176-
}
177-
178171
console.print(
179-
_rule_format_map.get(options.format, rules_as_str)(rules),
172+
rules_as_str(rules),
180173
highlight=False,
181174
)
182175
return 0
@@ -339,9 +332,9 @@ def main(argv: list[str] | None = None) -> int:
339332
from ansiblelint.rules import RulesCollection
340333

341334
if options.list_profiles:
342-
from ansiblelint.generate_docs import profiles_as_rich
335+
from ansiblelint.generate_docs import profiles_as_md
343336

344-
console.print(profiles_as_rich())
337+
console.print(Markdown(profiles_as_md()))
345338
return 0
346339

347340
app = get_app(

src/ansiblelint/cli.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,24 +255,22 @@ def get_cli_parser() -> argparse.ArgumentParser:
255255
dest="list_profiles",
256256
default=False,
257257
action="store_true",
258-
help="List all profiles, no formatting options available.",
258+
help="List all profiles.",
259259
)
260260
listing_group.add_argument(
261261
"-L",
262262
"--list-rules",
263263
dest="list_rules",
264264
default=False,
265265
action="store_true",
266-
help="List all the rules. For listing rules only the following formats "
267-
"for argument -f are supported: {brief, full, md} with 'brief' as default.",
266+
help="List all the rules.",
268267
)
269268
listing_group.add_argument(
270269
"-T",
271270
"--list-tags",
272271
dest="list_tags",
273272
action="store_true",
274-
help="List all the tags and the rules they cover. Increase the verbosity level "
275-
"with `-v` to include 'opt-in' tag and its rules.",
273+
help="List all the tags and the rules they cover.",
276274
)
277275
parser.add_argument(
278276
"-f",

src/ansiblelint/generate_docs.py

Lines changed: 7 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,26 @@
11
"""Utils to generate rules documentation."""
22

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-
113
from ansiblelint.config import PROFILES
124
from ansiblelint.constants import RULE_DOC_URL
135
from ansiblelint.rules import RulesCollection, TransformMixin
146

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-
"""
237

24-
_logger = logging.getLogger(__name__)
25-
26-
27-
def rules_as_str(rules: RulesCollection) -> RenderableType:
8+
def rules_as_str(rules: RulesCollection) -> str:
289
"""Return rules as string."""
29-
table = Table(show_header=False, header_style="title", box=box.SIMPLE)
10+
result = ""
3011
for rule in rules.alphabetical():
3112
if issubclass(rule.__class__, TransformMixin):
3213
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]"
3916

17+
if rule.version_changed and rule.version_changed != "historic":
18+
result += f"[dim] modified:{rule.version_changed}[/]"
4019

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"
6821
return result
6922

7023

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-
9324
def profiles_as_md(*, header: bool = False, docs_url: str = RULE_DOC_URL) -> str:
9425
"""Return markdown representation of supported profiles."""
9526
result = ""
@@ -127,8 +58,3 @@ def profiles_as_md(*, header: bool = False, docs_url: str = RULE_DOC_URL) -> str
12758

12859
result += "\n"
12960
return result
130-
131-
132-
def profiles_as_rich() -> Markdown:
133-
"""Return rich representation of supported profiles."""
134-
return Markdown(profiles_as_md())

test/test_rules_collection.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,21 +140,19 @@ def test_no_duplicate_rule_ids() -> None:
140140
assert not any(y > 1 for y in collections.Counter(rule_ids).values())
141141

142142

143-
def test_rich_rule_listing() -> None:
143+
def test_rule_listing() -> None:
144144
"""Test that rich list format output is rendered as a table.
145145
146146
This check also offers the contract of having rule id, short and long
147147
descriptions in the console output.
148148
"""
149149
rules_path = Path("./test/rules/fixtures").resolve()
150-
result = run_ansible_lint("-r", str(rules_path), "-f", "full", "-L")
150+
result = run_ansible_lint("-r", str(rules_path), "-L")
151151
assert result.returncode == 0
152152

153153
for rule in RulesCollection([rules_path]):
154154
assert rule.id in result.stdout
155155
assert rule.shortdesc in result.stdout
156-
# description could wrap inside table, so we do not check full length
157-
assert rule.description[:30] in result.stdout
158156

159157

160158
def test_rules_id_format(config_options: Options) -> None:

tools/generate_docs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
if __name__ == "__main__":
1414
subprocess.run( # noqa: S603
15-
["ansible-lint", "-L", "--format", "md"], # noqa: S607
15+
["ansible-lint", "--list-rules"], # noqa: S607
1616
check=True,
1717
stdout=subprocess.DEVNULL,
1818
)

0 commit comments

Comments
 (0)