From 982a4bbe8027ee4dbb50441f3bce2e6a7162b151 Mon Sep 17 00:00:00 2001 From: papertager <2567587994@qq.com> Date: Wed, 10 Jun 2026 16:18:32 +0800 Subject: [PATCH 1/2] Add mx-exporter README flag audit --- tests/test_readme_flag_audit.py | 29 ++++++++++++++++ tools/readme_flag_audit.py | 60 +++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 tests/test_readme_flag_audit.py create mode 100644 tools/readme_flag_audit.py diff --git a/tests/test_readme_flag_audit.py b/tests/test_readme_flag_audit.py new file mode 100644 index 0000000..70775f0 --- /dev/null +++ b/tests/test_readme_flag_audit.py @@ -0,0 +1,29 @@ +import sys +import tempfile +import unittest +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "tools")) + +from readme_flag_audit import build + + +class ReadmeFlagAuditTest(unittest.TestCase): + def test_detects_missing_readme_flags(self): + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + package = root / "mx_exporter" + package.mkdir() + (package / "__init__.py").write_text( + 'parser.add_argument("-p", "--port")\nparser.add_argument("-i", "--interval")\n', + encoding="utf-8", + ) + (root / "README.md").write_text("python3 -m mx_exporter -p 8000\n", encoding="utf-8") + + report = build(root) + + self.assertIn("--interval", report["flags_missing_from_readme"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/readme_flag_audit.py b/tools/readme_flag_audit.py new file mode 100644 index 0000000..cc2926b --- /dev/null +++ b/tools/readme_flag_audit.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""Compare CLI flags with README examples and parameter notes.""" + +from __future__ import annotations + +import argparse +import ast +import json +import re +from pathlib import Path + + +FLAG_RE = re.compile(r"-{1,2}[A-Za-z0-9-]+") + + +def cli_flags(init_path: Path) -> set[str]: + module = ast.parse(init_path.read_text(encoding="utf-8"), filename=str(init_path)) + flags = set() + for node in ast.walk(module): + if not isinstance(node, ast.Call): + continue + if not isinstance(node.func, ast.Attribute) or node.func.attr != "add_argument": + continue + for argument in node.args: + if isinstance(argument, ast.Constant) and isinstance(argument.value, str): + flags.add(argument.value) + return flags + + +def readme_flags(readme_path: Path) -> set[str]: + return set(FLAG_RE.findall(readme_path.read_text(encoding="utf-8"))) + + +def build(repo_root: Path) -> dict[str, object]: + cli = cli_flags(repo_root / "mx_exporter" / "__init__.py") + readme = readme_flags(repo_root / "README.md") + return { + "cli_flag_count": len(cli), + "readme_flag_count": len(readme), + "flags_missing_from_readme": sorted(flag for flag in cli - readme if flag.startswith("-")), + "flags_only_in_readme": sorted(flag for flag in readme - cli if flag.startswith("-")), + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--repo-root", type=Path, default=Path(".")) + parser.add_argument("--output", type=Path) + args = parser.parse_args() + + text = json.dumps(build(args.repo_root), indent=2, ensure_ascii=False) + if args.output: + args.output.write_text(text + "\n", encoding="utf-8") + else: + print(text) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From d69f2ae0d680cdf11e8deb46a99680248447e271 Mon Sep 17 00:00:00 2001 From: papertager <2567587994@qq.com> Date: Thu, 11 Jun 2026 00:07:21 +0800 Subject: [PATCH 2/2] Tighten README flag extraction --- tests/test_readme_flag_audit.py | 3 ++- tools/readme_flag_audit.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_readme_flag_audit.py b/tests/test_readme_flag_audit.py index 70775f0..b81e9d5 100644 --- a/tests/test_readme_flag_audit.py +++ b/tests/test_readme_flag_audit.py @@ -18,11 +18,12 @@ def test_detects_missing_readme_flags(self): 'parser.add_argument("-p", "--port")\nparser.add_argument("-i", "--interval")\n', encoding="utf-8", ) - (root / "README.md").write_text("python3 -m mx_exporter -p 8000\n", encoding="utf-8") + (root / "README.md").write_text("python3 -m mx-exporter -p 8000\n", encoding="utf-8") report = build(root) self.assertIn("--interval", report["flags_missing_from_readme"]) + self.assertNotIn("-exporter", report["flags_only_in_readme"]) if __name__ == "__main__": diff --git a/tools/readme_flag_audit.py b/tools/readme_flag_audit.py index cc2926b..b170300 100644 --- a/tools/readme_flag_audit.py +++ b/tools/readme_flag_audit.py @@ -10,7 +10,7 @@ from pathlib import Path -FLAG_RE = re.compile(r"-{1,2}[A-Za-z0-9-]+") +FLAG_RE = re.compile(r"(?:^|\s)(-{1,2}[A-Za-z0-9-]+)") def cli_flags(init_path: Path) -> set[str]: