From cba6fd043e129e885e64fcfda45bcbd090eb9be9 Mon Sep 17 00:00:00 2001 From: Damien Garros Date: Mon, 6 Jul 2026 16:48:12 +0000 Subject: [PATCH 1/2] chore(ci): replace markdownlint with rumdl for markdown linting Swap markdownlint-cli2 (run via npx) for rumdl, a Rust-based markdown linter installable from PyPI. This removes the Node.js dependency for the dedicated markdown-lint check, speeds up linting, and consolidates the configuration into pyproject.toml under [tool.rumdl]. Closes #1138 Co-Authored-By: Claude Opus 4.8 --- .agents/commands/pre-ci.md | 2 +- .github/workflows/ci.yml | 21 +- .markdownlint-cli2.yaml | 15 - AGENTS.md | 2 +- changelog/1138.housekeeping.md | 1 + dev/constitution.md | 9 + docs/.markdownlint.yaml | 15 - docs/docs/python-sdk/guides/installation.mdx | 9 + docs/docs/python-sdk/guides/tracking.mdx | 4 +- .../python-sdk/reference/compatibility.mdx | 8 + docs/docs/python-sdk/reference/config.mdx | 48 ++ docs/docs/python-sdk/reference/templating.mdx | 6 + .../sdk_ref/infrahub_sdk/client.mdx | 12 + .../sdk_ref/infrahub_sdk/node/node.mdx | 2 + docs/package-lock.json | 466 ------------------ docs/package.json | 1 - pyproject.toml | 32 ++ tasks.py | 21 +- uv.lock | 69 ++- 19 files changed, 195 insertions(+), 548 deletions(-) delete mode 100644 .markdownlint-cli2.yaml create mode 100644 changelog/1138.housekeeping.md delete mode 100644 docs/.markdownlint.yaml diff --git a/.agents/commands/pre-ci.md b/.agents/commands/pre-ci.md index 7f14d70d..c832cd75 100644 --- a/.agents/commands/pre-ci.md +++ b/.agents/commands/pre-ci.md @@ -7,7 +7,7 @@ Run a subset of fast CI checks locally. These are lightweight validations that c uv run invoke format ``` -2. **Lint** (YAML, Ruff, ty, mypy, markdownlint, vale): +2. **Lint** (YAML, Ruff, ty, mypy, rumdl, vale): ```bash uv run invoke lint ``` diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff89b20e..306ce479 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,27 +99,18 @@ jobs: if: | needs.files-changed.outputs.documentation == 'true' || needs.files-changed.outputs.github_workflows == 'true' - needs: ["files-changed"] + needs: ["files-changed", "prepare-environment"] runs-on: "ubuntu-latest" timeout-minutes: 5 steps: - name: "Check out repository code" uses: "actions/checkout@v7" - - name: "Linting: markdownlint" - uses: DavidAnson/markdownlint-cli2-action@v23 + - name: "Install uv" + uses: astral-sh/setup-uv@v7 with: - config: docs/.markdownlint.yaml - globs: | - **/*.{md,mdx} - !changelog/*.md - !.agents/commands/** - !.agents/skills/** - !.claude/commands/** - !.claude/skills/** - !dev/commands/** - !dev/skills/** - !.specify/templates/** - !.specify/extensions/** + version: ${{ needs.prepare-environment.outputs.UV_VERSION }} + - name: "Linting: rumdl" + run: "uvx rumdl@0.2.28 check ." action-lint: if: needs.files-changed.outputs.github_workflows == 'true' diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml deleted file mode 100644 index 0fb365c0..00000000 --- a/.markdownlint-cli2.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -# markdownlint-cli2 configuration -# https://github.com/DavidAnson/markdownlint-cli2#configuration - -globs: - - "**/*.{md,mdx}" - - "!.venv/**" - - "!node_modules/**" - - "!**/node_modules/**" - - "!.git/**" - - "!.claude/commands/**" - - "!dev/commands/**" - - "!.specify/templates/**" - -# Markdownlint settings are specified separately via --config flag diff --git a/AGENTS.md b/AGENTS.md index d38194f1..fbea0494 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,7 +19,7 @@ Foundational library for programmatically interacting with Infrahub. Abstracts t ```bash uv sync --all-groups --all-extras # Install all deps uv run invoke format # Format code -uv run invoke lint # Full pipeline: ruff, yamllint, ty, mypy, markdownlint, vale +uv run invoke lint # Full pipeline: ruff, yamllint, ty, mypy, rumdl, vale uv run invoke lint-code # All linters for Python code uv run invoke docs-generate # Generate all docs (CLI + SDK) uv run invoke docs-validate # Check generated docs match committed version diff --git a/changelog/1138.housekeeping.md b/changelog/1138.housekeeping.md new file mode 100644 index 00000000..4764d9fa --- /dev/null +++ b/changelog/1138.housekeeping.md @@ -0,0 +1 @@ +Replaced `markdownlint-cli2` with [rumdl](https://github.com/rvben/rumdl) for markdown linting. This removes the Node.js/npm dependency for the markdown check, speeds up linting, and consolidates the configuration into `pyproject.toml` under `[tool.rumdl]`. diff --git a/dev/constitution.md b/dev/constitution.md index a4670ff4..e63ff06b 100644 --- a/dev/constitution.md +++ b/dev/constitution.md @@ -1,46 +1,55 @@ # [PROJECT_NAME] Constitution + ## Core Principles ### [PRINCIPLE_1_NAME] + [PRINCIPLE_1_DESCRIPTION] ### [PRINCIPLE_2_NAME] + [PRINCIPLE_2_DESCRIPTION] ### [PRINCIPLE_3_NAME] + [PRINCIPLE_3_DESCRIPTION] ### [PRINCIPLE_4_NAME] + [PRINCIPLE_4_DESCRIPTION] ### [PRINCIPLE_5_NAME] + [PRINCIPLE_5_DESCRIPTION] ## [SECTION_2_NAME] + [SECTION_2_CONTENT] ## [SECTION_3_NAME] + [SECTION_3_CONTENT] ## Governance + [GOVERNANCE_RULES] diff --git a/docs/.markdownlint.yaml b/docs/.markdownlint.yaml deleted file mode 100644 index f0087fa9..00000000 --- a/docs/.markdownlint.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -default: true -MD013: false # disables max line-length -MD014: false # dollar signs used before commands -MD024: false # disables 'no duplicate headings', which we use in tabs for instructions -MD025: - front_matter_title: "" # prevent collisions with h1s and frontmatter titles -MD029: false # allows manually creating ordered lists -MD033: false # allows inline html to override markdown styles -MD034: false # no-bare-urls -MD041: false # allow 1st line to not be a top-level heading (required for Towncrier) -MD045: false # no alt text around images -MD047: false # single trailing newline -MD059: # Link descriptions that are prohibited - prohibited_texts: [] diff --git a/docs/docs/python-sdk/guides/installation.mdx b/docs/docs/python-sdk/guides/installation.mdx index d50eaf96..5478a956 100644 --- a/docs/docs/python-sdk/guides/installation.mdx +++ b/docs/docs/python-sdk/guides/installation.mdx @@ -1,6 +1,7 @@ --- title: Installing infrahub-sdk --- + # Installing infrahub-sdk The Infrahub SDK for Python is available on [PyPI](https://pypi.org/project/infrahub-sdk/) and can be installed using the pip package installer. It is recommended to install the SDK into a virtual environment. @@ -15,7 +16,9 @@ pip install infrahub-sdk Extras can be installed as part of the Python SDK and are not installed by default. + ### ctl + The `ctl` extra provides the `infrahubctl` command, which allows you to interact with an Infrahub instance. @@ -23,8 +26,11 @@ The `ctl` extra provides the `infrahubctl` command, which allows you to interact ```shell pip install 'infrahub-sdk[ctl]' ``` + + ### tests + The `tests` extra provides all the components for the testing framework of Transforms, Queries and Checks. @@ -32,8 +38,11 @@ The `tests` extra provides all the components for the testing framework of Trans ```shell pip install 'infrahub-sdk[tests]' ``` + + ### all + Installs `infrahub-sdk` together with all the extras. diff --git a/docs/docs/python-sdk/guides/tracking.mdx b/docs/docs/python-sdk/guides/tracking.mdx index 293bd65c..2afb3f67 100644 --- a/docs/docs/python-sdk/guides/tracking.mdx +++ b/docs/docs/python-sdk/guides/tracking.mdx @@ -106,12 +106,14 @@ This behavior ensures that the tracking group specifically reflects changes made When enabling tracking mode with the `start_tracking` method, you can customize the tracking session with the following parameters: + | Parameter | Description | |------------------------|-----------------------------------------------------------------------------------------------------------------------------| | **identifier** | Unique string to identify the session, used for correlating operations and logs. Defaults to "python-sdk" if not specified. | | **params** | Optional dictionary for extra context, enabling fine-grained control over tracking. | | **delete_unused_nodes**| Boolean indicating if nodes not referenced should be automatically deleted, helping maintain a clean state. | | **group_type** | Type of group object for tracking, default is `CoreStandardGroup`, customizable for specific grouping logic. | + These parameters provide flexibility, enabling detailed auditing, efficient data management, and support for idempotent operations. @@ -245,4 +247,4 @@ if group: ``` - + \ No newline at end of file diff --git a/docs/docs/python-sdk/reference/compatibility.mdx b/docs/docs/python-sdk/reference/compatibility.mdx index 8763c4e1..586e5f9e 100644 --- a/docs/docs/python-sdk/reference/compatibility.mdx +++ b/docs/docs/python-sdk/reference/compatibility.mdx @@ -10,6 +10,7 @@ This page documents which versions of the Infrahub Python SDK are compatible wit Each Infrahub release pins a specific SDK version. Using the matching SDK version ensures full compatibility. Newer patch releases of the SDK within the same minor version are generally safe to use. + | Infrahub | Required SDK | Release date | | --- | --- | --- | | 1.9.x | >= 1.20.0 | April 2026 | @@ -23,6 +24,7 @@ Each Infrahub release pins a specific SDK version. Using the matching SDK versio | 1.1.x | >= 1.3.0 | December 2024 | | 1.0.x | >= 1.0.0 | October 2024 | | 0.16.x | >= 0.13.1 | September 2024 | + ## Detailed release mapping @@ -30,6 +32,7 @@ Each Infrahub release pins a specific SDK version. Using the matching SDK versio The table below shows the exact SDK version pinned to each Infrahub release. + | Infrahub | SDK version | Infrahub release date | | --- | --- | --- | | 1.9.3 | 1.20.0 | 2026-05-05 | @@ -123,16 +126,19 @@ The table below shows the exact SDK version pinned to each Infrahub release. | 0.16.3 | 0.14.0 | 2024-10-10 | | 0.16.2 | 0.13.1 | 2024-10-01 | | 0.16.1 | 0.13.1 | 2024-09-25 | + ## Python version support + | SDK version | Python versions | | --- | --- | | >= 1.17.0 | 3.10, 3.11, 3.12, 3.13, 3.14 | | 1.16.0 | 3.10, 3.11, 3.12, 3.13 | | 1.13.0 - 1.15.x | 3.9, 3.10, 3.11, 3.12, 3.13 | + :::note @@ -144,11 +150,13 @@ The Infrahub server requires Python 3.12 or later. The SDK supports older Python Some SDK features require a minimum Infrahub version: + | Feature | Minimum SDK | Minimum Infrahub | | --- | --- | --- | | infrahubctl branch report | 1.19.0 | 1.7 | | FileObject support | 1.19.0 | 1.8 | | NumberPool support | 1.13.0 | 1.3 | + ## General guidance diff --git a/docs/docs/python-sdk/reference/config.mdx b/docs/docs/python-sdk/reference/config.mdx index bbb1b8a7..ffd36fd6 100644 --- a/docs/docs/python-sdk/reference/config.mdx +++ b/docs/docs/python-sdk/reference/config.mdx @@ -29,153 +29,199 @@ The Python SDK (Async or Sync) client can be configured using an instance of the The following settings can be defined in the `Config` class + ## address + **Description**: The URL to use when connecting to Infrahub.
**Type**: `string`
**Default value**: http://localhost:8000
**Environment variable**: `INFRAHUB_ADDRESS`
+ ## api_token + **Description**: API token for authentication against Infrahub.
**Type**: `string`
**Environment variable**: `INFRAHUB_API_TOKEN`
+ ## echo_graphql_queries + **Description**: If set the GraphQL query and variables will be echoed to the screen
**Type**: `boolean`
**Default value**: False
**Environment variable**: `INFRAHUB_ECHO_GRAPHQL_QUERIES`
+ ## username + **Description**: Username for accessing Infrahub
**Type**: `string`
**Environment variable**: `INFRAHUB_USERNAME`
+ ## password + **Description**: Password for accessing Infrahub
**Type**: `string`
**Environment variable**: `INFRAHUB_PASSWORD`
+ ## default_branch + **Description**: Default branch to target if not specified for each request.
**Type**: `string`
**Default value**: main
**Environment variable**: `INFRAHUB_DEFAULT_BRANCH`
+ ## default_branch_from_git + **Description**: Indicates if the default Infrahub branch to target should come from the active branch in the local Git repository.
**Type**: `boolean`
**Default value**: False
**Environment variable**: `INFRAHUB_DEFAULT_BRANCH_FROM_GIT`
+ ## identifier + **Description**: Tracker identifier
**Type**: `string`
**Environment variable**: `INFRAHUB_IDENTIFIER`
+ ## insert_tracker + **Description**: Insert a tracker on queries to the server
**Type**: `boolean`
**Default value**: False
**Environment variable**: `INFRAHUB_INSERT_TRACKER`
+ ## max_concurrent_execution + **Description**: Max concurrent execution in batch mode
**Type**: `integer`
**Default value**: 5
**Environment variable**: `INFRAHUB_MAX_CONCURRENT_EXECUTION`
+ ## mode + **Description**: Default mode for the client
**Type**: `object`
**Environment variable**: `INFRAHUB_MODE`
+ ## pagination_size + **Description**: Page size for queries to the server
**Type**: `integer`
**Default value**: 50
**Environment variable**: `INFRAHUB_PAGINATION_SIZE`
+ ## retry_delay + **Description**: Number of seconds to wait until attempting a retry.
**Type**: `integer`
**Default value**: 5
**Environment variable**: `INFRAHUB_RETRY_DELAY`
+ ## retry_on_failure + **Description**: Retry operation in case of failure
**Type**: `boolean`
**Default value**: False
**Environment variable**: `INFRAHUB_RETRY_ON_FAILURE`
+ ## max_retry_duration + **Description**: Maximum duration until we stop attempting to retry if enabled.
**Type**: `integer`
**Default value**: 300
**Environment variable**: `INFRAHUB_MAX_RETRY_DURATION`
+ ## schema_converge_timeout + **Description**: Number of seconds to wait for schema to have converged
**Type**: `integer`
**Default value**: 60
**Environment variable**: `INFRAHUB_SCHEMA_CONVERGE_TIMEOUT`
+ ## timeout + **Description**: Default connection timeout in seconds
**Type**: `integer`
**Default value**: 60
**Environment variable**: `INFRAHUB_TIMEOUT`
+ ## transport + **Description**: Set an alternate transport using a predefined option
**Type**: `object`
**Environment variable**: `INFRAHUB_TRANSPORT`
+ ## proxy + **Description**: Proxy address
**Type**: `string`
**Environment variable**: `INFRAHUB_PROXY`
+ ## proxy_mounts + **Description**: Proxy mounts configuration
**Type**: `object`
**Environment variable**: `INFRAHUB_PROXY_MOUNTS`
+ ## marketplace_url + **Description**: Base URL for the Infrahub Marketplace.
**Type**: `string`
**Default value**: https://marketplace.infrahub.app
**Environment variable**: `INFRAHUB_MARKETPLACE_URL`
+ ## update_group_context + **Description**: Update GraphQL query groups
**Type**: `boolean`
**Default value**: False
**Environment variable**: `INFRAHUB_UPDATE_GROUP_CONTEXT`
+ ## tls_insecure + **Description**: Indicates if TLS certificates are verified. @@ -185,7 +231,9 @@ The following settings can be defined in the `Config` class **Default value**: False
**Environment variable**: `INFRAHUB_TLS_INSECURE`
+ ## tls_ca_file + **Description**: File path to CA cert or bundle in PEM format
**Type**: `string`
diff --git a/docs/docs/python-sdk/reference/templating.mdx b/docs/docs/python-sdk/reference/templating.mdx index 191d249e..52dff67e 100644 --- a/docs/docs/python-sdk/reference/templating.mdx +++ b/docs/docs/python-sdk/reference/templating.mdx @@ -33,6 +33,7 @@ For backward compatibility, `validate(restricted=True)` maps to `CORE` and `vali The following filters are [shipped with Jinja2](https://jinja.palletsprojects.com/en/stable/templates/#list-of-builtin-filters) and enabled within Infrahub. + | Name | CORE | WORKER | LOCAL | | ---- | ---- | ------ | ----- | | abs | ✅ | ✅ | ✅ | @@ -89,6 +90,7 @@ The following filters are [shipped with Jinja2](https://jinja.palletsprojects.co | wordcount | ✅ | ✅ | ✅ | | wordwrap | ✅ | ✅ | ✅ | | xmlattr | ❌ | ✅ | ✅ | + ## Netutils filters @@ -96,6 +98,7 @@ The following filters are [shipped with Jinja2](https://jinja.palletsprojects.co The following Jinja2 filters from Netutils are included within Infrahub. + | Name | CORE | WORKER | LOCAL | | ---- | ---- | ------ | ----- | | abbreviated_interface_name | ✅ | ✅ | ✅ | @@ -176,6 +179,7 @@ The following Jinja2 filters from Netu | vlanconfig_to_list | ✅ | ✅ | ✅ | | vlanlist_to_config | ✅ | ✅ | ✅ | | wildcardmask_to_netmask | ✅ | ✅ | ✅ | + ## Infrahub filters @@ -183,6 +187,7 @@ The following Jinja2 filters from Netu These filters are provided by the Infrahub SDK for artifact and file object content composition. + | Name | CORE | WORKER | LOCAL | | ---- | ---- | ------ | ----- | | `artifact_content` | ❌ | ✅ | ❌ | @@ -191,6 +196,7 @@ These filters are provided by the Infrahub SDK for artifact and file object cont | `file_object_content_by_id` | ❌ | ✅ | ❌ | | `from_json` | ✅ | ✅ | ✅ | | `from_yaml` | ✅ | ✅ | ✅ | + ### Usage examples diff --git a/docs/docs/python-sdk/sdk_ref/infrahub_sdk/client.mdx b/docs/docs/python-sdk/sdk_ref/infrahub_sdk/client.mdx index 00c44dc6..b4ff5410 100644 --- a/docs/docs/python-sdk/sdk_ref/infrahub_sdk/client.mdx +++ b/docs/docs/python-sdk/sdk_ref/infrahub_sdk/client.mdx @@ -59,6 +59,7 @@ get(self, kind: str | type[SchemaType], raise_when_missing: bool = True, at: Tim ``` + #### `delete` ```python @@ -87,6 +88,7 @@ create(self, kind: type[SchemaType], data: dict | None = ..., branch: str | None ``` + #### `get_version` ```python @@ -264,6 +266,7 @@ Retrieve all nodes of a given kind. - list\[InfrahubNode]: List of Nodes + #### `filters` ```python @@ -312,6 +315,7 @@ Retrieve nodes of a given kind based on provided filters. - list\[InfrahubNodeSync]: List of Nodes that match the given filters. + #### `clone` ```python @@ -439,6 +443,7 @@ Allocate a new IP address by using the provided resource pool. - `ValueError`: If ``resource_pool`` is not a ``CoreIPAddressPool``. + #### `allocate_next_ip_prefix` ```python @@ -483,6 +488,7 @@ Allocate a new IP prefix by using the provided resource pool. - `ValueError`: If ``resource_pool`` is not a ``CoreIPPrefixPool``. + #### `create_batch` ```python @@ -563,6 +569,7 @@ get(self, kind: str | type[SchemaTypeSync], raise_when_missing: bool = True, at: ``` + #### `delete` ```python @@ -591,6 +598,7 @@ create(self, kind: type[SchemaTypeSync], data: dict | None = ..., branch: str | ``` + #### `get_version` ```python @@ -808,6 +816,7 @@ Retrieve all nodes of a given kind. - list\[InfrahubNodeSync]: List of Nodes + #### `filters` ```python @@ -856,6 +865,7 @@ Retrieve nodes of a given kind based on provided filters. - list\[InfrahubNodeSync]: List of Nodes that match the given filters. + #### `create_batch` ```python @@ -948,6 +958,7 @@ Allocate a new IP address by using the provided resource pool. - `ValueError`: If ``resource_pool`` is not a ``CoreIPAddressPool``. + #### `allocate_next_ip_prefix` ```python @@ -992,6 +1003,7 @@ Allocate a new IP prefix by using the provided resource pool. - `ValueError`: If ``resource_pool`` is not a ``CoreIPPrefixPool``. + #### `repository_update_commit` ```python diff --git a/docs/docs/python-sdk/sdk_ref/infrahub_sdk/node/node.mdx b/docs/docs/python-sdk/sdk_ref/infrahub_sdk/node/node.mdx index 8c48dc0b..99671d1e 100644 --- a/docs/docs/python-sdk/sdk_ref/infrahub_sdk/node/node.mdx +++ b/docs/docs/python-sdk/sdk_ref/infrahub_sdk/node/node.mdx @@ -178,6 +178,7 @@ The node must have been saved (have an id) before calling this method. ``` + #### `matches_local_checksum` ```python @@ -696,6 +697,7 @@ The node must have been saved (have an id) before calling this method. ``` + #### `matches_local_checksum` ```python diff --git a/docs/package-lock.json b/docs/package-lock.json index 8f9d613c..a445e87b 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -13,7 +13,6 @@ "@iconify/react": "^6.0.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", - "markdownlint-cli2": "^0.20.0", "prism-react-renderer": "^2.3.0", "raw-loader": "^4.0.2", "react": "^18.0.0", @@ -5177,9 +5176,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5197,9 +5193,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5217,9 +5210,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5237,9 +5227,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5257,9 +5244,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5277,9 +5261,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5405,18 +5386,6 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/@sindresorhus/merge-streams": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", - "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@slorber/remark-comment": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", @@ -6040,12 +6009,6 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, - "node_modules/@types/katex": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", - "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", - "license": "MIT" - }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -9857,18 +9820,6 @@ "node": ">=6.9.0" } }, - "node_modules/get-east-asian-width": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", - "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -11318,12 +11269,6 @@ "node": ">=6" } }, - "node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "license": "MIT" - }, "node_modules/jsonfile": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", @@ -11336,31 +11281,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/katex": { - "version": "0.16.45", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.45.tgz", - "integrity": "sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==", - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], - "license": "MIT", - "dependencies": { - "commander": "^8.3.0" - }, - "bin": { - "katex": "cli.js" - } - }, - "node_modules/katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -11574,9 +11494,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11598,9 +11515,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11622,9 +11536,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11646,9 +11557,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11722,25 +11630,6 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, - "node_modules/linkify-it": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz", - "integrity": "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/markdown-it" - } - ], - "license": "MIT", - "dependencies": { - "uc.micro": "^2.0.0" - } - }, "node_modules/loader-runner": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", @@ -11890,23 +11779,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/markdown-it": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", - "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.1.0" - }, - "bin": { - "markdown-it": "bin/markdown-it.mjs" - } - }, "node_modules/markdown-table": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", @@ -11917,161 +11789,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/markdownlint": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.40.0.tgz", - "integrity": "sha512-UKybllYNheWac61Ia7T6fzuQNDZimFIpCg2w6hHjgV1Qu0w1TV0LlSgryUGzM0bkKQCBhy2FDhEELB73Kb0kAg==", - "license": "MIT", - "dependencies": { - "micromark": "4.0.2", - "micromark-core-commonmark": "2.0.3", - "micromark-extension-directive": "4.0.0", - "micromark-extension-gfm-autolink-literal": "2.1.0", - "micromark-extension-gfm-footnote": "2.1.0", - "micromark-extension-gfm-table": "2.1.1", - "micromark-extension-math": "3.1.0", - "micromark-util-types": "2.0.2", - "string-width": "8.1.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/DavidAnson" - } - }, - "node_modules/markdownlint-cli2": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.20.0.tgz", - "integrity": "sha512-esPk+8Qvx/f0bzI7YelUeZp+jCtFOk3KjZ7s9iBQZ6HlymSXoTtWGiIRZP05/9Oy2ehIoIjenVwndxGtxOIJYQ==", - "license": "MIT", - "dependencies": { - "globby": "15.0.0", - "js-yaml": "4.1.1", - "jsonc-parser": "3.3.1", - "markdown-it": "14.1.0", - "markdownlint": "0.40.0", - "markdownlint-cli2-formatter-default": "0.0.6", - "micromatch": "4.0.8" - }, - "bin": { - "markdownlint-cli2": "markdownlint-cli2-bin.mjs" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/DavidAnson" - } - }, - "node_modules/markdownlint-cli2-formatter-default": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.6.tgz", - "integrity": "sha512-VVDGKsq9sgzu378swJ0fcHfSicUnMxnL8gnLm/Q4J/xsNJ4e5bA6lvAz7PCzIl0/No0lHyaWdqVD2jotxOSFMQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/DavidAnson" - }, - "peerDependencies": { - "markdownlint-cli2": ">=0.0.4" - } - }, - "node_modules/markdownlint-cli2/node_modules/globby": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-15.0.0.tgz", - "integrity": "sha512-oB4vkQGqlMl682wL1IlWd02tXCbquGWM4voPEI85QmNKCaw8zGTm1f1rubFgkg3Eli2PtKlFgrnmUqasbQWlkw==", - "license": "MIT", - "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "fast-glob": "^3.3.3", - "ignore": "^7.0.5", - "path-type": "^6.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.3.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdownlint-cli2/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/markdownlint-cli2/node_modules/path-type": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", - "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdownlint-cli2/node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdownlint/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/markdownlint/node_modules/string-width": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", - "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdownlint/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -12489,12 +12206,6 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "license": "CC0-1.0" }, - "node_modules/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "license": "MIT" - }, "node_modules/media-chrome": { "version": "4.19.0", "resolved": "https://registry.npmjs.org/media-chrome/-/media-chrome-4.19.0.tgz", @@ -12712,81 +12423,6 @@ ], "license": "MIT" }, - "node_modules/micromark-extension-directive": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", - "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, "node_modules/micromark-extension-frontmatter": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", @@ -13180,81 +12816,6 @@ ], "license": "MIT" }, - "node_modules/micromark-extension-math": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", - "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", - "license": "MIT", - "dependencies": { - "@types/katex": "^0.16.0", - "devlop": "^1.0.0", - "katex": "^0.16.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-math/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-math/node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-math/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, "node_modules/micromark-extension-mdx-expression": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", @@ -16874,15 +16435,6 @@ "node": ">=6" } }, - "node_modules/punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/pupa": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.3.0.tgz", @@ -19327,12 +18879,6 @@ "node": "*" } }, - "node_modules/uc.micro": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "license": "MIT" - }, "node_modules/undici-types": { "version": "7.19.2", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", @@ -19388,18 +18934,6 @@ "node": ">=4" } }, - "node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/unified": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", diff --git a/docs/package.json b/docs/package.json index 2c3cc492..fc8bf31d 100644 --- a/docs/package.json +++ b/docs/package.json @@ -22,7 +22,6 @@ "@iconify/react": "^6.0.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", - "markdownlint-cli2": "^0.20.0", "prism-react-renderer": "^2.3.0", "raw-loader": "^4.0.2", "react": "^18.0.0", diff --git a/pyproject.toml b/pyproject.toml index afcc780c..c4ed5aa8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,6 +84,7 @@ lint = [ "ruff==0.15.12", "astroid>=3.1,<4.0", "ty==0.0.14", + "rumdl==0.2.28", ] types = [ "types-ujson", @@ -518,6 +519,37 @@ directory = "housekeeping" name = "Housekeeping" showcontent = true +[tool.rumdl] +# Markdown linter (https://github.com/rvben/rumdl), replaces markdownlint-cli2. +# The first row mirrors the rules markdownlint had disabled; the second row disables +# rumdl-only rules and rules that false-positive on our MDX/Docusaurus docs +# (fenced blocks nested in , `$(base_url)` template links) that markdownlint +# never enforced. +disable = [ + "MD013", "MD014", "MD024", "MD029", "MD033", "MD034", "MD041", "MD045", "MD047", + "MD046", "MD057", "MD064", "MD069", "MD071", "MD077", +] +exclude = [ + ".venv", + "node_modules", + ".git", + "changelog/*.md", + ".agents/commands", + ".agents/skills", + ".claude/commands", + ".claude/skills", + "dev/commands", + "dev/skills", + ".specify/templates", + ".specify/extensions", +] + +[tool.rumdl.MD025] +front_matter_title = "" + +[tool.rumdl.MD059] +prohibited_texts = [] + [build-system] requires = ["hatchling"] build-backend = "hatchling.build" diff --git a/tasks.py b/tasks.py index 048789a6..9ad626f1 100644 --- a/tasks.py +++ b/tasks.py @@ -44,6 +44,11 @@ def require_tool(name: str, install_hint: str) -> None: raise Exit(f" - {name} is not installed. {install_hint}", code=1) +def _rumdl_fix(context: Context, path: Path) -> None: + """Auto-fix rumdl violations in the generated markdown under *path*.""" + context.run(f'rumdl check --fix "{path}"', pty=True) + + @task(name="docs-generate") def docs_generate(context: Context) -> None: """Generate all documentation (infrahubctl CLI + Python SDK).""" @@ -266,8 +271,7 @@ def _generate_sdk_api_docs(context: Context) -> None: target_path = output_dir / reduce(operator.truediv, (Path(part) for part in file_key.split("-"))) MDXDocPage(page=page, output_path=target_path).to_mdx() - with context.cd(DOCUMENTATION_DIRECTORY): - context.run(f"npx --no-install markdownlint-cli2 {output_dir}/ --fix --config .markdownlint.yaml", pty=True) + _rumdl_fix(context, output_dir) @task @@ -316,11 +320,11 @@ def lint_ruff(context: Context) -> None: @task -def lint_markdownlint(context: Context) -> None: - """Run markdownlint to check all markdown files.""" - print(" - Check documentation with markdownlint-cli2") - exec_cmd = "npx --no-install markdownlint-cli2 **/*.{md,mdx} !node_modules/** --config .markdownlint.yaml" - with context.cd(DOCUMENTATION_DIRECTORY): +def lint_rumdl(context: Context) -> None: + """Run rumdl to check all markdown files.""" + print(" - Check documentation with rumdl") + exec_cmd = "rumdl check ." + with context.cd(MAIN_DIRECTORY_PATH): context.run(exec_cmd) @@ -346,7 +350,7 @@ def lint_code(context: Context) -> None: @task def lint_docs(context: Context) -> None: """Run all documentation linters.""" - lint_markdownlint(context) + lint_rumdl(context) lint_vale(context) @@ -407,6 +411,7 @@ def generate_python_sdk(context: Context) -> None: _generate_infrahub_sdk_configuration_documentation() _generate_infrahub_sdk_template_documentation() _generate_infrahub_sdk_compatibility_documentation() + _rumdl_fix(context, DOCUMENTATION_DIRECTORY / "docs" / "python-sdk" / "reference") _generate_sdk_api_docs(context) diff --git a/uv.lock b/uv.lock index 60d05ab5..4cf1c1ca 100644 --- a/uv.lock +++ b/uv.lock @@ -734,6 +734,7 @@ dev = [ { name = "pytest-xdist" }, { name = "requests" }, { name = "ruff" }, + { name = "rumdl" }, { name = "towncrier" }, { name = "ty" }, { name = "types-python-slugify" }, @@ -745,6 +746,7 @@ lint = [ { name = "astroid" }, { name = "mypy" }, { name = "ruff" }, + { name = "rumdl" }, { name = "ty" }, { name = "yamllint" }, ] @@ -814,6 +816,7 @@ dev = [ { name = "pytest-xdist", specifier = ">=3.3.1" }, { name = "requests", specifier = ">=2.33.0" }, { name = "ruff", specifier = "==0.15.12" }, + { name = "rumdl", specifier = "==0.2.28" }, { name = "towncrier", specifier = ">=24.8.0" }, { name = "ty", specifier = "==0.0.14" }, { name = "types-python-slugify", specifier = ">=8.0.0.3" }, @@ -825,6 +828,7 @@ lint = [ { name = "astroid", specifier = ">=3.1,<4.0" }, { name = "mypy", specifier = "==1.11.2" }, { name = "ruff", specifier = "==0.15.12" }, + { name = "rumdl", specifier = "==0.2.28" }, { name = "ty", specifier = "==0.0.14" }, { name = "yamllint" }, ] @@ -886,17 +890,17 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "decorator", marker = "python_full_version < '3.11'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "jedi", marker = "python_full_version < '3.11'" }, - { name = "matplotlib-inline", marker = "python_full_version < '3.11'" }, - { name = "pexpect", marker = "python_full_version < '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit", marker = "python_full_version < '3.11'" }, - { name = "pygments", marker = "python_full_version < '3.11'" }, - { name = "stack-data", marker = "python_full_version < '3.11'" }, - { name = "traitlets", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "exceptiongroup" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/85/31/10ac88f3357fc276dc8a64e8880c82e80e7459326ae1d0a211b40abf6665/ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216", size = 5606088, upload-time = "2025-05-31T16:39:09.613Z" } wheels = [ @@ -913,17 +917,17 @@ resolution-markers = [ "python_full_version == '3.11.*'", ] dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, - { name = "decorator", marker = "python_full_version >= '3.11'" }, - { name = "ipython-pygments-lexers", marker = "python_full_version >= '3.11'" }, - { name = "jedi", marker = "python_full_version >= '3.11'" }, - { name = "matplotlib-inline", marker = "python_full_version >= '3.11'" }, - { name = "pexpect", marker = "python_full_version >= '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit", marker = "python_full_version >= '3.11'" }, - { name = "pygments", marker = "python_full_version >= '3.11'" }, - { name = "stack-data", marker = "python_full_version >= '3.11'" }, - { name = "traitlets", marker = "python_full_version >= '3.11'" }, - { name = "typing-extensions", marker = "python_full_version == '3.11.*'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2a/34/29b18c62e39ee2f7a6a3bba7efd952729d8aadd45ca17efc34453b717665/ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731", size = 4396932, upload-time = "2025-09-29T10:55:53.948Z" } wheels = [ @@ -935,7 +939,7 @@ name = "ipython-pygments-lexers" version = "1.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pygments", marker = "python_full_version >= '3.11'" }, + { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } wheels = [ @@ -1468,8 +1472,8 @@ name = "pendulum" version = "3.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "python-dateutil", marker = "python_full_version < '3.13'" }, - { name = "tzdata", marker = "python_full_version < '3.13'" }, + { name = "python-dateutil" }, + { name = "tzdata" }, ] sdist = { url = "https://files.pythonhosted.org/packages/23/7c/009c12b86c7cc6c403aec80f8a4308598dfc5995e5c523a5491faaa3952e/pendulum-3.1.0.tar.gz", hash = "sha256:66f96303560f41d097bee7d2dc98ffca716fbb3a832c4b3062034c2d45865015", size = 85930, upload-time = "2025-04-19T14:30:01.675Z" } wheels = [ @@ -2502,6 +2506,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c0/98/6beb4b351e472e5f4c4613f7c35a5290b8be2497e183825310c4c3a3984b/ruff-0.15.12-py3-none-win_arm64.whl", hash = "sha256:a538f7a82d061cee7be55542aca1d86d1393d55d81d4fcc314370f4340930d4f", size = 11120821, upload-time = "2026-04-24T18:16:57.979Z" }, ] +[[package]] +name = "rumdl" +version = "0.2.28" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/40/da219dd6f19eaeb4e620c0b2c942adc0d743aed6186e37d35ba1ab4d0a6a/rumdl-0.2.28.tar.gz", hash = "sha256:ff7e4b9ffaa617495a9fed775323e557d7719208ba2596b778864c0d31c132e9", size = 2834931, upload-time = "2026-07-03T09:21:25.54Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/1a/13ad9ef84cf0407b5685d6c297d44df45d3fa68a7289291451d960df5401/rumdl-0.2.28-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1c5580ef900acee7b112655c569355af5914e7e26248612c2a0df7f877cf1928", size = 6032238, upload-time = "2026-07-03T09:21:13.156Z" }, + { url = "https://files.pythonhosted.org/packages/60/97/f7cfffd9515a5bdf2273a92662183ab172c7fd5149c4296b089ce7f3b7dd/rumdl-0.2.28-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9e38e5e48db8b38935cfd2ba986aa8deb7bdf784de4228629f581849e11a8b76", size = 5698394, upload-time = "2026-07-03T09:21:15.238Z" }, + { url = "https://files.pythonhosted.org/packages/43/46/18111e2471c767d69b7874a643b7dbec5978fd03b65394e122a9990c8015/rumdl-0.2.28-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:8299462c03d498b90014fb03983d9aa8cdd2d2a5ff64f8a27231e8ffe00cdbb9", size = 5836882, upload-time = "2026-07-03T09:21:16.907Z" }, + { url = "https://files.pythonhosted.org/packages/65/e5/0cd0fd9c530c53192e4fd12c33717b6c4f1c7f9ac28f2443869e101719b3/rumdl-0.2.28-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:2a0f14e56ce50583d600404ff80aac7c98e11862103dcbfcb5aee5225184b702", size = 6205179, upload-time = "2026-07-03T09:21:18.986Z" }, + { url = "https://files.pythonhosted.org/packages/d3/d5/06a52f22d768296cf3deef12dde93c1b22a9177a3adff7944f7602b47c22/rumdl-0.2.28-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4d518eaec6972d1651b71e48d7a2d9dd5e2ec73acbd29e3e51343d0cd6c65b10", size = 5828991, upload-time = "2026-07-03T09:21:20.657Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ff/d35ce3e759b7696fe07d3dbdc05de8494f5f0ad202d9e44595de8024df01/rumdl-0.2.28-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b8d2249d7951e46b455e8812f30b7ec453c24c37afa34ff5def541756113d652", size = 6191050, upload-time = "2026-07-03T09:21:22.331Z" }, + { url = "https://files.pythonhosted.org/packages/94/6d/2d233563f17e28da273200fd9532d4ed706294ae4287e0a52b424eef71a2/rumdl-0.2.28-py3-none-win_amd64.whl", hash = "sha256:e96ba5e683e2b1dc39037879770930d28d0cbc5e3d13fdd872abb327cd5a68f5", size = 6126533, upload-time = "2026-07-03T09:21:23.942Z" }, +] + [[package]] name = "shellingham" version = "1.5.4" From beda13af890e1753277a409a56fa278448817b9a Mon Sep 17 00:00:00 2001 From: Damien Garros Date: Tue, 7 Jul 2026 11:44:53 +0000 Subject: [PATCH 2/2] chore(ci): make markdown lint task tool-agnostic and drop stale exclude Rename the `lint_rumdl` invoke task to `lint_markdown` so it no longer names the underlying tool, and remove the `dev/commands` rumdl exclude since that directory no longer exists. Co-Authored-By: Claude Opus 4.8 --- pyproject.toml | 1 - tasks.py | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c4ed5aa8..0c9a343a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -538,7 +538,6 @@ exclude = [ ".agents/skills", ".claude/commands", ".claude/skills", - "dev/commands", "dev/skills", ".specify/templates", ".specify/extensions", diff --git a/tasks.py b/tasks.py index 9ad626f1..69bf7986 100644 --- a/tasks.py +++ b/tasks.py @@ -320,8 +320,8 @@ def lint_ruff(context: Context) -> None: @task -def lint_rumdl(context: Context) -> None: - """Run rumdl to check all markdown files.""" +def lint_markdown(context: Context) -> None: + """Run the markdown linter to check all markdown files.""" print(" - Check documentation with rumdl") exec_cmd = "rumdl check ." with context.cd(MAIN_DIRECTORY_PATH): @@ -350,7 +350,7 @@ def lint_code(context: Context) -> None: @task def lint_docs(context: Context) -> None: """Run all documentation linters.""" - lint_rumdl(context) + lint_markdown(context) lint_vale(context)