feat: Add generate_readme.py script
This commit is contained in:
11
README.md
11
README.md
@@ -1,3 +1,12 @@
|
|||||||
# toolbox
|
# toolbox
|
||||||
|
|
||||||
工具箱
|
工具箱
|
||||||
|
|
||||||
|
# tool list
|
||||||
|
|
||||||
|
> 暂无 Python 脚本或可执行包。
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
> 自动由 `generate_readme.py` 生成
|
||||||
|
|
||||||
|
|||||||
11
README.template.md
Normal file
11
README.template.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# toolbox
|
||||||
|
|
||||||
|
工具箱
|
||||||
|
|
||||||
|
# tool list
|
||||||
|
|
||||||
|
{content}
|
||||||
|
|
||||||
|
---
|
||||||
|
> 自动由 `{script_name}` 生成
|
||||||
|
|
||||||
125
generate_readme.py
Normal file
125
generate_readme.py
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#!/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()
|
||||||
|
|
||||||
Reference in New Issue
Block a user