From 5e9af6374164ffaa5223aef54da6ea0f12716e0e Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Thu, 26 Oct 2023 21:39:12 +0200 Subject: [PATCH] feat: add options to list rules The option `--list` is added that allow you to list rules matching a pattern and the option `--show` is present that allow you to pick the level of detail that you want to show for each rule. Fixes #37 --- src/doctor/__init__.py | 24 +++++++++++++++++++++++- src/doctor/cli.py | 16 ++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/doctor/__init__.py b/src/doctor/__init__.py index 5d96c64..e134e7f 100644 --- a/src/doctor/__init__.py +++ b/src/doctor/__init__.py @@ -18,7 +18,8 @@ database. """ -from textwrap import dedent, fill +from fnmatch import fnmatch +from textwrap import dedent, fill, TextWrapper from os.path import dirname, basename, isfile, join from abc import ABC from packaging.version import parse @@ -92,6 +93,27 @@ def register(cls): return cls +def list_rules(pattern, show): + """List all rules matching pattern. + + Will list rules matching `pattern`, and print detailed message if + `details` is true. Note that since the detailed message contains + variables for expansion, and there is no replacements to use, the + message with the placeholders will be printed. + """ + wrapper = TextWrapper(initial_indent=" ", subsequent_indent=" ") + for category, rules in RULES.items(): + for name, cls in rules.items(): + fullname = f"{category}.{name}" + if fnmatch(fullname, pattern): + print(f"{fullname}:") + print(wrapper.fill(cls.__doc__)) + if show in ("details", "message"): + print("\n == MESSAGE ==", end="\n\n") + print(wrapper.fill(cls.message), end="\n\n") + if show == "details" and hasattr(cls, 'detail'): + print(wrapper.fill(cls.detail), end="\n\n") + def check_rules(dbname, user, host, port): """Check all rules with the database.""" conn = psycopg2.connect(dbname=dbname, user=user, diff --git a/src/doctor/cli.py b/src/doctor/cli.py index 73d2d3b..46c1caf 100644 --- a/src/doctor/cli.py +++ b/src/doctor/cli.py @@ -18,7 +18,7 @@ import getpass import os -from doctor import check_rules +from doctor import check_rules, list_rules from doctor.rules import load_rules @@ -42,10 +42,22 @@ def parse_arguments(): parser.add_argument("--verbose", "-v", dest="log_level", action="count", default=2, help='Verbose logging. More options give higher verbosity.') + parser.add_argument("--list", nargs='?', const='*', metavar="PATTERN", + help=("List rules matching pattern. " + "If no pattern is given, will list all rules")) + parser.add_argument( + '--show', choices=['brief', 'message', 'details'], default="brief", + help=("What to show from the rule. The brief description is always shown, " + "but it is possible to show the message and the detailed message as " + "well.") + ) return parser.parse_args() def main(): """Run application.""" load_rules() args = parse_arguments() - check_rules(user=args.user, dbname=args.dbname, port=args.port, host=args.host) + if args.show is not None: + list_rules(args.list, args.show) + else: + check_rules(user=args.user, dbname=args.dbname, port=args.port, host=args.host)