#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 自动生成 README.md:扫描当前目录下的 Python 脚本和可执行包, 提取其 docstring 并更新到 README 中。 """ import os import ast import sys from pathlib import Path # 当前脚本所在目录 SCRIPT_DIR = Path(__file__).parent.resolve() # 输出 README 路径 README_PATH = SCRIPT_DIR / "README.md" # 模板路径(可选) TEMPLATE_PATH = SCRIPT_DIR / "README.template.md" def extract_docstring_from_file(file_path: Path) -> str: """从 Python 文件中提取模块级 docstring。""" try: with open(file_path, "r", encoding="utf-8") as f: node = ast.parse(f.read()) return ast.get_docstring(node) or "(无文档说明)" except Exception as e: return f"(解析失败: {e})" def collect_items(): """收集当前目录下所有 .py 文件和含 __main__.py 的子目录。""" items = [] for item in SCRIPT_DIR.iterdir(): if item.name == Path(__file__).name: continue # 跳过本脚本 if item.name.startswith("."): continue # 跳过隐藏文件/目录 if item.is_file() and item.suffix == ".py": name = item.stem doc = extract_docstring_from_file(item) items.append({"type": "script", "name": name, "doc": doc, "path": item.name}) elif item.is_dir(): main_py = item / "__main__.py" if main_py.exists(): name = item.name doc = extract_docstring_from_file(main_py) items.append({"type": "package", "name": name, "doc": doc, "path": str(item.name) + "/__main__.py"}) # 按名称排序 items.sort(key=lambda x: x["name"].lower()) return items def load_template() -> str: """加载模板:优先用 README.template.md,否则用内置模板。""" if TEMPLATE_PATH.exists(): with open(TEMPLATE_PATH, "r", encoding="utf-8") as f: return f.read() else: # 内置默认模板 return """# 工具集 本目录包含以下可执行脚本与工具包: {content} --- > 自动由 `{script_name}` 生成 """ def generate_content(items): """根据 items 生成 Markdown 内容。""" if not items: return "> 暂无 Python 脚本或可执行包。\n" lines = [] for item in items: title = f"`{item['name']}`" if item["type"] == "package": title += " (包)" lines.append(f"## {title}") lines.append("") # 渲染 docstring(保留原始换行,但缩进处理) doc = item["doc"].strip() if doc: # 如果 docstring 是多行,用引用块或直接段落 if "\n" in doc: lines.append("```text") lines.append(doc) lines.append("```") else: lines.append(doc) else: lines.append("(无文档说明)") lines.append("") lines.append(f"> 文件路径: `{item['path']}`") lines.append("") return "\n".join(lines) def main(): items = collect_items() template = load_template() content = generate_content(items) readme_text = template.format( content=content, script_name=Path(__file__).name ) with open(README_PATH, "w", encoding="utf-8") as f: f.write(readme_text) print(f"✅ README.md 已更新,共收录 {len(items)} 个项目。") if __name__ == "__main__": main()