mirror of
https://github.com/tradecatlabs/vibe-coding-cn.git
synced 2026-08-05 15:17:44 +00:00
docs: align onboarding and harden docs checks
This commit is contained in:
@@ -15,19 +15,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
- name: Install markdownlint-cli
|
||||
run: npm install -g markdownlint-cli
|
||||
cache: npm
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Run markdownlint
|
||||
run: markdownlint --config .github/lint_config.json --ignore .history --ignore tools/external '**/*.md'
|
||||
run: npm run lint:md
|
||||
- name: Check local markdown links and anchors
|
||||
run: python3 scripts/check-local-links.py
|
||||
- name: Check markdown details and summaries
|
||||
run: python3 scripts/check-markdown-details.py
|
||||
- name: Check docs README structure
|
||||
run: python3 scripts/check-doc-structure.py
|
||||
- name: Check metadata paths and anchors
|
||||
run: python3 scripts/check-metadata.py
|
||||
- name: Check llms and AI citation paths and anchors
|
||||
@@ -36,8 +39,8 @@ jobs:
|
||||
link-checker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Link Checker
|
||||
uses: lycheeverse/lychee-action@v1.5.0
|
||||
uses: lycheeverse/lychee-action@v2.8.0
|
||||
with:
|
||||
args: --verbose --no-progress --exclude-path .history --exclude-path .github/wiki --exclude-path tools/external --exclude-path tools/chat-vault './**/*.md'
|
||||
args: --verbose --no-progress --exclude-path .history --exclude-path .github/wiki --exclude-path node_modules --exclude-path tools/external --exclude-path tools/chat-vault './**/*.md'
|
||||
|
||||
@@ -14,9 +14,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Run Labeler
|
||||
uses: actions/labeler@v4
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
configuration-path: .github/labeler.yml
|
||||
configuration-path: .github/labeler.yml
|
||||
|
||||
@@ -21,6 +21,9 @@ wheels/
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# Node.js
|
||||
node_modules/
|
||||
|
||||
# Virtual Environment
|
||||
.venv/
|
||||
env/
|
||||
|
||||
@@ -54,7 +54,7 @@ git push origin develop
|
||||
## 3. Must-Run Commands(必须执行的命令清单)
|
||||
|
||||
### 环境要求
|
||||
- Node.js 22+(用于 markdownlint-cli)
|
||||
- Node.js 22+(通过 `package-lock.json` 锁定 markdownlint-cli)
|
||||
- Python 3.8+(用于 prompts-library 工具与链接检查脚本)
|
||||
- Git
|
||||
|
||||
@@ -63,9 +63,10 @@ git push origin develop
|
||||
| 命令 | 用途 | 前置条件 |
|
||||
|:---|:---|:---|
|
||||
| `make help` | 列出所有 Make 目标 | 无 |
|
||||
| `make lint` | 校验全仓库 Markdown | 需安装 markdownlint-cli |
|
||||
| `make lint` | 校验全仓库 Markdown | Node.js 22+;首次运行会通过 `npm ci` 安装锁定依赖 |
|
||||
| `make check-links` | 校验仓库内 Markdown 相对链接 | Python 3 |
|
||||
| `make check-details` | 校验 Markdown 折叠块 `<details>/<summary>` 结构 | Python 3 |
|
||||
| `make check-doc-structure` | 校验 docs 线性 README 主章节顺序、重复锚点与目录入口 | Python 3 |
|
||||
| `make check-metadata` | 校验 metadata 路径与锚点 | Python 3 |
|
||||
| `make check-ai-citation` | 校验 llms 与 AI 引用语料路径和锚点 | Python 3 |
|
||||
| `make test` | 执行本地质量门禁 | Node.js 22+、Python 3 |
|
||||
@@ -113,7 +114,7 @@ git push origin develop
|
||||
## 5. Style & Quality(风格与质量标准)
|
||||
|
||||
### 格式化工具
|
||||
- Markdown:`markdownlint-cli`(通过 `make lint` 执行)
|
||||
- Markdown:锁定在 `package-lock.json` 中的 `markdownlint-cli`(通过 `make lint` 执行)
|
||||
- CI 自动检查:`.github/workflows/ci.yml`
|
||||
|
||||
### 命名约定
|
||||
@@ -150,7 +151,8 @@ git push origin develop
|
||||
│ ├── getting-started/ # 从零开始、学习地图、环境与 AI CLI 配置
|
||||
│ ├── concepts/ # 核心概念、方法论与工程思想
|
||||
│ ├── philosophy/ # 哲学方法论、思维模型与底层认知模型
|
||||
│ └── references/ # 清单、约束、常见坑、模板
|
||||
│ ├── references/ # 清单、约束、常见坑、模板
|
||||
│ └── research/ # 新技术、优秀 repo 与工程范式研究
|
||||
│
|
||||
├── prompts/ # 提示词库入口(指向云端表格)
|
||||
│ ├── README.md # 在线表格链接
|
||||
@@ -210,11 +212,13 @@ git push origin develop
|
||||
- `llms.txt` - 面向 AI 助手的短上下文入口,用于让 LLM 快速理解项目定位
|
||||
- `assets/ai-citation/llms-full.txt` - 面向 AI 助手的完整上下文入口,用于 GEO / AI 推荐与引用
|
||||
- `assets/ai-citation/` - AI 引用语料包,包含摘要、FAQ、对比、推荐回答与 GEO/SEO 检查清单
|
||||
- `package.json` / `package-lock.json` - Node 工具依赖锁定,避免 CI 与本地 markdownlint 版本漂移
|
||||
- `.gitattributes` - GitHub Linguist 语言统计规则,当前将 `tools/external/**` 标记为 vendored
|
||||
- `.github/lint_config.json` - markdownlint 规则,供 `make lint` 与 CI 共用
|
||||
- `.github/workflows/ci.yml` - GitHub Actions:develop/master 分支 markdown-lint + link-checker
|
||||
- `scripts/check-local-links.py` - 仓库内 Markdown 相对链接与锚点检查脚本,供 `make check-links` 与 CI 使用
|
||||
- `scripts/check-markdown-details.py` - 仓库内 Markdown 折叠块结构检查脚本,供 `make check-details` 与 CI 使用
|
||||
- `scripts/check-doc-structure.py` - docs 线性 README 主章节顺序、重复锚点与目录入口检查脚本,供 `make check-doc-structure` 与 CI 使用
|
||||
- `scripts/check-metadata.py` - metadata 路径与锚点检查脚本,供 `make check-metadata` 与 CI 使用
|
||||
- `scripts/check-ai-citation.py` - llms 与 AI 引用语料路径和锚点检查脚本,供 `make check-ai-citation` 与 CI 使用
|
||||
- `tools/prompts-library/main.py` - 提示词转换工具入口
|
||||
@@ -230,7 +234,7 @@ git push origin develop
|
||||
|
||||
| 问题 | 原因 | 修复 |
|
||||
|:---|:---|:---|
|
||||
| `make lint` 失败 | 未安装 markdownlint-cli | `npm install -g markdownlint-cli` |
|
||||
| `make lint` 失败 | Node.js 不可用、`npm ci` 失败或 Markdown 规则违规 | 先确认 `node -v` 为 22+,再运行 `npm ci` 和 `make lint` |
|
||||
| prompts-library 报错 | 缺少 Python 依赖 | `pip install -r tools/prompts-library/requirements.txt` |
|
||||
| prompts-library 辅助脚本报 Google API 依赖错误 | 未安装脚本专用依赖 | `pip install -r tools/prompts-library/scripts/requirements.txt` |
|
||||
| CI markdown-lint 失败 | Markdown 规则违规或本地未按 `.github/lint_config.json` 校验 | 运行 `make lint`,按输出修复对应 Markdown |
|
||||
@@ -265,9 +269,10 @@ feat|fix|docs|chore|refactor|test: scope - summary
|
||||
1. `markdown-lint` - Markdown 格式检查
|
||||
2. `check local markdown links and anchors` - 仓库内相对链接与锚点检查
|
||||
3. `check markdown details and summaries` - Markdown 折叠块结构检查
|
||||
4. `check metadata paths and anchors` - metadata 路径与锚点检查
|
||||
5. `check llms and AI citation paths and anchors` - llms 与 AI 引用语料路径和锚点检查
|
||||
6. `link-checker` - 链接有效性检查
|
||||
4. `check docs README structure` - docs 线性 README 主章节顺序、重复锚点与目录入口检查
|
||||
5. `check metadata paths and anchors` - metadata 路径与锚点检查
|
||||
6. `check llms and AI citation paths and anchors` - llms 与 AI 引用语料路径和锚点检查
|
||||
7. `link-checker` - 链接有效性检查
|
||||
|
||||
### 提交前清单
|
||||
- [ ] 运行 `make lint` 通过
|
||||
@@ -347,7 +352,7 @@ make test
|
||||
- **提示词转换工具:** `tools/prompts-library/`
|
||||
- **数据处理:** `pandas`, `openpyxl`(prompts-library)
|
||||
- **配置管理:** `PyYAML`(prompts-library)
|
||||
- **文档规范:** `markdownlint-cli`
|
||||
- **文档规范:** `package-lock.json` 锁定的 `markdownlint-cli`
|
||||
- **版本控制:** Git
|
||||
- **自动化:** Makefile
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Makefile for Vibe Coding Guide
|
||||
|
||||
.PHONY: help lint check-links check-details check-metadata check-ai-citation build test clean
|
||||
.PHONY: help lint check-links check-details check-doc-structure check-metadata check-ai-citation build test clean
|
||||
|
||||
help:
|
||||
@echo "Makefile for Vibe Coding Guide"
|
||||
@@ -10,6 +10,7 @@ help:
|
||||
@echo " lint - Lint all markdown files"
|
||||
@echo " check-links - Check local markdown links and anchors"
|
||||
@echo " check-details - Check markdown details/summary blocks"
|
||||
@echo " check-doc-structure - Check docs README anchors, order and duplicate anchors"
|
||||
@echo " check-metadata - Check metadata paths and anchors"
|
||||
@echo " check-ai-citation - Check llms and AI citation paths and anchors"
|
||||
@echo " build - Verify knowledge base has no build step"
|
||||
@@ -17,10 +18,12 @@ help:
|
||||
@echo " clean - Remove ignored generated caches"
|
||||
@echo ""
|
||||
|
||||
lint:
|
||||
node_modules/.bin/markdownlint: package.json package-lock.json
|
||||
@npm ci
|
||||
|
||||
lint: node_modules/.bin/markdownlint
|
||||
@echo "Linting markdown files..."
|
||||
@npm install -g markdownlint-cli
|
||||
@markdownlint --config .github/lint_config.json --ignore .history --ignore tools/external '**/*.md'
|
||||
@npm run lint:md
|
||||
|
||||
check-links:
|
||||
@echo "Checking local markdown links and anchors..."
|
||||
@@ -30,6 +33,10 @@ check-details:
|
||||
@echo "Checking markdown details/summary blocks..."
|
||||
@python3 scripts/check-markdown-details.py
|
||||
|
||||
check-doc-structure:
|
||||
@echo "Checking docs README structure..."
|
||||
@python3 scripts/check-doc-structure.py
|
||||
|
||||
check-metadata:
|
||||
@echo "Checking metadata paths and anchors..."
|
||||
@python3 scripts/check-metadata.py
|
||||
@@ -41,7 +48,7 @@ check-ai-citation:
|
||||
build:
|
||||
@echo "No build step: this repository is a documentation and knowledge-base project."
|
||||
|
||||
test: lint check-links check-details check-metadata check-ai-citation
|
||||
test: lint check-links check-details check-doc-structure check-metadata check-ai-citation
|
||||
@echo "Quality gates complete."
|
||||
|
||||
clean:
|
||||
|
||||
@@ -146,29 +146,33 @@
|
||||
|
||||
## ⚡ 1 分钟快速开始
|
||||
|
||||
> 已有网络和开发环境?直接开始 Vibe Coding!
|
||||
> 新电脑也可以开始:先用网页 AI 这个零依赖入口,生成适合你系统的网络环境、Codex CLI 和本地 Agent 安装步骤。
|
||||
|
||||
**第 1 步**:复制下面的提示词,粘贴到 [ChatGPT](https://chatgpt.com/)
|
||||
**第 1 步**:复制下面的提示词,粘贴到 [ChatGPT](https://chatgpt.com/) / Claude / Gemini 网页版
|
||||
|
||||
```
|
||||
你是一个专业的 AI 编程助手。我想用 Vibe Coding 的方式开发一个项目。
|
||||
你是一个专业的 AI 编程环境配置助手。我要从新电脑开始学习 Vibe Coding。
|
||||
|
||||
请先问我:
|
||||
1. 你想做什么项目?(一句话描述)
|
||||
2. 你熟悉什么编程语言?(不熟悉也没关系)
|
||||
3. 你的操作系统是什么?
|
||||
1. 我的操作系统是什么?Windows 11 / WSL / Linux / macOS?
|
||||
2. 我是否已经能访问 OpenAI、GitHub、Node.js/npm 和系统包管理器?
|
||||
3. 我是否已有可用的 Codex / ChatGPT 订阅?
|
||||
|
||||
然后帮我:
|
||||
1. 推荐最简单的技术栈
|
||||
2. 生成项目结构
|
||||
3. 一步步指导我完成开发
|
||||
1. 先判断网络环境和订阅是否满足 Codex CLI 前置条件。
|
||||
2. 按我的系统生成从 0 到 1 安装 Codex CLI 的步骤。
|
||||
3. 每条需要在终端执行的命令都单独放在代码块里。
|
||||
4. Codex CLI 登录成功后,告诉我如何让本地 Agent 继续配置 Git、Node.js、Python、编辑器、项目依赖、测试命令和 Git 工作流。
|
||||
5. 如果我贴报错,请逐条解释原因并给出下一条最小修复命令。
|
||||
|
||||
要求:每完成一步问我是否成功,再继续下一步。
|
||||
要求:不要跳步;每一步只做一件事;每一步都说明如何判断成功。
|
||||
```
|
||||
|
||||
**第 2 步**:跟着 AI 的指导,把想法变成现实 🚀
|
||||
**第 2 步**:按网页 AI 生成的步骤先装好 Codex CLI。
|
||||
|
||||
**就这么简单!** 更多内容(新手从零开始)请继续阅读 👇
|
||||
**第 3 步**:Codex CLI 跑通后,让本地 Agent 读取本仓库文档并主动配置剩余环境。
|
||||
|
||||
**核心口径**:网页 AI 是零依赖启动器,Codex CLI 是默认本地执行入口。更多内容(新手从零开始)请继续阅读 👇
|
||||
|
||||
### 🚀 从零开始
|
||||
|
||||
@@ -192,7 +196,7 @@
|
||||
### 环境要求
|
||||
|
||||
- Git:版本控制与 submodule 初始化
|
||||
- Node.js 22+:运行 `markdownlint-cli`,与 GitHub Actions 中的 `setup-node@v4` 配置一致
|
||||
- Node.js 22+:通过 `package-lock.json` 锁定并运行 `markdownlint-cli`
|
||||
- Python 3.8+:运行 prompts-library 与链接检查脚本
|
||||
|
||||
### 初始化
|
||||
@@ -216,6 +220,7 @@ pip install -r tools/prompts-library/scripts/requirements.txt
|
||||
| 全仓 Markdown lint | `make lint` | `Makefile` + `.github/lint_config.json` |
|
||||
| 本地相对链接检查 | `make check-links` | `scripts/check-local-links.py` |
|
||||
| 折叠块结构检查 | `make check-details` | `scripts/check-markdown-details.py` |
|
||||
| docs 线性目录结构检查 | `make check-doc-structure` | `scripts/check-doc-structure.py` |
|
||||
| Metadata 路径检查 | `make check-metadata` | `scripts/check-metadata.py` |
|
||||
| AI 引用路径检查 | `make check-ai-citation` | `scripts/check-ai-citation.py` |
|
||||
| 全部本地质量门禁 | `make test` | `Makefile` |
|
||||
@@ -225,7 +230,8 @@ pip install -r tools/prompts-library/scripts/requirements.txt
|
||||
### 配置与 CI
|
||||
|
||||
- Markdown lint 配置:`.github/lint_config.json`
|
||||
- CI 配置:`.github/workflows/ci.yml`,在 `develop` / `master` 分支的 push / pull_request 上运行 markdown-lint、本地链接检查与 link-checker
|
||||
- Node 依赖锁定:`package.json` 与 `package-lock.json`
|
||||
- CI 配置:`.github/workflows/ci.yml`,在 `develop` / `master` 分支的 push / pull_request 上运行 markdown-lint、本地链接检查、docs 结构检查与 link-checker
|
||||
- Codex 配置基线:`tools/config/.codex/config.toml`
|
||||
- Submodule 来源:`.gitmodules`
|
||||
|
||||
@@ -454,7 +460,8 @@ pip install -r tools/prompts-library/scripts/requirements.txt
|
||||
│ ├── getting-started/ # 从零开始、学习地图、环境与 AI CLI 配置
|
||||
│ ├── concepts/ # 核心概念、方法论与底层模型
|
||||
│ ├── philosophy/ # 哲学方法论与底层认知模型
|
||||
│ └── references/ # 清单、约束、常见坑与模板
|
||||
│ ├── references/ # 清单、约束、常见坑与模板
|
||||
│ └── research/ # 新技术、优秀 repo 与工程范式研究
|
||||
├── prompts/ # 提示词库入口(指向云端表格)
|
||||
├── skills/ # 技能库入口
|
||||
│ ├── auto-skill/ # 元技能核心
|
||||
|
||||
Generated
+1162
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "vibe-coding-cn",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"lint:md": "markdownlint --config .github/lint_config.json --ignore .history --ignore node_modules --ignore tools/external '**/*.md'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"markdownlint-cli": "0.48.0"
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
# scripts
|
||||
|
||||
本目录存放仓库级自动化脚本,例如链接检查、索引生成、taxonomy 校验和迁移辅助脚本。
|
||||
本目录存放仓库级自动化脚本,例如链接检查、索引生成、taxonomy 校验和文档结构校验脚本。
|
||||
|
||||
当前已有:
|
||||
|
||||
- `check-local-links.py`:仓库内 Markdown 相对链接与锚点检查脚本。
|
||||
- `check-markdown-details.py`:仓库内 Markdown `<details>/<summary>` 折叠块结构检查脚本。
|
||||
- `check-doc-structure.py`:`docs/` 线性 README 的主章节顺序、重复锚点与细粒度目录入口检查脚本。
|
||||
- `check-metadata.py`:`metadata/taxonomy.yml` 与 `metadata/redirects.yml` 路径和锚点检查脚本。
|
||||
- `check-ai-citation.py`:`llms.txt`、`assets/ai-citation/llms-full.txt` 与 AI 引用语料路径和锚点检查脚本。
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check docs README structure, stable anchors and duplicate manual anchors."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
DOC_READMES: dict[Path, list[str]] = {
|
||||
Path("docs/getting-started/README.md"): [
|
||||
"vibe-coding-experience",
|
||||
"learning-map",
|
||||
"network-environment",
|
||||
"cli-setup",
|
||||
"development-environment",
|
||||
],
|
||||
Path("docs/concepts/README.md"): [
|
||||
"concept-problem-solving",
|
||||
"concept-glue-coding",
|
||||
"concept-system-building",
|
||||
"concept-development-paradigms",
|
||||
"concept-language-layers",
|
||||
"concept-recursive-self-optimizing-system",
|
||||
],
|
||||
Path("docs/philosophy/README.md"): [
|
||||
"philosophy-thinking-models",
|
||||
"philosophy-compositional-description-model",
|
||||
"philosophy-programming-dao",
|
||||
"philosophy-methodology-toolbox",
|
||||
],
|
||||
Path("docs/references/README.md"): [
|
||||
"reference-engineering-practice",
|
||||
"reference-technology-stack",
|
||||
],
|
||||
Path("docs/research/README.md"): [
|
||||
"research-harness-engineering",
|
||||
],
|
||||
}
|
||||
SKIP_PARTS = {".git", ".history", "node_modules"}
|
||||
SKIP_PREFIXES = [
|
||||
Path(".github/wiki"),
|
||||
Path("tools/external"),
|
||||
]
|
||||
ANCHOR_PATTERN = re.compile(r"<a\s+id=[\"']([^\"']+)[\"']")
|
||||
|
||||
|
||||
def strip_fenced_code(text: str) -> str:
|
||||
lines: list[str] = []
|
||||
in_fence = False
|
||||
fence_marker = ""
|
||||
|
||||
for line in text.splitlines():
|
||||
stripped = line.lstrip()
|
||||
if stripped.startswith(("```", "~~~")):
|
||||
marker = stripped[:3]
|
||||
if not in_fence:
|
||||
in_fence = True
|
||||
fence_marker = marker
|
||||
elif marker == fence_marker:
|
||||
in_fence = False
|
||||
fence_marker = ""
|
||||
lines.append("")
|
||||
continue
|
||||
lines.append("" if in_fence else line)
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def should_skip(path: Path) -> bool:
|
||||
rel = path.relative_to(ROOT)
|
||||
if any(part in SKIP_PARTS for part in rel.parts):
|
||||
return True
|
||||
return any(rel == prefix or prefix in rel.parents for prefix in SKIP_PREFIXES)
|
||||
|
||||
|
||||
def duplicate_manual_anchors(path: Path) -> list[str]:
|
||||
text = strip_fenced_code(path.read_text(encoding="utf-8", errors="ignore"))
|
||||
seen: dict[str, int] = {}
|
||||
errors: list[str] = []
|
||||
|
||||
for lineno, line in enumerate(text.splitlines(), start=1):
|
||||
for anchor in ANCHOR_PATTERN.findall(line):
|
||||
if anchor in seen:
|
||||
rel = path.relative_to(ROOT)
|
||||
errors.append(f"{rel}:{lineno}: duplicate manual anchor '{anchor}', first seen at line {seen[anchor]}")
|
||||
else:
|
||||
seen[anchor] = lineno
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
def check_linear_readme(path: Path, expected_anchors: list[str]) -> list[str]:
|
||||
rel = path.relative_to(ROOT)
|
||||
text = strip_fenced_code(path.read_text(encoding="utf-8", errors="ignore"))
|
||||
errors: list[str] = []
|
||||
|
||||
if "完整细粒度目录(点击展开/收起)" not in text:
|
||||
errors.append(f"{rel}: missing collapsible full fine-grained table of contents")
|
||||
|
||||
if "<details>" not in text or "</details>" not in text:
|
||||
errors.append(f"{rel}: missing details block for long-form navigation")
|
||||
|
||||
anchor_lines: dict[str, int] = {}
|
||||
for lineno, line in enumerate(text.splitlines(), start=1):
|
||||
for anchor in ANCHOR_PATTERN.findall(line):
|
||||
anchor_lines.setdefault(anchor, lineno)
|
||||
|
||||
previous_line = 0
|
||||
for anchor in expected_anchors:
|
||||
line = anchor_lines.get(anchor)
|
||||
if line is None:
|
||||
errors.append(f"{rel}: missing required main anchor '{anchor}'")
|
||||
continue
|
||||
if line <= previous_line:
|
||||
errors.append(f"{rel}:{line}: main anchor '{anchor}' is out of expected section order")
|
||||
previous_line = line
|
||||
|
||||
toc_boundary = min((anchor_lines.get(anchor, len(text.splitlines()) + 1) for anchor in expected_anchors), default=0)
|
||||
toc_text = "\n".join(text.splitlines()[:toc_boundary])
|
||||
for anchor in expected_anchors:
|
||||
if f"#{anchor}" not in toc_text:
|
||||
errors.append(f"{rel}: top navigation or fine-grained TOC does not link to '#{anchor}'")
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
def main() -> int:
|
||||
errors: list[str] = []
|
||||
checked_files = 0
|
||||
|
||||
for markdown_file in sorted(ROOT.rglob("*.md")):
|
||||
if should_skip(markdown_file):
|
||||
continue
|
||||
checked_files += 1
|
||||
errors.extend(duplicate_manual_anchors(markdown_file))
|
||||
|
||||
for rel_path, expected_anchors in DOC_READMES.items():
|
||||
path = ROOT / rel_path
|
||||
if not path.exists():
|
||||
errors.append(f"{rel_path}: missing docs README")
|
||||
continue
|
||||
errors.extend(check_linear_readme(path, expected_anchors))
|
||||
|
||||
if errors:
|
||||
print("DOC_STRUCTURE_ERRORS")
|
||||
for error in errors:
|
||||
print(error)
|
||||
print(f"TOTAL={len(errors)}")
|
||||
return 1
|
||||
|
||||
print(f"OK docs structure checked: {checked_files} markdown files")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -10,7 +10,7 @@ from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SKIP_PARTS = {".git", ".history"}
|
||||
SKIP_PARTS = {".git", ".history", "node_modules"}
|
||||
SKIP_PREFIXES = [
|
||||
Path(".github/wiki"),
|
||||
Path("tools/external"),
|
||||
|
||||
@@ -9,7 +9,7 @@ from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SKIP_PARTS = {".git", ".history"}
|
||||
SKIP_PARTS = {".git", ".history", "node_modules"}
|
||||
SKIP_PREFIXES = [
|
||||
Path(".github/wiki"),
|
||||
Path("tools/external"),
|
||||
|
||||
Reference in New Issue
Block a user