cpdocs 0.3.7__tar.gz → 0.3.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cpdocs-0.3.9/.github/workflows/docs-tag-rebuild.yml +59 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/PKG-INFO +52 -3
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/cpdocs.yml +1 -1
- {cpdocs-0.3.7 → cpdocs-0.3.9}/pyproject.toml +1 -3
- cpdocs-0.3.9/readme.md +86 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/__init__.py +1 -1
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/build.py +108 -61
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/config.py +24 -1
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/providers/contract.py +39 -5
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/rendering/html.py +37 -7
- cpdocs-0.3.9/test/test_language_configurations.py +128 -0
- cpdocs-0.3.9/test/test_tagged_docs_ci.py +76 -0
- cpdocs-0.3.9/uv.lock +835 -0
- cpdocs-0.3.7/readme.md +0 -36
- cpdocs-0.3.7/uv.lock +0 -776
- {cpdocs-0.3.7 → cpdocs-0.3.9}/.github/workflows/docs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/.github/workflows/test.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/.gitignore +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/.reuse/templates/bordered.jinja2 +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/LICENSES/Apache-2.0.txt +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/REUSE.toml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/api/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/examples/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/explanation/architecture.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/explanation/feature-sets.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/how-to/ci.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/how-to/feature-sets.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/how-to/generated-headers.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/how-to/other-build-systems.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/how-to/properdocs.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/reference/api.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/reference/cli.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/reference/cmake.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/reference/comments.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/reference/configuration.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/reference/contract.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/reference/extraction.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/reference/links.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/docs/web/tutorials/first-reference.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/basic-cpp/.gitignore +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/basic-cpp/CMakeLists.txt +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/basic-cpp/docs/api/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/basic-cpp/docs/cpdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/basic-cpp/docs/web/api.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/basic-cpp/docs/web/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/basic-cpp/include/acme/math.hpp +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/basic-cpp/properdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/basic-cpp/readme.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/basic-cpp/src/math.cpp +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/c-basic/.gitignore +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/c-basic/CMakeLists.txt +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/c-basic/docs/api/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/c-basic/docs/cpdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/c-basic/docs/web/api.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/c-basic/docs/web/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/c-basic/include/ring/ring.h +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/c-basic/properdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/c-basic/readme.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/c-basic/src/ring.c +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/.gitignore +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/CMakeLists.txt +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/docs/api/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/docs/cpdocs-minibuild.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/docs/cpdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/docs/web/api.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/docs/web/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/include/demo/solver.hpp +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/properdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/readme.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-features/tools/minibuild.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-templates/.gitignore +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-templates/CMakeLists.txt +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-templates/docs/api/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-templates/docs/cpdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-templates/docs/web/api.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-templates/docs/web/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-templates/include/meta/meta.hpp +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-templates/properdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/cpp-templates/readme.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/fortran-basic/CMakeLists.txt +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/fortran-basic/docs/api.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/fortran-basic/docs/cpdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/fortran-basic/docs/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/fortran-basic/lib/normalize.f90 +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/fortran-basic/mod/geometry.f90 +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/fortran-basic/properdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/fortran-basic/readme.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/.gitignore +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/CMakeLists.txt +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/docs/api/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/docs/cpdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/docs/web/api.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/docs/web/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/generated-template/generated.hpp +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/include/acme/core.hpp +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/properdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/readme.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/generated-cpp/src/generated.cpp +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/.gitignore +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/CMakeLists.txt +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/docs/api/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/docs/cpdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/docs/web/api.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/docs/web/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/include/geom/vector.hpp +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/properdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/python/pygeom/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/readme.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/mixed/src/geom.cpp +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/.gitignore +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/docs/api/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/docs/cpdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/docs/web/api.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/docs/web/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/properdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/pyproject.toml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/readme.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/src/dice/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/src/dice/_rng.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/python-basic/src/dice/core.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/Cargo.lock +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/Cargo.toml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/docs/api.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/docs/cpdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/docs/index.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/properdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/readme.md +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/rust-toolchain.toml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/src/geometry.rs +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/src/internal.rs +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/examples/rust-basic/src/lib.rs +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/properdocs.yml +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/__main__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/cli.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/contract.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/base.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/cpp/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/cpp/extract.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/cpp/render.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/fortran/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/fortran/extract.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/fortran/render.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/python/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/python/extract.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/python/render.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/rust/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/rust/extract.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/languages/rust/render.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/model.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/plugins/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/plugins/properdocs/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/plugins/properdocs/core.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/plugins/properdocs/plugin.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/providers/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/providers/cargo.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/providers/cmake.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/providers/python.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/rendering/__init__.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/rendering/common.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/src/cpdocs/versioning.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/conftest.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/test_api_reference.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/test_build.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/test_config.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/test_contract.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/test_examples.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/test_feature_set_signatures.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/test_properdocs_core.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/test_rust_example.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/test_rust_provider.py +0 -0
- {cpdocs-0.3.7 → cpdocs-0.3.9}/test/test_versioning.py +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# --------------------------------------------------------------------------------------------------
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# SPDX-FileCopyrightText: 2026 cpdocs developers
|
|
4
|
+
# --------------------------------------------------------------------------------------------------
|
|
5
|
+
name: historical tag documentation rebuild
|
|
6
|
+
|
|
7
|
+
# GitHub loads push workflows from the pushed tag. Older tags carry the original
|
|
8
|
+
# documentation workflow, which attempts to run the old cpdocs implementation
|
|
9
|
+
# against the current branch. This workflow lives on the default branch and is
|
|
10
|
+
# triggered when an old documentation run completes, even if that run failed.
|
|
11
|
+
on:
|
|
12
|
+
workflow_run:
|
|
13
|
+
workflows: [documentation]
|
|
14
|
+
types: [completed]
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
rebuild:
|
|
21
|
+
if: github.event.workflow_run.event == 'push'
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
permissions:
|
|
24
|
+
contents: read
|
|
25
|
+
actions: write
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
with:
|
|
29
|
+
ref: ${{ github.event.repository.default_branch }}
|
|
30
|
+
fetch-depth: 0
|
|
31
|
+
|
|
32
|
+
- name: Detect legacy tag workflow
|
|
33
|
+
id: legacy
|
|
34
|
+
env:
|
|
35
|
+
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
36
|
+
run: |
|
|
37
|
+
# A branch push (or a PR) must not trigger another docs build.
|
|
38
|
+
if ! git tag --points-at "$HEAD_SHA" | grep -q .; then
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# Current tagged workflows already dispatch a default-branch build.
|
|
43
|
+
# Avoid dispatching a duplicate for those tags.
|
|
44
|
+
if git show "$HEAD_SHA:.github/workflows/docs.yml" 2>/dev/null \
|
|
45
|
+
| grep -q 'rebuild-for-tag:'; then
|
|
46
|
+
exit 0
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
echo 'rebuild=true' >> "$GITHUB_OUTPUT"
|
|
50
|
+
|
|
51
|
+
- name: Build tagged API from the current documentation tool
|
|
52
|
+
if: steps.legacy.outputs.rebuild == 'true'
|
|
53
|
+
env:
|
|
54
|
+
GH_TOKEN: ${{ github.token }}
|
|
55
|
+
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
|
|
56
|
+
run: |
|
|
57
|
+
gh workflow run docs.yml \
|
|
58
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
59
|
+
--ref "$DEFAULT_BRANCH"
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: cpdocs
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.9
|
|
4
4
|
Summary: Semantic, versioned API documentation for C, C++, CUDA, HIP, Fortran, Python and Rust projects
|
|
5
5
|
Project-URL: Source, https://github.com/ambhora/cpdocs
|
|
6
6
|
Author-email: Jayesh Badwaik <j.badwaik@fz-juelich.de>
|
|
7
7
|
License-Expression: Apache-2.0
|
|
8
8
|
Requires-Python: >=3.11
|
|
9
|
+
Requires-Dist: keyso
|
|
9
10
|
Requires-Dist: markdown-it-py>=3
|
|
10
11
|
Requires-Dist: pygments>=2.17
|
|
11
12
|
Requires-Dist: pyyaml>=6
|
|
12
|
-
Provides-Extra: properdocs
|
|
13
|
-
Requires-Dist: properdocs>=1.6.7; extra == 'properdocs'
|
|
14
13
|
Description-Content-Type: text/markdown
|
|
15
14
|
|
|
16
15
|
<!--
|
|
@@ -35,6 +34,56 @@ cpdocs versions # document the configured versions
|
|
|
35
34
|
properdocs build # project website with the versioned API mounted
|
|
36
35
|
```
|
|
37
36
|
|
|
37
|
+
## Language configurations
|
|
38
|
+
|
|
39
|
+
The optional `languages` field in `docs/cpdocs.yml` is a [Keyso configuration
|
|
40
|
+
space](https://ambhora.github.io/keyso/language/syntax/). cpdocs expands it using pykeyso,
|
|
41
|
+
then runs `build.feature-sets` once per concrete configuration and `build.build` once per
|
|
42
|
+
feature set discovered for that configuration. Both command templates receive dotted placeholders
|
|
43
|
+
from the resulting nested dictionaries, such as `{{cxx.standard}}`, `{{c.standard}}`,
|
|
44
|
+
`{{fortran.standard}}`, `{{python.version}}`, or `{{rust.edition}}`. The build system decides
|
|
45
|
+
how to apply each value; cpdocs does not translate them into compiler flags.
|
|
46
|
+
|
|
47
|
+
```yaml
|
|
48
|
+
languages:
|
|
49
|
+
_product:
|
|
50
|
+
- cxx:
|
|
51
|
+
_nested:
|
|
52
|
+
standard: [17, 20, 23]
|
|
53
|
+
- python:
|
|
54
|
+
_nested:
|
|
55
|
+
version: ["3.11", "3.12"]
|
|
56
|
+
|
|
57
|
+
build:
|
|
58
|
+
feature-sets: >-
|
|
59
|
+
cmake -S "{{source}}" -B "{{tmpdir}}"
|
|
60
|
+
-DCMAKE_CXX_STANDARD="{{cxx.standard}}"
|
|
61
|
+
-DPROJECT_FEATURE_SETS_OUTPUT="{{output-file}}"
|
|
62
|
+
build: >-
|
|
63
|
+
cmake -S "{{source}}" -B "{{tmpdir}}"
|
|
64
|
+
-DCMAKE_CXX_STANDARD="{{cxx.standard}}"
|
|
65
|
+
-DPROJECT_FEATURE_SET="{{feature-set}}"
|
|
66
|
+
-DPROJECT_CPDOCS_OUTPUT="{{output-file}}"
|
|
67
|
+
&& cmake --build "{{tmpdir}}" --target project.cpdocs
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Use `_set` for explicitly paired combinations rather than the `_product` Cartesian product:
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
languages:
|
|
74
|
+
_set:
|
|
75
|
+
- cxx: {standard: 17}
|
|
76
|
+
python: {version: "3.11"}
|
|
77
|
+
- cxx: {standard: 23}
|
|
78
|
+
python: {version: "3.12"}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Each concrete configuration has its own work directory. The merged API records both the
|
|
82
|
+
language configuration and feature set in symbol availability, including overload signatures.
|
|
83
|
+
If `languages` is omitted, cpdocs performs the original single build configuration, and the
|
|
84
|
+
existing `{{source}}`, `{{tmpdir}}`, `{{output-file}}`, `{{feature-set}}`, and `{{python}}`
|
|
85
|
+
placeholders continue to work unchanged.
|
|
86
|
+
|
|
38
87
|
The configuration lives in `docs/cpdocs.yml`, the API introduction in `docs/api/index.md` and the
|
|
39
88
|
ProperDocs pages in `docs/web`. The documentation starts at `docs/web/index.md`; the `examples/`
|
|
40
89
|
directory holds standalone projects that the test suite builds.
|
|
@@ -13,7 +13,7 @@ build:
|
|
|
13
13
|
--source "{{source}}" --feature-set "{{feature-set}}" --output "{{output-file}}"
|
|
14
14
|
--package cpdocs --package-source src/cpdocs
|
|
15
15
|
|
|
16
|
-
versions: [main]
|
|
16
|
+
versions: [main, 0.3.7, 0.0.1]
|
|
17
17
|
|
|
18
18
|
site:
|
|
19
19
|
copyright: Copyright © cpdocs developers · Apache-2.0
|
cpdocs-0.3.9/readme.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 cpdocs developers
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
-->
|
|
5
|
+
# cpdocs
|
|
6
|
+
|
|
7
|
+
cpdocs generates semantic, versioned API documentation for C, C++, CUDA, HIP, Fortran, Python and Rust projects.
|
|
8
|
+
|
|
9
|
+
It asks the project's build system, through a small JSON contract, for the concrete feature sets to
|
|
10
|
+
document. It builds each feature set independently, consumes the resulting manifest, extracts the API
|
|
11
|
+
with Clang for C-family languages, source modules for Fortran, `ast` for Python or rustdoc JSON for
|
|
12
|
+
Rust, and merges the results. Implementation files from the manifest are kept in the file hierarchy
|
|
13
|
+
without becoming API entities.
|
|
14
|
+
Feature-set availability and API language are tracked independently. The versions
|
|
15
|
+
to publish are an explicit ordered list in `cpdocs.yml`.
|
|
16
|
+
|
|
17
|
+
```console
|
|
18
|
+
cpdocs build # document the working tree into build/cpdocs/current
|
|
19
|
+
cpdocs versions # document the configured versions
|
|
20
|
+
properdocs build # project website with the versioned API mounted
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Language configurations
|
|
24
|
+
|
|
25
|
+
The optional `languages` field in `docs/cpdocs.yml` is a [Keyso configuration
|
|
26
|
+
space](https://ambhora.github.io/keyso/language/syntax/). cpdocs expands it using pykeyso,
|
|
27
|
+
then runs `build.feature-sets` once per concrete configuration and `build.build` once per
|
|
28
|
+
feature set discovered for that configuration. Both command templates receive dotted placeholders
|
|
29
|
+
from the resulting nested dictionaries, such as `{{cxx.standard}}`, `{{c.standard}}`,
|
|
30
|
+
`{{fortran.standard}}`, `{{python.version}}`, or `{{rust.edition}}`. The build system decides
|
|
31
|
+
how to apply each value; cpdocs does not translate them into compiler flags.
|
|
32
|
+
|
|
33
|
+
```yaml
|
|
34
|
+
languages:
|
|
35
|
+
_product:
|
|
36
|
+
- cxx:
|
|
37
|
+
_nested:
|
|
38
|
+
standard: [17, 20, 23]
|
|
39
|
+
- python:
|
|
40
|
+
_nested:
|
|
41
|
+
version: ["3.11", "3.12"]
|
|
42
|
+
|
|
43
|
+
build:
|
|
44
|
+
feature-sets: >-
|
|
45
|
+
cmake -S "{{source}}" -B "{{tmpdir}}"
|
|
46
|
+
-DCMAKE_CXX_STANDARD="{{cxx.standard}}"
|
|
47
|
+
-DPROJECT_FEATURE_SETS_OUTPUT="{{output-file}}"
|
|
48
|
+
build: >-
|
|
49
|
+
cmake -S "{{source}}" -B "{{tmpdir}}"
|
|
50
|
+
-DCMAKE_CXX_STANDARD="{{cxx.standard}}"
|
|
51
|
+
-DPROJECT_FEATURE_SET="{{feature-set}}"
|
|
52
|
+
-DPROJECT_CPDOCS_OUTPUT="{{output-file}}"
|
|
53
|
+
&& cmake --build "{{tmpdir}}" --target project.cpdocs
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Use `_set` for explicitly paired combinations rather than the `_product` Cartesian product:
|
|
57
|
+
|
|
58
|
+
```yaml
|
|
59
|
+
languages:
|
|
60
|
+
_set:
|
|
61
|
+
- cxx: {standard: 17}
|
|
62
|
+
python: {version: "3.11"}
|
|
63
|
+
- cxx: {standard: 23}
|
|
64
|
+
python: {version: "3.12"}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Each concrete configuration has its own work directory. The merged API records both the
|
|
68
|
+
language configuration and feature set in symbol availability, including overload signatures.
|
|
69
|
+
If `languages` is omitted, cpdocs performs the original single build configuration, and the
|
|
70
|
+
existing `{{source}}`, `{{tmpdir}}`, `{{output-file}}`, `{{feature-set}}`, and `{{python}}`
|
|
71
|
+
placeholders continue to work unchanged.
|
|
72
|
+
|
|
73
|
+
The configuration lives in `docs/cpdocs.yml`, the API introduction in `docs/api/index.md` and the
|
|
74
|
+
ProperDocs pages in `docs/web`. The documentation starts at `docs/web/index.md`; the `examples/`
|
|
75
|
+
directory holds standalone projects that the test suite builds.
|
|
76
|
+
|
|
77
|
+
## Development
|
|
78
|
+
|
|
79
|
+
```console
|
|
80
|
+
uv sync
|
|
81
|
+
uv run pytest
|
|
82
|
+
uv run ruff check && uv run ruff format --check
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The C and C++ tests need `clang++`, `cmake` and `ninja`. Building the Rust example/site also needs
|
|
86
|
+
the nightly toolchain pinned by `examples/rust-basic/rust-toolchain.toml`.
|
|
@@ -31,7 +31,11 @@ from .languages.fortran.extract import extract_fortran_graph
|
|
|
31
31
|
from .languages.python.extract import build_python_graph
|
|
32
32
|
from .languages.rust.extract import build_rust_graph
|
|
33
33
|
from .model import ApiGraph, merge_graphs, relative_source_path
|
|
34
|
-
from .providers.contract import
|
|
34
|
+
from .providers.contract import (
|
|
35
|
+
discover_feature_sets,
|
|
36
|
+
language_template_values,
|
|
37
|
+
resolve_manifest,
|
|
38
|
+
)
|
|
35
39
|
from .rendering.html import render_html_site
|
|
36
40
|
from .versioning import SelectedRef, current_branch, select_refs
|
|
37
41
|
|
|
@@ -348,72 +352,114 @@ def build_graph(
|
|
|
348
352
|
work: Path,
|
|
349
353
|
version: str,
|
|
350
354
|
) -> ApiGraph:
|
|
351
|
-
"""
|
|
352
|
-
|
|
353
|
-
feature_sets = discover_feature_sets(config.feature_sets, source=source, work=work)
|
|
355
|
+
"""Build every allowed language configuration and its discovered feature sets."""
|
|
354
356
|
|
|
355
357
|
per_feature_set: list[tuple[str, ApiGraph]] = []
|
|
356
358
|
metadata: dict[str, object] = {}
|
|
357
359
|
languages: set[str] = set()
|
|
358
360
|
units: dict[tuple[str, str], None] = {}
|
|
359
361
|
configuration_options: dict[str, list[dict[str, object]]] = {}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
362
|
+
all_feature_selections: list[dict[str, object]] = []
|
|
363
|
+
project: str | None = None
|
|
364
|
+
project_version = ""
|
|
365
|
+
generator = ""
|
|
366
|
+
multiple_languages = len(config.language_configurations) > 1
|
|
367
|
+
|
|
368
|
+
for index, configuration in enumerate(config.language_configurations, 1):
|
|
369
|
+
template_values = language_template_values(configuration)
|
|
370
|
+
# Preserve the existing work directory layout for projects with a single configuration.
|
|
371
|
+
language_work = (
|
|
372
|
+
work / "language-configurations" / f"language-{index:03d}"
|
|
373
|
+
if multiple_languages
|
|
374
|
+
else work
|
|
370
375
|
)
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
work=work / "feature-sets" / feature_set.key,
|
|
386
|
-
config=config,
|
|
376
|
+
feature_sets = discover_feature_sets(
|
|
377
|
+
config.feature_sets,
|
|
378
|
+
source=source,
|
|
379
|
+
work=language_work,
|
|
380
|
+
template_values=template_values,
|
|
381
|
+
)
|
|
382
|
+
if project is None:
|
|
383
|
+
project = feature_sets.project
|
|
384
|
+
project_version = feature_sets.version
|
|
385
|
+
generator = feature_sets.generator
|
|
386
|
+
elif project != feature_sets.project:
|
|
387
|
+
raise RuntimeError(
|
|
388
|
+
f"build.feature-sets returned inconsistent projects: "
|
|
389
|
+
f"{project!r} and {feature_sets.project!r}"
|
|
387
390
|
)
|
|
388
|
-
display_paths = unit_graph.metadata.setdefault("source_display_paths", {})
|
|
389
|
-
assert isinstance(display_paths, dict)
|
|
390
|
-
for path, display in _api_display_paths(unit, unit_graph, project_root=source).items():
|
|
391
|
-
display_paths.setdefault(path, display)
|
|
392
391
|
|
|
393
|
-
|
|
394
|
-
|
|
392
|
+
for feature_set in feature_sets.feature_sets:
|
|
393
|
+
key = (
|
|
394
|
+
f"language-{index:03d}--{feature_set.key}"
|
|
395
|
+
if multiple_languages
|
|
396
|
+
else feature_set.key
|
|
395
397
|
)
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
398
|
+
manifest = resolve_manifest(
|
|
399
|
+
config.build,
|
|
400
|
+
feature_set,
|
|
401
|
+
source=source,
|
|
402
|
+
work=language_work,
|
|
403
|
+
template_values=template_values,
|
|
404
|
+
)
|
|
405
|
+
if manifest.options:
|
|
406
|
+
configuration_options[key] = [dict(option) for option in manifest.options]
|
|
407
|
+
languages.update(unit.language for unit in manifest.units if unit.language is not None)
|
|
408
|
+
for unit in manifest.units:
|
|
409
|
+
units[(unit.id, unit.language)] = None
|
|
410
|
+
feature_set_language_values = sorted(
|
|
411
|
+
{unit.language for unit in manifest.units if unit.language is not None}
|
|
412
|
+
)
|
|
413
|
+
if len(feature_set_language_values) == 1:
|
|
414
|
+
feature_set_language = feature_set_language_values[0]
|
|
415
|
+
elif feature_set_language_values:
|
|
416
|
+
feature_set_language = "mixed"
|
|
417
|
+
else:
|
|
418
|
+
feature_set_language = "none"
|
|
419
|
+
unit_graphs = []
|
|
420
|
+
for unit in manifest.units:
|
|
421
|
+
unit_graph = extract_unit(
|
|
422
|
+
unit,
|
|
423
|
+
project=feature_sets.project,
|
|
424
|
+
version=version,
|
|
425
|
+
project_root=source,
|
|
426
|
+
feature_set=key,
|
|
427
|
+
work=language_work / "feature-sets" / feature_set.key,
|
|
428
|
+
config=config,
|
|
429
|
+
)
|
|
430
|
+
display_paths = unit_graph.metadata.setdefault("source_display_paths", {})
|
|
431
|
+
assert isinstance(display_paths, dict)
|
|
432
|
+
for path, display in _api_display_paths(
|
|
433
|
+
unit, unit_graph, project_root=source
|
|
434
|
+
).items():
|
|
435
|
+
display_paths.setdefault(path, display)
|
|
436
|
+
|
|
437
|
+
browse_files, generated_files, browse_display_paths = _collect_browse_files(
|
|
438
|
+
unit, project_root=source
|
|
439
|
+
)
|
|
440
|
+
for path, content in browse_files.items():
|
|
441
|
+
unit_graph.files.setdefault(path, content)
|
|
442
|
+
for path, display in browse_display_paths.items():
|
|
443
|
+
display_paths.setdefault(path, display)
|
|
444
|
+
if generated_files:
|
|
445
|
+
existing = unit_graph.metadata.setdefault("generated_files", [])
|
|
446
|
+
assert isinstance(existing, list)
|
|
447
|
+
existing.extend(path for path in generated_files if path not in existing)
|
|
448
|
+
unit_graphs.append(unit_graph)
|
|
449
|
+
graph = _combine(
|
|
450
|
+
unit_graphs,
|
|
451
|
+
project=feature_sets.project,
|
|
452
|
+
version=version,
|
|
453
|
+
language=feature_set_language,
|
|
454
|
+
)
|
|
455
|
+
graph.feature_sets[key] = {
|
|
456
|
+
"features": list(feature_set.features),
|
|
457
|
+
"selection": feature_set.selection,
|
|
458
|
+
"languages": configuration,
|
|
459
|
+
}
|
|
460
|
+
_merge_metadata(metadata, graph.metadata)
|
|
461
|
+
per_feature_set.append((key, graph))
|
|
462
|
+
all_feature_selections.append(feature_set.selection)
|
|
417
463
|
|
|
418
464
|
language_values = sorted(languages)
|
|
419
465
|
if len(language_values) == 1:
|
|
@@ -423,17 +469,18 @@ def build_graph(
|
|
|
423
469
|
else:
|
|
424
470
|
language = "none"
|
|
425
471
|
merged = merge_graphs(
|
|
426
|
-
per_feature_set, project=
|
|
472
|
+
per_feature_set, project=project or "", version=version, language=language
|
|
427
473
|
)
|
|
428
|
-
metadata["feature_sets"] =
|
|
474
|
+
metadata["feature_sets"] = all_feature_selections
|
|
475
|
+
metadata["language_configurations"] = list(config.language_configurations)
|
|
429
476
|
sorted_units = sorted(units, key=lambda value: (value[0], value[1] or ""))
|
|
430
477
|
metadata["units"] = [
|
|
431
478
|
{"id": unit_id, "language": unit_language} for unit_id, unit_language in sorted_units
|
|
432
479
|
]
|
|
433
480
|
if configuration_options:
|
|
434
481
|
metadata["configuration_options"] = configuration_options
|
|
435
|
-
metadata["generator"] =
|
|
436
|
-
metadata["project_version"] =
|
|
482
|
+
metadata["generator"] = generator
|
|
483
|
+
metadata["project_version"] = project_version
|
|
437
484
|
merged.metadata = metadata
|
|
438
485
|
|
|
439
486
|
_apply_visibility(merged, config)
|
|
@@ -28,6 +28,7 @@ class CpdocsConfig:
|
|
|
28
28
|
project_root: Path
|
|
29
29
|
feature_sets: str
|
|
30
30
|
build: str
|
|
31
|
+
language_configurations: tuple[dict[str, Any], ...]
|
|
31
32
|
versions: tuple[str, ...]
|
|
32
33
|
index: Path | None
|
|
33
34
|
copyright: str | None
|
|
@@ -86,6 +87,27 @@ def _command(value: object, name: str) -> str:
|
|
|
86
87
|
return value.strip()
|
|
87
88
|
|
|
88
89
|
|
|
90
|
+
def _language_configurations(raw: dict[str, Any]) -> tuple[dict[str, Any], ...]:
|
|
91
|
+
"""Expand the optional Keyso language space, preserving the original default build."""
|
|
92
|
+
|
|
93
|
+
if "languages" not in raw:
|
|
94
|
+
return ({},)
|
|
95
|
+
expression = _mapping(raw["languages"], "languages")
|
|
96
|
+
try:
|
|
97
|
+
import keyso
|
|
98
|
+
except ImportError as error:
|
|
99
|
+
raise RuntimeError("cpdocs.yml: languages requires the keyso package") from error
|
|
100
|
+
try:
|
|
101
|
+
configurations = keyso.expand(expression)
|
|
102
|
+
except Exception as error:
|
|
103
|
+
raise RuntimeError(f"cpdocs.yml: invalid languages Keyso space: {error}") from error
|
|
104
|
+
if not configurations:
|
|
105
|
+
raise RuntimeError("cpdocs.yml: languages must expand to at least one configuration")
|
|
106
|
+
if not all(isinstance(configuration, dict) for configuration in configurations):
|
|
107
|
+
raise RuntimeError("cpdocs.yml: languages must expand to dictionaries")
|
|
108
|
+
return tuple(configurations)
|
|
109
|
+
|
|
110
|
+
|
|
89
111
|
def load_config(path: Path | str = DEFAULT_CONFIG) -> CpdocsConfig:
|
|
90
112
|
config_file = Path(path).expanduser().resolve()
|
|
91
113
|
if not config_file.is_file():
|
|
@@ -97,7 +119,7 @@ def load_config(path: Path | str = DEFAULT_CONFIG) -> CpdocsConfig:
|
|
|
97
119
|
raise RuntimeError(
|
|
98
120
|
f"cpdocs.yml: contract must be {CONTRACT_VERSION}, found {raw.get('contract')!r}"
|
|
99
121
|
)
|
|
100
|
-
known = {"contract", "build", "versions", "site", "api", "checks"}
|
|
122
|
+
known = {"contract", "build", "languages", "versions", "site", "api", "checks"}
|
|
101
123
|
unknown = sorted(set(raw) - known)
|
|
102
124
|
if unknown:
|
|
103
125
|
raise RuntimeError(f"cpdocs.yml: unknown top-level keys: {', '.join(unknown)}")
|
|
@@ -123,6 +145,7 @@ def load_config(path: Path | str = DEFAULT_CONFIG) -> CpdocsConfig:
|
|
|
123
145
|
project_root=root,
|
|
124
146
|
feature_sets=_command(build.get("feature-sets"), "build.feature-sets"),
|
|
125
147
|
build=_command(build.get("build"), "build.build"),
|
|
148
|
+
language_configurations=_language_configurations(raw),
|
|
126
149
|
versions=_versions(raw.get("versions")),
|
|
127
150
|
index=index if index.is_file() else None,
|
|
128
151
|
copyright=str(copyright_value) if copyright_value is not None else None,
|
|
@@ -22,7 +22,31 @@ from ..contract import (
|
|
|
22
22
|
write_feature_set,
|
|
23
23
|
)
|
|
24
24
|
|
|
25
|
-
_PLACEHOLDER = re.compile(r"\{\{([a-z][a-z0-
|
|
25
|
+
_PLACEHOLDER = re.compile(r"\{\{\s*([a-z][a-z0-9_.-]*)\s*\}\}")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def language_template_values(configuration: dict[str, object]) -> dict[str, str]:
|
|
29
|
+
"""Flatten concrete Keyso values into dotted command-template placeholders."""
|
|
30
|
+
|
|
31
|
+
result: dict[str, str] = {}
|
|
32
|
+
|
|
33
|
+
def visit(path: str, value: object) -> None:
|
|
34
|
+
if isinstance(value, dict):
|
|
35
|
+
for key, child in value.items():
|
|
36
|
+
if not isinstance(key, str) or not re.fullmatch(r"[a-z][a-z0-9_-]*", key):
|
|
37
|
+
raise RuntimeError(f"cpdocs.yml: invalid language property {key!r}")
|
|
38
|
+
visit(f"{path}.{key}" if path else key, child)
|
|
39
|
+
elif isinstance(value, (str, int, float, bool)) and not isinstance(value, complex):
|
|
40
|
+
if not path:
|
|
41
|
+
raise RuntimeError("cpdocs.yml: language configuration needs a property name")
|
|
42
|
+
if path in {"source", "tmpdir", "output-file", "feature-set", "python"}:
|
|
43
|
+
raise RuntimeError(f"cpdocs.yml: language property {path!r} is reserved")
|
|
44
|
+
result[path] = str(value).lower() if isinstance(value, bool) else str(value)
|
|
45
|
+
else:
|
|
46
|
+
raise RuntimeError(f"cpdocs.yml: language property {path!r} must be a scalar value")
|
|
47
|
+
|
|
48
|
+
visit("", configuration)
|
|
49
|
+
return result
|
|
26
50
|
|
|
27
51
|
|
|
28
52
|
def _expand(command: str, values: dict[str, str], *, allowed: set[str], name: str) -> str:
|
|
@@ -71,7 +95,9 @@ def _run_command(
|
|
|
71
95
|
)
|
|
72
96
|
|
|
73
97
|
|
|
74
|
-
def discover_feature_sets(
|
|
98
|
+
def discover_feature_sets(
|
|
99
|
+
command: str, *, source: Path, work: Path, template_values: dict[str, str] | None = None
|
|
100
|
+
) -> FeatureSets:
|
|
75
101
|
"""Run ``build.feature-sets`` and read ``feature-sets.json``."""
|
|
76
102
|
|
|
77
103
|
directory = work / "feature-sets"
|
|
@@ -87,8 +113,9 @@ def discover_feature_sets(command: str, *, source: Path, work: Path) -> FeatureS
|
|
|
87
113
|
"tmpdir": str(tmpdir.resolve()),
|
|
88
114
|
"output-file": str(output.resolve()),
|
|
89
115
|
"python": sys.executable,
|
|
116
|
+
**(template_values or {}),
|
|
90
117
|
},
|
|
91
|
-
allowed={"source", "tmpdir", "output-file", "python"},
|
|
118
|
+
allowed={"source", "tmpdir", "output-file", "python"} | set(template_values or {}),
|
|
92
119
|
name="feature-sets",
|
|
93
120
|
log=directory / "log.txt",
|
|
94
121
|
)
|
|
@@ -96,7 +123,12 @@ def discover_feature_sets(command: str, *, source: Path, work: Path) -> FeatureS
|
|
|
96
123
|
|
|
97
124
|
|
|
98
125
|
def resolve_manifest(
|
|
99
|
-
command: str,
|
|
126
|
+
command: str,
|
|
127
|
+
feature_set: FeatureSetDeclaration,
|
|
128
|
+
*,
|
|
129
|
+
source: Path,
|
|
130
|
+
work: Path,
|
|
131
|
+
template_values: dict[str, str] | None = None,
|
|
100
132
|
) -> Manifest:
|
|
101
133
|
"""Run ``build.build`` for one feature set and read ``manifest.json``."""
|
|
102
134
|
|
|
@@ -116,8 +148,10 @@ def resolve_manifest(
|
|
|
116
148
|
"feature-set": str(feature_set_file.resolve()),
|
|
117
149
|
"output-file": str(output.resolve()),
|
|
118
150
|
"python": sys.executable,
|
|
151
|
+
**(template_values or {}),
|
|
119
152
|
},
|
|
120
|
-
allowed={"source", "tmpdir", "feature-set", "output-file", "python"}
|
|
153
|
+
allowed={"source", "tmpdir", "feature-set", "output-file", "python"}
|
|
154
|
+
| set(template_values or {}),
|
|
121
155
|
name="build",
|
|
122
156
|
log=directory / "log.txt",
|
|
123
157
|
)
|