From 276bcf788c17bc387984c228d4a5d22bb43062e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 4 Dec 2023 13:00:47 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Update=20docs=20build=20setup,?= =?UTF-8?q?=20add=20support=20for=20sponsors,=20add=20sponsor=20GOVCERT.LU?= =?UTF-8?q?=20(#720)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-docs.yml | 10 +- README.md | 10 +- data/sponsors.yml | 6 ++ docs/img/sponsors/govcert.png | Bin 0 -> 10063 bytes docs/index.md | 19 ++++ mkdocs.insiders.yml | 5 +- mkdocs.maybe-insiders.yml | 6 ++ mkdocs.no-insiders.yml | 0 mkdocs.yml | 28 +++--- pyproject.toml | 2 + scripts/docs.py | 155 +++++++++++++++++++++++++++++++ 11 files changed, 220 insertions(+), 21 deletions(-) create mode 100644 data/sponsors.yml create mode 100644 docs/img/sponsors/govcert.png create mode 100644 mkdocs.maybe-insiders.yml create mode 100644 mkdocs.no-insiders.yml create mode 100644 scripts/docs.py diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 3d29204..2e60ed7 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -30,6 +30,8 @@ jobs: - pyproject.toml - mkdocs.yml - mkdocs.insiders.yml + - ./github/workflows/build-docs.yml + - ./github/workflows/deploy-docs.yml build-docs: needs: @@ -69,12 +71,10 @@ jobs: with: key: mkdocs-cards-${{ github.ref }} path: .cache + - name: Verify README + run: python ./scripts/docs.py verify-readme - name: Build Docs - if: github.event_name == 'pull_request' && github.secret_source != 'Actions' - run: python -m poetry run mkdocs build - - name: Build Docs with Insiders - if: github.event_name != 'pull_request' || github.secret_source == 'Actions' - run: python -m poetry run mkdocs build --config-file mkdocs.insiders.yml + run: python ./scripts/docs.py build - uses: actions/upload-artifact@v3 with: name: docs-site diff --git a/README.md b/README.md index a9387c5..ba3bb21 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,14 @@ The key features are: * **Extensible**: You have all the power of SQLAlchemy and Pydantic underneath. * **Short**: Minimize code duplication. A single type annotation does a lot of work. No need to duplicate models in SQLAlchemy and Pydantic. +## Sponsors + + + + + + + ## SQL Databases in FastAPI @@ -68,7 +76,7 @@ Successfully installed sqlmodel ## Example -For an introduction to databases, SQL, and everything else, see the SQLModel documentation. +For an introduction to databases, SQL, and everything else, see the SQLModel documentation. Here's a quick example. ✨ diff --git a/data/sponsors.yml b/data/sponsors.yml new file mode 100644 index 0000000..95cf878 --- /dev/null +++ b/data/sponsors.yml @@ -0,0 +1,6 @@ +gold: [] +silver: + - url: https://www.govcert.lu + title: This project is being supported by GOVCERT.LU + img: https://sqlmodel.tiangolo.com/img/sponsors/govcert.png +bronze: [] diff --git a/docs/img/sponsors/govcert.png b/docs/img/sponsors/govcert.png new file mode 100644 index 0000000000000000000000000000000000000000..0bb4cb934ae3a8f9aa3d1ce04546eda5b51be4fb GIT binary patch literal 10063 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 +.md-content .md-typeset h1 { display: none; } + +

SQLModel

@@ -38,6 +42,21 @@ The key features are: * **Extensible**: You have all the power of SQLAlchemy and Pydantic underneath. * **Short**: Minimize code duplication. A single type annotation does a lot of work. No need to duplicate models in SQLAlchemy and Pydantic. +## Sponsors + + + +{% if sponsors %} +{% for sponsor in sponsors.gold -%} + +{% endfor -%} +{%- for sponsor in sponsors.silver -%} + +{% endfor %} +{% endif %} + + + ## SQL Databases in FastAPI diff --git a/mkdocs.insiders.yml b/mkdocs.insiders.yml index 9f2775f..d24d754 100644 --- a/mkdocs.insiders.yml +++ b/mkdocs.insiders.yml @@ -1,4 +1,3 @@ -INHERIT: mkdocs.yml plugins: - - search - - social + social: + typeset: diff --git a/mkdocs.maybe-insiders.yml b/mkdocs.maybe-insiders.yml new file mode 100644 index 0000000..07aefaa --- /dev/null +++ b/mkdocs.maybe-insiders.yml @@ -0,0 +1,6 @@ +# Define this here and not in the main mkdocs.yml file because that one could be auto +# updated and written, and the script would remove the env var +INHERIT: !ENV [INSIDERS_FILE, './mkdocs.no-insiders.yml'] +markdown_extensions: + pymdownx.highlight: + linenums: !ENV [LINENUMS, false] diff --git a/mkdocs.no-insiders.yml b/mkdocs.no-insiders.yml new file mode 100644 index 0000000..e69de29 diff --git a/mkdocs.yml b/mkdocs.yml index a41839c..ce98f15 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,3 +1,4 @@ +INHERIT: ./mkdocs.maybe-insiders.yml site_name: SQLModel site_description: SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness. site_url: https://sqlmodel.tiangolo.com/ @@ -36,6 +37,11 @@ theme: repo_name: tiangolo/sqlmodel repo_url: https://github.com/tiangolo/sqlmodel edit_uri: '' +plugins: + search: null + markdownextradata: + data: ./data + nav: - SQLModel: index.md - features.md @@ -98,30 +104,28 @@ nav: - release-notes.md markdown_extensions: -- markdown.extensions.attr_list -- markdown.extensions.tables -- markdown.extensions.md_in_html -- toc: + markdown.extensions.attr_list: + markdown.extensions.tables: + markdown.extensions.md_in_html: + toc: permalink: true -- pymdownx.superfences: + pymdownx.superfences: custom_fences: - name: mermaid class: mermaid format: !!python/name:pymdownx.superfences.fence_code_format '' -- pymdownx.betterem -- pymdownx.highlight: - linenums: !ENV [LINENUMS, false] -- pymdownx.blocks.details -- pymdownx.blocks.admonition: + pymdownx.betterem: + pymdownx.blocks.details: + pymdownx.blocks.admonition: types: - note - info - tip - warning - danger -- pymdownx.blocks.tab: + pymdownx.blocks.tab: alternate_style: True -- mdx_include + mdx_include: extra: analytics: diff --git a/pyproject.toml b/pyproject.toml index 9bfc434..24a6c5c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,8 @@ fastapi = "^0.103.2" ruff = "^0.1.2" # For FastAPI tests httpx = "0.24.1" +typer-cli = "^0.0.13" +mkdocs-markdownextradata-plugin = ">=0.1.7,<0.3.0" [build-system] requires = ["poetry-core"] diff --git a/scripts/docs.py b/scripts/docs.py new file mode 100644 index 0000000..cab6c87 --- /dev/null +++ b/scripts/docs.py @@ -0,0 +1,155 @@ +import logging +import os +import re +import subprocess +from functools import lru_cache +from http.server import HTTPServer, SimpleHTTPRequestHandler +from importlib import metadata +from pathlib import Path + +import mkdocs.commands.build +import mkdocs.commands.serve +import mkdocs.config +import mkdocs.utils +import typer +from jinja2 import Template + +logging.basicConfig(level=logging.INFO) + +mkdocs_name = "mkdocs.yml" +en_docs_path = Path("") + +app = typer.Typer() + + +@lru_cache +def is_mkdocs_insiders() -> bool: + version = metadata.version("mkdocs-material") + return "insiders" in version + + +@app.callback() +def callback() -> None: + if is_mkdocs_insiders(): + os.environ["INSIDERS_FILE"] = "./mkdocs.insiders.yml" + # For MacOS with insiders and Cairo + os.environ["DYLD_FALLBACK_LIBRARY_PATH"] = "/opt/homebrew/lib" + + +index_sponsors_template = """ +{% if sponsors %} +{% for sponsor in sponsors.gold -%} + +{% endfor -%} +{%- for sponsor in sponsors.silver -%} + +{% endfor %} +{% endif %} +""" + + +def generate_readme_content() -> str: + en_index = en_docs_path / "docs" / "index.md" + content = en_index.read_text("utf-8") + match_pre = re.search(r"\n\n", content) + match_start = re.search(r"", content) + match_end = re.search(r"", content) + sponsors_data_path = en_docs_path / "data" / "sponsors.yml" + sponsors = mkdocs.utils.yaml_load(sponsors_data_path.read_text(encoding="utf-8")) + if not (match_start and match_end): + raise RuntimeError("Couldn't auto-generate sponsors section") + if not match_pre: + raise RuntimeError("Couldn't find pre section (