mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00

## Summary We don't enable E501 by default, but `line-length` is a useful example for configuration, so we now set `--extend-select` in the tutorial with a note to that effect. I've also updated all the outputs to match the latest CLI behavior, and changed the example from `List` to `Sequence` because `List` now spits out two diagnostics (one for the import, one for the usage), which IMO is confusing for beginners.
154 lines
5.2 KiB
Python
154 lines
5.2 KiB
Python
"""Generate an MkDocs-compatible `docs` and `mkdocs.yml` from the README.md."""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
from typing import NamedTuple
|
|
|
|
import yaml
|
|
|
|
|
|
class Section(NamedTuple):
|
|
"""A section to include in the MkDocs documentation."""
|
|
|
|
title: str
|
|
filename: str
|
|
generated: bool
|
|
|
|
|
|
SECTIONS: list[Section] = [
|
|
Section("Overview", "index.md", generated=True),
|
|
Section("Tutorial", "tutorial.md", generated=False),
|
|
Section("Installation", "installation.md", generated=False),
|
|
Section("Usage", "usage.md", generated=False),
|
|
Section("Configuration", "configuration.md", generated=False),
|
|
Section("Preview", "preview.md", generated=False),
|
|
Section("Rules", "rules.md", generated=True),
|
|
Section("Settings", "settings.md", generated=True),
|
|
Section("Editor Integrations", "editor-integrations.md", generated=False),
|
|
Section("Versioning", "versioning.md", generated=False),
|
|
Section("FAQ", "faq.md", generated=False),
|
|
Section("Contributing", "contributing.md", generated=True),
|
|
]
|
|
|
|
|
|
LINK_REWRITES: dict[str, str] = {
|
|
"https://docs.astral.sh/ruff/": "index.md",
|
|
"https://docs.astral.sh/ruff/configuration/": "configuration.md",
|
|
"https://docs.astral.sh/ruff/configuration/#pyprojecttoml-discovery": (
|
|
"configuration.md#pyprojecttoml-discovery"
|
|
),
|
|
"https://docs.astral.sh/ruff/contributing/": "contributing.md",
|
|
"https://docs.astral.sh/ruff/editor-integrations/": "editor-integrations.md",
|
|
"https://docs.astral.sh/ruff/faq/#how-does-ruff-compare-to-flake8": (
|
|
"faq.md#how-does-ruff-compare-to-flake8"
|
|
),
|
|
"https://docs.astral.sh/ruff/installation/": "installation.md",
|
|
"https://docs.astral.sh/ruff/rules/": "rules.md",
|
|
"https://docs.astral.sh/ruff/settings/": "settings.md",
|
|
}
|
|
|
|
|
|
def clean_file_content(content: str, title: str) -> str:
|
|
"""Add missing title, fix the header depth, and remove trailing empty lines."""
|
|
lines = content.splitlines()
|
|
if lines[0].startswith("# "):
|
|
return content
|
|
|
|
in_code_block = False
|
|
for i, line in enumerate(lines):
|
|
if line.startswith("```"):
|
|
in_code_block = not in_code_block
|
|
if not in_code_block and line.startswith("#"):
|
|
lines[i] = line[1:]
|
|
|
|
# Remove trailing empty lines.
|
|
for line in reversed(lines):
|
|
if line == "":
|
|
del lines[-1]
|
|
else:
|
|
break
|
|
|
|
content = "\n".join(lines) + "\n"
|
|
|
|
# Add a missing title.
|
|
return f"# {title}\n\n" + content
|
|
|
|
|
|
def main() -> None:
|
|
"""Generate an MkDocs-compatible `docs` and `mkdocs.yml`."""
|
|
subprocess.run(["cargo", "dev", "generate-docs"], check=True)
|
|
|
|
with Path("README.md").open(encoding="utf8") as fp:
|
|
content = fp.read()
|
|
|
|
# Rewrite links to the documentation.
|
|
for src, dst in LINK_REWRITES.items():
|
|
before = content
|
|
after = content.replace(f"({src})", f"({dst})")
|
|
if before == after:
|
|
msg = f"Unexpected link rewrite in README.md: {src}"
|
|
raise ValueError(msg)
|
|
content = after
|
|
|
|
if m := re.search(r"\(https://docs.astral.sh/ruff/.*\)", content):
|
|
msg = f"Unexpected absolute link to documentation: {m.group(0)}"
|
|
raise ValueError(msg)
|
|
|
|
Path("docs").mkdir(parents=True, exist_ok=True)
|
|
|
|
# Split the README.md into sections.
|
|
for title, filename, generated in SECTIONS:
|
|
if not generated:
|
|
continue
|
|
|
|
with Path(f"docs/{filename}").open("w+") as f:
|
|
if filename == "contributing.md":
|
|
# Copy the CONTRIBUTING.md.
|
|
shutil.copy("CONTRIBUTING.md", "docs/contributing.md")
|
|
continue
|
|
|
|
if filename == "settings.md":
|
|
file_content = subprocess.check_output(
|
|
["cargo", "dev", "generate-options"],
|
|
encoding="utf-8",
|
|
)
|
|
else:
|
|
block = content.split(f"<!-- Begin section: {title} -->\n\n")
|
|
if len(block) != 2:
|
|
msg = f"Section {title} not found in README.md"
|
|
raise ValueError(msg)
|
|
|
|
block = block[1].split(f"\n<!-- End section: {title} -->")
|
|
if len(block) != 2:
|
|
msg = f"Section {title} not found in README.md"
|
|
raise ValueError(msg)
|
|
|
|
file_content = block[0]
|
|
|
|
if filename == "rules.md":
|
|
file_content += "\n" + subprocess.check_output(
|
|
["cargo", "dev", "generate-rules-table"],
|
|
encoding="utf-8",
|
|
)
|
|
|
|
f.write(clean_file_content(file_content, title))
|
|
|
|
# Add the nav section to mkdocs.yml.
|
|
with Path("mkdocs.template.yml").open(encoding="utf8") as fp:
|
|
config = yaml.safe_load(fp)
|
|
config["nav"] = [{section.title: section.filename} for section in SECTIONS]
|
|
|
|
with Path("mkdocs.generated.yml").open("w+") as fp:
|
|
yaml.safe_dump(config, fp)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description="Generate an MkDocs-compatible `docs` and `mkdocs.yml`.",
|
|
)
|
|
args = parser.parse_args()
|
|
main()
|