From 38995e8e128208d9424505faf78648da804bbebe Mon Sep 17 00:00:00 2001 From: "hanzhi.421" Date: Mon, 29 Dec 2025 20:09:13 +0800 Subject: [PATCH 1/3] feat: pre commit of readme metadata --- .pre-commit-config.yaml | 8 ++ workflow_utils/check_readme_metadata.py | 113 ++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 workflow_utils/check_readme_metadata.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3159605..19dbbba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,3 +23,11 @@ repos: - markdownlint-cli2 language: system pass_filenames: false + - id: check-use-cases-readme-metadata + name: check-use-cases-readme-metadata + entry: python + args: + - workflow_utils/check_readme_metadata.py + language: system + files: ^02-use-cases/.*/README\.md$ + types_or: [ markdown ] diff --git a/workflow_utils/check_readme_metadata.py b/workflow_utils/check_readme_metadata.py new file mode 100644 index 0000000..9480884 --- /dev/null +++ b/workflow_utils/check_readme_metadata.py @@ -0,0 +1,113 @@ +# pip install python-frontmatter +from typing import Any +from pathlib import Path +import argparse +import subprocess +import sys +import frontmatter + + +def check_name(metadata: dict[str, Any]): + name = metadata.get("name") + if not name: + raise ValueError("name is required") + + +def check_description(metadata: dict[str, Any]): + description = metadata.get("description") + if not description: + raise ValueError("description is required") + + +def check_senarios(metadata: dict[str, Any]): + senarios = metadata.get("senarios") + if not senarios: + raise ValueError("senarios is required") + if len(senarios) != 4: + raise ValueError("senarios should have 4 items") + + +def check_components(metadata: dict[str, Any]): + standard_components = ["Identity", "MCP Toolset"] + components = metadata.get("components") + if not components: + raise ValueError("components is required") + if len(components) == 0: + raise ValueError("components should have at least 1 item") + for component in components: + name = component.get("name") + if not name: + raise ValueError("component name is required") + desc = component.get("desc") + if not desc: + raise ValueError("component desc is required") + if component["name"] not in standard_components: + raise ValueError(f"component name should be one of {standard_components}") + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser() + parser.add_argument("files", nargs="*") + args = parser.parse_args(argv) + + if not args.files: + post = frontmatter.load("README.md") + check_name(post.metadata) + check_description(post.metadata) + check_senarios(post.metadata) + check_components(post.metadata) + return 0 + + repo_root = Path(__file__).resolve().parent.parent + use_cases_dir = repo_root / "02-use-cases" + + completed = subprocess.run( + [ + "git", + "diff", + "--cached", + "--name-only", + "--diff-filter=ACMRT", + ], + capture_output=True, + text=True, + cwd=str(repo_root), + ) + staged_files = { + line.strip() for line in completed.stdout.splitlines() if line.strip() + } + + failed = False + + for file_path in args.files: + path = Path(file_path).resolve() + try: + rel = path.relative_to(repo_root) + except ValueError: + continue + + if path.name.lower() != "readme.md": + continue + + if use_cases_dir not in path.parents: + continue + + if str(rel) not in staged_files: + continue + + post = frontmatter.load(path) + + try: + check_name(post.metadata) + check_description(post.metadata) + check_senarios(post.metadata) + check_components(post.metadata) + except ValueError as exc: + sys.stderr.write(f"{rel}: {exc}\n") + failed = True + + return 1 if failed else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 2f87f2d3d0414e8edab742a4d2db0995e9f7173d Mon Sep 17 00:00:00 2001 From: "hanzhi.421" Date: Mon, 29 Dec 2025 20:13:42 +0800 Subject: [PATCH 2/3] fix: pre commit of readme metadata script --- workflow_utils/check_readme_metadata.py | 33 +++++++++++++------------ 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/workflow_utils/check_readme_metadata.py b/workflow_utils/check_readme_metadata.py index 9480884..a61f0f5 100644 --- a/workflow_utils/check_readme_metadata.py +++ b/workflow_utils/check_readme_metadata.py @@ -61,21 +61,22 @@ def main(argv: list[str] | None = None) -> int: repo_root = Path(__file__).resolve().parent.parent use_cases_dir = repo_root / "02-use-cases" - completed = subprocess.run( - [ - "git", - "diff", - "--cached", - "--name-only", - "--diff-filter=ACMRT", - ], - capture_output=True, - text=True, - cwd=str(repo_root), - ) - staged_files = { - line.strip() for line in completed.stdout.splitlines() if line.strip() - } + diff_commands = [ + ["git", "diff", "--name-only", "--diff-filter=ACMRT"], + ["git", "diff", "--cached", "--name-only", "--diff-filter=ACMRT"], + ] + + changed_files: set[str] = set() + for cmd in diff_commands: + completed = subprocess.run( + cmd, + capture_output=True, + text=True, + cwd=str(repo_root), + ) + changed_files.update( + line.strip() for line in completed.stdout.splitlines() if line.strip() + ) failed = False @@ -92,7 +93,7 @@ def main(argv: list[str] | None = None) -> int: if use_cases_dir not in path.parents: continue - if str(rel) not in staged_files: + if str(rel) not in changed_files: continue post = frontmatter.load(path) From fa9ee0cf81a43151202a4b175676994c921de622 Mon Sep 17 00:00:00 2001 From: "hanzhi.421" Date: Mon, 29 Dec 2025 20:20:12 +0800 Subject: [PATCH 3/3] fix: pre commit with python frontmatter --- .pre-commit-config.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 19dbbba..1056db3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,6 +28,8 @@ repos: entry: python args: - workflow_utils/check_readme_metadata.py - language: system + language: python + additional_dependencies: + - python-frontmatter files: ^02-use-cases/.*/README\.md$ types_or: [ markdown ]