Prhub

#49587 [Docs] Use `gen-files` for generated docs content

原始 PR 作者 hmellor 合并时间 2026-07-25 22:43 文件变更 34 提交数 18 评论 2 代码增减 +522 / -868

执行摘要

统一文档生成方式为 gen-files

PR body 指出之前文档生成方法混杂(mkdocs hooks + pre-commit hooks),维护困难。通过统一到 gen-files,简化构建流程,减少 git 跟踪的生成内容,并使 CLI 帮助文本与文档同步。

值得精读,尤其是 generated_content.py 的设计和 fill_markers 的严格校验理念;涉及文档自动化的团队可学习 gen-files 插件的使用模式。

讨论亮点

PR 得到 1 个 approve 评论(来自 DarkLight1337),无其他讨论或争议。

实现拆解

实现拆解分以下步骤:

  1. 新增文档生成核心库 generated_content.py,提供 fill_markers 函数,支持在文档源页中通过 --8<-- "gen:<key>" 标记插入生成内容,避免 pymdownx.snippets 的隐式行为。
  2. 将原本在 docs/mkdocs/hooks/ 下的 generate_argparse.pygenerate_metrics.pygenerate_examples.py 重命名搬迁到 docs/mkdocs/gen_files/,并改造成 gen-files 脚本:去掉 on_startup 函数封装,直接在模块作用域执行生成逻辑;将内容写入替换为 mkdocs_gen_files.open;从写独立文件改为调用 fill_markers 填充标记。
  3. 将原本作为 pre-commit 钩子的 tools/pre_commit/generate_attention_backend_docs.py 搬迁到 docs/mkdocs/gen_files/generate_attention_backends.py,移除 is_relevant_fileRELEVANT_PATTERNS 等预提交逻辑,改用 fill_markers 将生成的表格嵌入 docs/design/attention_backends.md
  4. 修改 docs/mkdocs/hooks/url_schemes.py,增加 replace_docs_link 方法,将 docs.vllm.ai 绝对链接重写为相对链接,并处理 vllm.config.<Class> API 引用转换为 mkdocstrings 交叉引用。
  5. 调整 mkdocs.yaml 配置,注册 gen-files 插件并移除不再需要的生成文件路径;同步删除旧的 .inc.md 文件和 pre-commit 钩子配置。
  6. 更新 vllm/entrypoints/cli/ 下的入口文件(mm_processor.pylaunch.py),添加 DESCRIPTION 和子命令注册,使 CLI 帮助文本完整,以便 gen-files 能生成准确的 CLI 参考。
文件 模块 状态 重要度
docs/mkdocs/gen_files/generate_argparse.py 文档生成 renamed 8.87
docs/mkdocs/gen_files/generated_content.py 文档生成 added 7.69
docs/mkdocs/hooks/url_schemes.py 文档生成 modified 7.07
docs/mkdocs/gen_files/generate_attention_backends.py 文档生成 renamed 8.98
docs/mkdocs/gen_files/generate_metrics.py 文档生成 renamed 7.26

关键符号

fill_markers replace_docs_link format_help linkify_docs_urls child_link generate_markdown_table generate_usage_section generate_priority_section generate_legend _feature_table generate_mla_section on_startup

关键源码片段

docs/mkdocs/gen_files/generated_content.py dependency-wiring

新增核心模块,提供 fill_markers 函数,是统一生成机制的基石。

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
"""
Inline build-time generated content into existing docs pages.Source pages mark where generated content goes with a snippet-style marker,
`--8<-- \"gen:<key>\"`, so the insertion point is explicit and readable.
The substitution happens here (at gen-files time, before mkdocs-gen-files
shadows the page), not via pymdownx.snippets, so the content can be
generated at build time without living in a real file on disk.The `gen:` prefix keeps these markers distinct from real pymdownx.snippets
includes, and `fill_markers` fails loudly if a marker is missing or left
behind (pymdownx.snippets would otherwise silently drop an unsubstituted
marker).
"""from pathlib import Path
import mkdocs_gen_files
import regex as reDOCS_DIR = Path(__file__).parent.parent.parent
_MARKER = '--8<-- "gen:{key}"'
_ANY_MARKER = re.compile(r'--8<-- "gen:[^"]*"')
​
​
def fill_markers(doc_path: str, blocks: dict[str, str]) -> None:
    """Replace `--8<-- "gen:<key>"` markers in a docs page with generated content.    Args:
        doc_path: Docs-relative path of the source page to fill.
        blocks: Mapping of marker key to the markdown to insert in its place.    Raises:
        FileNotFoundError: If the source page does not exist.
        ValueError: If an expected marker is missing, or any `gen:` marker
            is left unsubstituted after filling.
    """
    source = DOCS_DIR / doc_path
    if not source.exists():
        raise FileNotFoundError(
            f"Cannot fill markers in missing page: {doc_path}"
        )
​
    text = source.read_text()
    # 逐个替换标记为对应的生成内容
    for key, content in blocks.items():
        marker = _MARKER.format(key=key)
        if marker not in text:
            raise ValueError(
                f"{doc_path}: missing marker {marker}"
            )
        text = text.replace(marker, content)
​
    # 严格检查是否还有未替换的 gen: 标记
    if leftover := _ANY_MARKER.search(text):
        raise ValueError(
            f"{doc_path}: unsubstituted marker {leftover.group()}"
        )
​
    # 通过 mkdocs_gen_files 写入虚拟文件
    with mkdocs_gen_files.open(doc_path, "w") as f:
        f.write(text)
    # 让编辑按钮指向真实源页(而不是虚拟路径)
    mkdocs_gen_files.set_edit_path(doc_path, doc_path)
docs/mkdocs/hooks/url_schemes.py core-logic

扩展 URL 方案预处理,新增 docs.vllm.ai 绝对链接重写和 API 引用转换,确保生成页面中链接正确。

class UrlSchemesPreprocessor(Preprocessor):
    def run(self, lines):
        page = self.ext.page
        files = self.ext.files
        if page is None:
            return lines
​
        # 定义替换函数
        def replace_docs_link(match: re.Match) -> str:
            """Rewrite absolute docs.vllm.ai links as doc-relative links."""
            title = match.group("title")
            path = match.group("path").rstrip("/")
            fragment = match.group("fragment") or ""
​
            # vllm.config.<Class> API reference -> mkdocstrings cross-reference
            if path == "api/vllm/config" and re.fullmatch(
                r"#vllm\.config\.\w+", fragment
            ):
                ident = fragment[1:]
                return f"[`{ident}`][{ident}]"
​
            # 其他文档页 -> 相对于当前页面的链接
            src = f"{path.removesuffix('.html')}.md"
            if files.get_file_from_path(src) is None:
                return match.group(0) # 未知页面,保留原链接
​
            rel = posixpath.relpath(src, posixpath.dirname(page.file.src_uri))
            if title.startswith("http"):
                title = path.rstrip("/").split("/")[-1].replace("-", " ").title()
                title += fragment.replace("#", " § ").replace("-", " ").title()
​
            return f"[{title}]({rel}{fragment})"
​
        # 对每行应用替换
        lines = [docs_link.sub(replace_docs_link, line) for line in lines]
        # ... 其他替换 ...
        return lines

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

风险较低。主要影响文档构建流程,gen-files 插件配置错误可能导致文档缺失或构建失败。但作者已验证预览页面(metrics、engine_args、attention_backends、CLI 均正常)。不涉及运行时逻辑,对用户无影响。fill_markers 对标记严格校验,若源文档中标记丢失或残留会报错,但这也避免了静默缺失。

对用户:文档浏览体验不变,但生成内容(如表、参数列表)保持与代码同步更可靠。对系统:不再需要在 git 中跟踪 docs/generated/ 下的文件,构建时不需要 pre-commit 钩子。对团队:文档生成逻辑统一在 docs/mkdocs/gen_files/ 下,维护更简单;添加新生成页面时可复用 generated_content.pyfill_markers

文档构建变更 无运行时影响 构建失败风险低

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论