From 47590c54365bd47d1e91fa19491945d7bfa173fa Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Fri, 6 Mar 2026 15:21:20 +0100 Subject: [PATCH 1/2] Add diagraming tooling --- .gitignore | 1 + docs/diagrams/.gitignore | 2 + docs/diagrams/config.toml | 14 + docs/diagrams/main.py | 157 +++ docs/diagrams/src/indexing-parcels.excalidraw | 959 ++++++++++++++++++ pixi.toml | 19 +- 6 files changed, 1148 insertions(+), 4 deletions(-) create mode 100644 docs/diagrams/.gitignore create mode 100644 docs/diagrams/config.toml create mode 100644 docs/diagrams/main.py create mode 100644 docs/diagrams/src/indexing-parcels.excalidraw diff --git a/.gitignore b/.gitignore index a0b957bd95..235fb25699 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ docs/_downloads docs/jupyter_execute/* docs/.jupyter_cache/* docs/reference +docs/diagrams/build output *.log diff --git a/docs/diagrams/.gitignore b/docs/diagrams/.gitignore new file mode 100644 index 0000000000..1ece604ddb --- /dev/null +++ b/docs/diagrams/.gitignore @@ -0,0 +1,2 @@ +# Ignore the built diagrams +build diff --git a/docs/diagrams/config.toml b/docs/diagrams/config.toml new file mode 100644 index 0000000000..b590189d22 --- /dev/null +++ b/docs/diagrams/config.toml @@ -0,0 +1,14 @@ +# Configuration file for diagram generation using Kroki +# Each [[diagram]] entry represents a diagram to be generated + +# Example Excalidraw diagram configuration +# [[diagram]] +# file_src = "src/example.excalidraw" +# output_name = "example" +# format = "svg" + +# Add your diagram configurations below +[[diagram]] +file_src = "src/indexing-parcels.excalidraw" +output_name = "indexing-parcels" +format = "svg" diff --git a/docs/diagrams/main.py b/docs/diagrams/main.py new file mode 100644 index 0000000000..b401feb927 --- /dev/null +++ b/docs/diagrams/main.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +""" +Script to generate diagrams from source files using Kroki. + +This script reads configuration from config.toml and processes diagram files +using the kroki CLI tool to generate output images. +""" + +import subprocess +import sys +from pathlib import Path +from typing import Literal + +from pydantic import BaseModel, Field, field_validator + +try: + import tomllib +except ImportError: + import tomli as tomllib + + +# Supported diagram types in Kroki +DiagramType = Literal[ "actdiag", "blockdiag", "bpmn", "bytefield", "c4plantuml", "d2", "diagramsnet", "ditaa", "erd", "excalidraw", "graphviz", "mermaid", "nomnoml", "nwdiag", "packetdiag", "pikchr", "plantuml", "rackdiag", "seqdiag", "structurizr", "svgbob", "umlet", "vega", "vegalite", "wavedrom"] # fmt: skip + +# Supported output formats +OutputFormat = Literal["base64", "jpeg", "pdf", "png", "svg"] + + +class DiagramConfig(BaseModel): + """Configuration for a single diagram.""" + + file_src: str = Field( + ..., description="Path to the source diagram file, relative to the script" + ) + output_name: str | None = Field( + None, description="Output filename without extension (defaults to input stem)" + ) + format: OutputFormat = Field("svg", description="Output format") + type: DiagramType | None = Field( + None, description="Diagram type (defaults to infer from file extension)" + ) + + @field_validator("file_src") + @classmethod + def validate_file_src(cls, v: str) -> str: + """Ensure file_src is not empty.""" + if not v or not v.strip(): + raise ValueError("file_src cannot be empty") + return v + + +class Config(BaseModel): + """Root configuration model.""" + + diagram: list[DiagramConfig] = Field( + default_factory=list, description="List of diagrams to generate" + ) + + +def main(): + """Main function to process diagrams based on config.toml.""" + script_dir = Path(__file__).parent + config_file = script_dir / "config.toml" + build_dir = script_dir / "build" + + # Ensure build directory exists + build_dir.mkdir(parents=True, exist_ok=True) + + # Load configuration + try: + with open(config_file, "rb") as f: + config_data = tomllib.load(f) + except FileNotFoundError: + print(f"Error: Configuration file not found: {config_file}", file=sys.stderr) + sys.exit(1) + except Exception as e: + print(f"Error reading configuration file: {e}", file=sys.stderr) + sys.exit(1) + + # Validate configuration with Pydantic + try: + config = Config(**config_data) + except Exception as e: + print(f"Error: Invalid configuration: {e}", file=sys.stderr) + sys.exit(1) + + # Check if there are any diagrams configured + if not config.diagram: + print("No diagrams configured in config.toml") + return + + print(f"Processing {len(config.diagram)} diagram(s)...") + + # Process each diagram + for i, diagram in enumerate(config.diagram, 1): + # Get input file path (relative to script directory) + input_file = script_dir / diagram.file_src + if not input_file.exists(): + print( + f"Warning: Source file not found: {input_file}, skipping", + file=sys.stderr, + ) + continue + + # Get output configuration + output_name = diagram.output_name or input_file.stem + output_format = diagram.format + output_file = build_dir / f"{output_name}.{output_format}" + + # Detect diagram type from file extension or use explicit type + if diagram.type: + diagram_type = diagram.type + else: + # Infer from file extension + diagram_type = input_file.suffix.lstrip(".") + if diagram_type == "excalidraw": + diagram_type = "excalidraw" + + # Build kroki command + cmd = [ + "kroki", + "convert", + str(input_file), + "--type", + diagram_type, + "--format", + output_format, + "--out-file", + str(output_file), + ] + + # Execute kroki command + print( + f" [{i}/{len(config.diagram)}] Processing {diagram.file_src} -> {output_file.name}" + ) + try: + result = subprocess.run(cmd, capture_output=True, text=True, check=True) + if result.stdout: + print(f" {result.stdout.strip()}") + except subprocess.CalledProcessError as e: + print( + f" Error processing {diagram.file_src}: {e.stderr.strip()}", + file=sys.stderr, + ) + continue + except FileNotFoundError: + print( + "Error: 'kroki' command not found. Please ensure kroki is installed.", + file=sys.stderr, + ) + sys.exit(1) + + print("Done!") + + +if __name__ == "__main__": + main() diff --git a/docs/diagrams/src/indexing-parcels.excalidraw b/docs/diagrams/src/indexing-parcels.excalidraw new file mode 100644 index 0000000000..8e56c94ef1 --- /dev/null +++ b/docs/diagrams/src/indexing-parcels.excalidraw @@ -0,0 +1,959 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "pS3TSD2GtHyJQDD-PmYtj", + "type": "text", + "x": 450.4439695578745, + "y": 411.19574905612217, + "width": 86.85050697061288, + "height": 14.566385566744904, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2b1", + "roundness": null, + "seed": 901703820, + "version": 444, + "versionNonce": 1505847220, + "isDeleted": false, + "boundElements": [], + "updated": 1765259785797, + "link": null, + "locked": false, + "text": "all-but-dask.yml", + "fontSize": 11.653108453395923, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "all-but-dask.yml", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "_wBmLcXRql6xjeXIxlYw1", + "type": "text", + "x": 471.16276074285076, + "y": 428.2107268435237, + "width": 93.97054583361685, + "height": 14.566385566744904, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2b2", + "roundness": null, + "seed": 946517556, + "version": 296, + "versionNonce": 724639116, + "isDeleted": false, + "boundElements": [], + "updated": 1765259785797, + "link": null, + "locked": false, + "text": "all-but-numba.yml", + "fontSize": 11.653108453395923, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "all-but-numba.yml", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "qLgLNQu1eiueuO-h2PBN4", + "type": "text", + "x": 485.8695875874733, + "y": 445.23711010666653, + "width": 122.15940024614639, + "height": 14.566385566744904, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2b3", + "roundness": null, + "seed": 1634334476, + "version": 299, + "versionNonce": 841109812, + "isDeleted": false, + "boundElements": [], + "updated": 1765259785797, + "link": null, + "locked": false, + "text": "bare-min-and-scipy.yml", + "fontSize": 11.653108453395923, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "bare-min-and-scipy.yml", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "qPV6WyKRadSPMjWcFOjtj", + "type": "text", + "x": 424.373284252489, + "y": 383.8124463238723, + "width": 89.89196454289042, + "height": 14.566385566744904, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2b5", + "roundness": null, + "seed": 1000198068, + "version": 318, + "versionNonce": 885885964, + "isDeleted": false, + "boundElements": [], + "updated": 1765259785797, + "link": null, + "locked": false, + "text": "bare-minimum.yml", + "fontSize": 11.653108453395923, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "bare-minimum.yml", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "WvyvzxNRz6TwidtFQRNGr", + "type": "text", + "x": 528.3200086934362, + "y": 476.5066585466431, + "width": 39.632177663637066, + "height": 14.566385566744904, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2b6", + "roundness": null, + "seed": 833566092, + "version": 357, + "versionNonce": 1906969268, + "isDeleted": false, + "boundElements": [], + "updated": 1765259785797, + "link": null, + "locked": false, + "text": "doc.yml", + "fontSize": 11.653108453395923, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "doc.yml", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "Rd-f8_JPfAhr71hyRcwIb", + "type": "text", + "x": 506.50771213730644, + "y": 461.62343539254255, + "width": 112.40577194188074, + "height": 14.566385566744904, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2b8", + "roundness": null, + "seed": 1815198004, + "version": 295, + "versionNonce": 1574447756, + "isDeleted": false, + "boundElements": [], + "updated": 1765259785797, + "link": null, + "locked": false, + "text": "environment-3.14.yml", + "fontSize": 11.653108453395923, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "environment-3.14.yml", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "IqhERpxqHGLgbP_TAgoHS", + "type": "text", + "x": 543.4874800324359, + "y": 494.9032748844515, + "width": 85.54539785363762, + "height": 14.566385566744904, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2b9", + "roundness": null, + "seed": 1034961548, + "version": 512, + "versionNonce": 721327156, + "isDeleted": false, + "boundElements": [], + "updated": 1765259785797, + "link": null, + "locked": false, + "text": "environment.yml", + "fontSize": 11.653108453395923, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "environment.yml", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "HsAvX9HB6muZ1mC-7VfeI", + "type": "text", + "x": 440.6268194113605, + "y": 397.04963291000456, + "width": 83.84401174650505, + "height": 14.566385566744904, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2bB", + "roundness": null, + "seed": 1716780084, + "version": 398, + "versionNonce": 2030762252, + "isDeleted": false, + "boundElements": [], + "updated": 1765259785797, + "link": null, + "locked": false, + "text": "min-all-deps.yml", + "fontSize": 11.653108453395923, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "min-all-deps.yml", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "oqndYdUISF1toX4hxa9We", + "type": "text", + "x": 526.1040680295845, + "y": 354.364114770269, + "width": 25.951950073242188, + "height": 20, + "angle": 0.5890106895717713, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2bC", + "roundness": null, + "seed": 1957946508, + "version": 121, + "versionNonce": 1371260428, + "isDeleted": false, + "boundElements": [], + "updated": 1765259713586, + "link": null, + "locked": false, + "text": ". . .", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": ". . .", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "cfS6BY8IKv5djnT6kEx-I", + "type": "line", + "x": 1011.8700724289458, + "y": 186.76441515025076, + "width": 0, + "height": 649.0393866414967, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2bt", + "roundness": { + "type": 2 + }, + "seed": 216185868, + "version": 235, + "versionNonce": 1369586316, + "isDeleted": false, + "boundElements": [], + "updated": 1765259589945, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 649.0393866414967 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "LTExYj_QVNpiKnSxdBIxx", + "type": "text", + "x": 666.0621758585035, + "y": 192.96430962228686, + "width": 66.47994995117188, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2bx", + "roundness": null, + "seed": 1322149772, + "version": 113, + "versionNonce": 152242444, + "isDeleted": false, + "boundElements": [], + "updated": 1765259589945, + "link": null, + "locked": false, + "text": "Before", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Before", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "QYXvQ2RKiZCKbBTCYl4Yy", + "type": "text", + "x": 1207.2727699748636, + "y": 203.49685112455137, + "width": 53.49995422363281, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2bzl", + "roundness": null, + "seed": 864480012, + "version": 112, + "versionNonce": 1717962636, + "isDeleted": false, + "boundElements": [], + "updated": 1765259589945, + "link": null, + "locked": false, + "text": "After", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "After", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "_N3yj8qLu_gfVEOp18CWm", + "type": "rectangle", + "x": 555.3390308011008, + "y": 298.9368125997553, + "width": 125.81449966376888, + "height": 159.6718100577669, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "qngFaoPhiqQu-5F0tWBnA" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2bzzwV", + "roundness": { + "type": 3 + }, + "seed": 340677132, + "version": 1188, + "versionNonce": 1305818636, + "isDeleted": false, + "boundElements": [], + "updated": 1765259589945, + "link": null, + "locked": false + }, + { + "id": "F1v_V_1fuqjX75x_qLutt", + "type": "rectangle", + "x": 567.9675379348723, + "y": 324.7025131758043, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "qngFaoPhiqQu-5F0tWBnA" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2bzzx", + "roundness": null, + "seed": 1129697204, + "version": 584, + "versionNonce": 63604660, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593540, + "link": null, + "locked": false + }, + { + "id": "227Tm5tcQoPtEcJJa9b83", + "type": "rectangle", + "x": 567.9675379348723, + "y": 388.0399413722284, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "qngFaoPhiqQu-5F0tWBnA" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2bzzy", + "roundness": null, + "seed": 338056628, + "version": 821, + "versionNonce": 1506409868, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593540, + "link": null, + "locked": false + }, + { + "id": "YqiUQEdpReCD1LNWH2cmB", + "type": "rectangle", + "x": 567.9675379348723, + "y": 406.72738921589297, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "qngFaoPhiqQu-5F0tWBnA" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2bzzz", + "roundness": null, + "seed": 1840873268, + "version": 888, + "versionNonce": 2114416948, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593540, + "link": null, + "locked": false + }, + { + "id": "dubEsdJ7UpxQhKvYiI2yZ", + "type": "text", + "x": 510.10270690114385, + "y": 273.54078397554827, + "width": 173.31837421160614, + "height": 40, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2bzzzx", + "roundness": null, + "seed": 909805196, + "version": 546, + "versionNonce": 319773580, + "isDeleted": false, + "boundElements": [], + "updated": 1765259634954, + "link": null, + "locked": false, + "text": "Many environment.yml\nfiles", + "fontSize": 16, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Many environment.yml files", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "YlkdfMI3umY79rgyDc6oQ", + "type": "frame", + "x": 290.8519652874269, + "y": 146.1318766609008, + "width": 1330.377796661944, + "height": 739.8808046076831, + "angle": 0, + "strokeColor": "#bbb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b2c", + "roundness": null, + "seed": 1125351476, + "version": 391, + "versionNonce": 51768972, + "isDeleted": false, + "boundElements": [], + "updated": 1765259589945, + "link": null, + "locked": false, + "name": null + }, + { + "id": "JDQ8PY5kePHYDDgaBkwvw", + "type": "rectangle", + "x": 574.9215117412518, + "y": 316.3070800452902, + "width": 125.81449966376888, + "height": 159.6718100577669, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "PfWysFd2ewMGF0IHPYSgB" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2d", + "roundness": { + "type": 3 + }, + "seed": 1160712332, + "version": 1160, + "versionNonce": 972045580, + "isDeleted": false, + "boundElements": [], + "updated": 1765259589945, + "link": null, + "locked": false + }, + { + "id": "lL0W6OTWJ8S1wVQiaddVL", + "type": "rectangle", + "x": 589.4780107244567, + "y": 404.64809842052426, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "PfWysFd2ewMGF0IHPYSgB" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2e", + "roundness": null, + "seed": 846473012, + "version": 1179, + "versionNonce": 1565158412, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593541, + "link": null, + "locked": false + }, + { + "id": "SfArjsHRbd9xdkEkcp6ra", + "type": "rectangle", + "x": 589.4780107244567, + "y": 423.33554626418885, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "PfWysFd2ewMGF0IHPYSgB" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2f", + "roundness": null, + "seed": 1968251060, + "version": 1245, + "versionNonce": 1139485364, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593541, + "link": null, + "locked": false + }, + { + "id": "sRr8RSx-zO4Y9V5FEef81", + "type": "rectangle", + "x": 601.5273546686503, + "y": 335.1590988499276, + "width": 125.81449966376888, + "height": 159.6718100577669, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "fwma7iZsCOUMDqvgUR1oF" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2g", + "roundness": { + "type": 3 + }, + "seed": 466764300, + "version": 1929, + "versionNonce": 475285644, + "isDeleted": false, + "boundElements": [], + "updated": 1765259589945, + "link": null, + "locked": false + }, + { + "id": "tqR6HBmciq52Z_1trT4iI", + "type": "rectangle", + "x": 613.4121276518713, + "y": 359.0448926794787, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "fwma7iZsCOUMDqvgUR1oF" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2h", + "roundness": null, + "seed": 682980916, + "version": 1086, + "versionNonce": 1094757172, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593540, + "link": null, + "locked": false + }, + { + "id": "IutTOPmDCQ4vO7AfSoQp-", + "type": "rectangle", + "x": 613.4121276518713, + "y": 376.35880596425426, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "fwma7iZsCOUMDqvgUR1oF" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2i", + "roundness": null, + "seed": 928161460, + "version": 1120, + "versionNonce": 1893323276, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593540, + "link": null, + "locked": false + }, + { + "id": "mO2QfLvDkJx69QQuCZQ-q", + "type": "rectangle", + "x": 613.4121276518713, + "y": 392.66630452615715, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "fwma7iZsCOUMDqvgUR1oF" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2j", + "roundness": null, + "seed": 34167604, + "version": 1168, + "versionNonce": 2146247860, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593540, + "link": null, + "locked": false + }, + { + "id": "7X19cJqNjgUwtMcZP4jm0", + "type": "rectangle", + "x": 613.4121276518713, + "y": 405.8406251772306, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "fwma7iZsCOUMDqvgUR1oF" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2k", + "roundness": null, + "seed": 2035589940, + "version": 1257, + "versionNonce": 476819596, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593540, + "link": null, + "locked": false + }, + { + "id": "3gVXvp4oqN8BoKcbmRLtz", + "type": "rectangle", + "x": 613.4121276518713, + "y": 422.287376090726, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "fwma7iZsCOUMDqvgUR1oF" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2l", + "roundness": null, + "seed": 1268557620, + "version": 1322, + "versionNonce": 1976462900, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593540, + "link": null, + "locked": false + }, + { + "id": "geh_KCBzxNsSRJJTExpSu", + "type": "rectangle", + "x": 613.4121276518713, + "y": 441.0697687195673, + "width": 101.79030418790063, + "height": 9.972367269722211, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "fwma7iZsCOUMDqvgUR1oF" + ], + "frameId": "YlkdfMI3umY79rgyDc6oQ", + "index": "b2m", + "roundness": null, + "seed": 1665024268, + "version": 1391, + "versionNonce": 1732099852, + "isDeleted": false, + "boundElements": [], + "updated": 1765259593540, + "link": null, + "locked": false + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff", + "lockedMultiSelections": {} + }, + "files": {} +} diff --git a/pixi.toml b/pixi.toml index 71ddfe96ed..c6cf5c82a1 100644 --- a/pixi.toml +++ b/pixi.toml @@ -1,7 +1,7 @@ [workspace] name = "Parcels" preview = ["pixi-build"] -channels = ["conda-forge"] +channels = ["conda-forge", "https://prefix.dev/github-releases"] platforms = ["win-64", "linux-64", "osx-64", "osx-arm64"] requires-pixi = ">=0.63.0" @@ -91,11 +91,22 @@ sphinx-autobuild = "*" sphinxcontrib-mermaid = "*" sphinx-design = "*" sphinx-autoapi = "*" +pydantic = "*" +kroki-cli = { version = "*", channel = "https://prefix.dev/github-releases" } [feature.docs.tasks] -docs = { cmd = "sphinx-build docs docs/_build", description = "Build the documentation." } -docs-watch = { cmd = "sphinx-autobuild docs docs/_build", description = "Build and auto-rebuild the documentation on changes." } -docs-linkcheck = { cmd = "sphinx-build -b linkcheck docs/ docs/_build/linkcheck", description = "Verify all links in documentation don't 404." } +docs = { cmd = "sphinx-build docs docs/_build", depends-on = [ + 'docs-diagrams', +], description = "Build the documentation." } +docs-watch = { cmd = "sphinx-autobuild docs docs/_build", depends-on = [ + 'docs-diagrams', +], description = "Build and auto-rebuild the documentation on changes." } +docs-linkcheck = { cmd = "sphinx-build -b linkcheck docs/ docs/_build/linkcheck", depends-on = [ + 'docs-diagrams', +], description = "Verify all links in documentation don't 404." } +docs-diagrams = { cmd = "python docs/diagrams/main.py", description = "Build diagrams using Kroki.", outputs = [ + "docs/diagrams/build", +] } [feature.pre-commit.dependencies] pre_commit = "*" From ca336c414be4105625af365a598c5d09394d6b62 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Fri, 6 Mar 2026 17:39:50 +0100 Subject: [PATCH 2/2] Update inputs --- pixi.toml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pixi.toml b/pixi.toml index c6cf5c82a1..77dbe3ca0a 100644 --- a/pixi.toml +++ b/pixi.toml @@ -104,8 +104,10 @@ docs-watch = { cmd = "sphinx-autobuild docs docs/_build", depends-on = [ docs-linkcheck = { cmd = "sphinx-build -b linkcheck docs/ docs/_build/linkcheck", depends-on = [ 'docs-diagrams', ], description = "Verify all links in documentation don't 404." } -docs-diagrams = { cmd = "python docs/diagrams/main.py", description = "Build diagrams using Kroki.", outputs = [ - "docs/diagrams/build", +docs-diagrams = { cmd = "python docs/diagrams/main.py", description = "Build diagrams using Kroki.", inputs = [ + "docs/diagrams/src/*", +], outputs = [ + "docs/diagrams/build/*", ] } [feature.pre-commit.dependencies]