diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..e649ce0 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,48 @@ +name: "Sphinx: Render docs" + +on: + pull_request: + branches: + - "**" + paths: + # Run for changes to *this* workflow file, but not for other workflows + - ".github/workflows/docs.yml" + # Trigger off docs and Python source code changes + - "docs/**" + - "src/**.py" + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + permissions: + # Allow updating the gh-pages branch + contents: write + + # Check https://github.com/actions/action-versions/tree/main/config/actions + # for latest versions if the standard actions start emitting warnings + steps: + - uses: actions/checkout@v4 + + - name: Build HTML + uses: ammaraskar/sphinx-action@master + with: + docs-folder: "docs/" + # Skip link check until after the venvstacks repo is public + # pre-build-command: "sphinx-build -b linkcheck . _build" + build-command: "sphinx-build -b dirhtml . _build" + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: html-docs + path: docs/_build/dirhtml/ + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + if: github.ref == 'refs/heads/main' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: docs/_build/dirhtml diff --git a/ci-bootstrap-requirements.txt b/ci-bootstrap-requirements.txt index 42a5616..e39e3a3 100644 --- a/ci-bootstrap-requirements.txt +++ b/ci-bootstrap-requirements.txt @@ -19,9 +19,9 @@ distlib==0.3.9 \ filelock==3.16.1 \ --hash=sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0 \ --hash=sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435 -findpython==0.6.1 \ - --hash=sha256:1fb4d709205de185b0561900267dfff64a841c910fe28d6038b2394ff925a81a \ - --hash=sha256:56e52b409a92bcbd495cf981c85acf137f3b3e51cc769b46eba219bb1ab7533c +findpython==0.6.2 \ + --hash=sha256:bda62477f858ea623ef2269f5e734469a018104a5f6c0fd9317ba238464ddb76 \ + --hash=sha256:e0c75ba9f35a7f9bb4423eb31bd17358cccf15761b6837317719177aeff46723 h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ --hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761 @@ -69,9 +69,9 @@ packaging==24.1 \ pbs-installer==2024.10.10 \ --hash=sha256:228bba8e78134c407ee6637da6a5a16479aaa702332bfb1b95d873fc00802305 \ --hash=sha256:b82fb5c96a4ca2a8c2ea2521268fa83fa18c1bfa32decfb3d77139a07c13f90c -pdm==2.19.2 \ - --hash=sha256:42af4e0897b139656e003767e99c4f77014bf36d9a7b759d3e09b49ee5979143 \ - --hash=sha256:efb39264569181d0375536ef81c556648f16b540d429a53715730490a2283567 +pdm==2.19.3 \ + --hash=sha256:80594e5d6167fb17ea724df09b68cdfe9c601ad7f218f1beea2c032b61bf30e9 \ + --hash=sha256:a9cc7f2078cd3b25ac645ffb5eca9d6b3d5dfcd788eaddfb6083432da71c97c2 platformdirs==4.3.6 \ --hash=sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907 \ --hash=sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb @@ -111,6 +111,6 @@ typing-extensions==4.12.2 \ unearth==0.17.2 \ --hash=sha256:0b8a2afd3476f1ab6155fc579501ac47fffe43547d88a70e5a5b76a7fe6caa2c \ --hash=sha256:4d21af1238a583835fca156322f7225382e718cdcc42d6278050a88e605c4ad5 -virtualenv==20.26.6 \ - --hash=sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48 \ - --hash=sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2 +virtualenv==20.27.0 \ + --hash=sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2 \ + --hash=sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655 diff --git a/ci-constraints.txt b/ci-constraints.txt index 673a74e..6d3d61a 100644 --- a/ci-constraints.txt +++ b/ci-constraints.txt @@ -1,12 +1,21 @@ # This file is @generated by PDM. # Please do not edit it manually. +alabaster==1.0.0 \ + --hash=sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e \ + --hash=sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b anyio==4.6.2.post1 \ --hash=sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c \ --hash=sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ --hash=sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2 +babel==2.16.0 \ + --hash=sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b \ + --hash=sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316 +beautifulsoup4==4.12.3 \ + --hash=sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051 \ + --hash=sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed blinker==1.8.2 \ --hash=sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01 \ --hash=sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83 @@ -22,6 +31,24 @@ certifi==2024.8.30 \ chardet==5.2.0 \ --hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \ --hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 +charset-normalizer==3.4.0 \ + --hash=sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6 \ + --hash=sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c \ + --hash=sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e \ + --hash=sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc \ + --hash=sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc \ + --hash=sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db \ + --hash=sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee \ + --hash=sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b \ + --hash=sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15 \ + --hash=sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250 \ + --hash=sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9 \ + --hash=sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944 \ + --hash=sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27 \ + --hash=sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114 \ + --hash=sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf \ + --hash=sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed \ + --hash=sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079 click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de @@ -34,20 +61,18 @@ dep-logic==0.4.9 \ distlib==0.3.9 \ --hash=sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87 \ --hash=sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403 -dulwich==0.22.1 \ - --hash=sha256:12482e318895da9acabea7c0cc70b35d36833e7cb2def511ab3a63617f5c1af3 \ - --hash=sha256:6dc42afedc8cda4f2fd15a06d2e9e41281074a02cdf31bb2e0dde4d80766a408 \ - --hash=sha256:82f26e592e9a36ab33bcdb419c7d53320e26c85dfc254cdb84f5f561a2fcaabf \ - --hash=sha256:9d19f04ecd4628a0e4587b4c4e98e040b87924c1362ae5aa27420435f05d5dd8 \ - --hash=sha256:a18d1392eabd02f337dcba23d723a4dcca87274ce8693cf88e6320f38bc3fdcd \ - --hash=sha256:e36d85967cfbf25da1c7bc3d6921adc5baa976969d926aaf1582bd5fd7e94758 \ - --hash=sha256:e90b8a2f24149c5803b733a24f1a016a2943b1f5a9ab2360db545e4638354c35 +docutils==0.21.2 \ + --hash=sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f \ + --hash=sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 filelock==3.16.1 \ --hash=sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0 \ --hash=sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435 -findpython==0.6.1 \ - --hash=sha256:1fb4d709205de185b0561900267dfff64a841c910fe28d6038b2394ff925a81a \ - --hash=sha256:56e52b409a92bcbd495cf981c85acf137f3b3e51cc769b46eba219bb1ab7533c +findpython==0.6.2 \ + --hash=sha256:bda62477f858ea623ef2269f5e734469a018104a5f6c0fd9317ba238464ddb76 \ + --hash=sha256:e0c75ba9f35a7f9bb4423eb31bd17358cccf15761b6837317719177aeff46723 +furo==2024.8.6 \ + --hash=sha256:6cd97c58b47813d3619e63e9081169880fbe331f0ca883c871ff1f3f11814f5c \ + --hash=sha256:b63e4cee8abfc3136d3bc03a3d45a76a850bada4d6374d24c1716b0e01394a01 h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ --hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761 @@ -63,15 +88,39 @@ httpx==0.27.2 \ idna==3.10 \ --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 +imagesize==1.4.1 \ + --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \ + --hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a iniconfig==2.0.0 \ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 installer==0.7.0 \ --hash=sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53 \ --hash=sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631 +jinja2==3.1.4 \ + --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \ + --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d markdown-it-py==3.0.0 \ --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb +markupsafe==3.0.2 \ + --hash=sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 \ + --hash=sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b \ + --hash=sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225 \ + --hash=sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87 \ + --hash=sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d \ + --hash=sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93 \ + --hash=sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf \ + --hash=sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84 \ + --hash=sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb \ + --hash=sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c \ + --hash=sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd \ + --hash=sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d \ + --hash=sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8 \ + --hash=sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f \ + --hash=sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f \ + --hash=sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0 \ + --hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba @@ -92,24 +141,24 @@ msgpack==1.1.0 \ --hash=sha256:d46cf9e3705ea9485687aa4001a76e44748b609d260af21c4ceea7f2212a501d \ --hash=sha256:dd432ccc2c72b914e4cb77afce64aab761c1137cc698be3984eee260bcb2896e \ --hash=sha256:fd2906780f25c8ed5d7b323379f6138524ba793428db5d0e9d226d3fa6aa1788 -mypy==1.12.0 \ - --hash=sha256:1ebf9e796521f99d61864ed89d1fb2926d9ab6a5fab421e457cd9c7e4dd65aa9 \ - --hash=sha256:20c7c5ce0c1be0b0aea628374e6cf68b420bcc772d85c3c974f675b88e3e6e57 \ - --hash=sha256:233e11b3f73ee1f10efada2e6da0f555b2f3a5316e9d8a4a1224acc10e7181d3 \ - --hash=sha256:2f106db5ccb60681b622ac768455743ee0e6a857724d648c9629a9bd2ac3f721 \ - --hash=sha256:48d3e37dd7d9403e38fa86c46191de72705166d40b8c9f91a3de77350daa0893 \ - --hash=sha256:4ae8959c21abcf9d73aa6c74a313c45c0b5a188752bf37dace564e29f06e9c1b \ - --hash=sha256:4b86de37a0da945f6d48cf110d5206c5ed514b1ca2614d7ad652d4bf099c7de7 \ - --hash=sha256:52b9e1492e47e1790360a43755fa04101a7ac72287b1a53ce817f35899ba0521 \ - --hash=sha256:5bc81701d52cc8767005fdd2a08c19980de9ec61a25dbd2a937dfb1338a826f9 \ - --hash=sha256:65a22d87e757ccd95cbbf6f7e181e6caa87128255eb2b6be901bb71b26d8a99d \ - --hash=sha256:8462655b6694feb1c99e433ea905d46c478041a8b8f0c33f1dab00ae881b2164 \ - --hash=sha256:923ea66d282d8af9e0f9c21ffc6653643abb95b658c3a8a32dca1eff09c06475 \ - --hash=sha256:a64ee25f05fc2d3d8474985c58042b6759100a475f8237da1f4faf7fcd7e6309 \ - --hash=sha256:c72861b7139a4f738344faa0e150834467521a3fba42dc98264e5aa9507dd601 \ - --hash=sha256:e478601cc3e3fa9d6734d255a59c7a2e5c2934da4378f3dd1e3411ea8a248642 \ - --hash=sha256:faca7ab947c9f457a08dcb8d9a8664fd438080e002b0fa3e41b0535335edcf7f \ - --hash=sha256:fd313226af375d52e1e36c383f39bf3836e1f192801116b31b090dfcd3ec5266 +mypy==1.12.1 \ + --hash=sha256:02dcfe270c6ea13338210908f8cadc8d31af0f04cee8ca996438fe6a97b4ec66 \ + --hash=sha256:1230048fec1380faf240be6385e709c8570604d2d27ec6ca7e573e3bc09c3735 \ + --hash=sha256:186e0c8346efc027ee1f9acf5ca734425fc4f7dc2b60144f0fbe27cc19dc7931 \ + --hash=sha256:19bf51f87a295e7ab2894f1d8167622b063492d754e69c3c2fed6563268cb42a \ + --hash=sha256:20db6eb1ca3d1de8ece00033b12f793f1ea9da767334b7e8c626a4872090cf02 \ + --hash=sha256:389e307e333879c571029d5b93932cf838b811d3f5395ed1ad05086b52148fb0 \ + --hash=sha256:427878aa54f2e2c5d8db31fa9010c599ed9f994b3b49e64ae9cd9990c40bd635 \ + --hash=sha256:4ee5932370ccf7ebf83f79d1c157a5929d7ea36313027b0d70a488493dc1b179 \ + --hash=sha256:5fcde63ea2c9f69d6be859a1e6dd35955e87fa81de95bc240143cf00de1f7f81 \ + --hash=sha256:673ba1140a478b50e6d265c03391702fa11a5c5aff3f54d69a62a48da32cb811 \ + --hash=sha256:94b2048a95a21f7a9ebc9fbd075a4fcd310410d078aa0228dbbad7f71335e042 \ + --hash=sha256:9fb83a7be97c498176fb7486cafbb81decccaef1ac339d837c377b0ce3743a7f \ + --hash=sha256:a5a437c9102a6a252d9e3a63edc191a3aed5f2fcb786d614722ee3f4472e33f6 \ + --hash=sha256:ce561a09e3bb9863ab77edf29ae3a50e65685ad74bba1431278185b7e5d5486e \ + --hash=sha256:d34167d43613ffb1d6c6cdc0cc043bb106cac0aa5d6a4171f77ab92a3c758bcc \ + --hash=sha256:d54d840f6c052929f4a3d2aab2066af0f45a020b085fe0e40d4583db52aab4e4 \ + --hash=sha256:f5b3936f7a6d0e8280c9bdef94c7ce4847f5cdfc258fbb2c29a8c1711e8bb96d mypy-extensions==1.0.0 \ --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782 @@ -119,9 +168,9 @@ packaging==24.1 \ pbs-installer==2024.10.10 \ --hash=sha256:228bba8e78134c407ee6637da6a5a16479aaa702332bfb1b95d873fc00802305 \ --hash=sha256:b82fb5c96a4ca2a8c2ea2521268fa83fa18c1bfa32decfb3d77139a07c13f90c -pdm==2.19.2 \ - --hash=sha256:42af4e0897b139656e003767e99c4f77014bf36d9a7b759d3e09b49ee5979143 \ - --hash=sha256:efb39264569181d0375536ef81c556648f16b540d429a53715730490a2283567 +pdm==2.19.3 \ + --hash=sha256:80594e5d6167fb17ea724df09b68cdfe9c601ad7f218f1beea2c032b61bf30e9 \ + --hash=sha256:a9cc7f2078cd3b25ac645ffb5eca9d6b3d5dfcd788eaddfb6083432da71c97c2 pip==24.2 \ --hash=sha256:2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2 \ --hash=sha256:5b5e490b5e9cb275c879595064adce9ebd31b854e3e803740b72f9ccf34a45b8 @@ -152,37 +201,70 @@ pytest-subtests==0.13.1 \ python-dotenv==1.0.1 \ --hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \ --hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a +requests==2.32.3 \ + --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ + --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 resolvelib==1.0.1 \ --hash=sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309 \ --hash=sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf rich==13.9.2 \ --hash=sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c \ --hash=sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1 -ruff==0.6.9 \ - --hash=sha256:140d4b5c9f5fc7a7b074908a78ab8d384dd7f6510402267bc76c37195c02a7ec \ - --hash=sha256:53fd8ca5e82bdee8da7f506d7b03a261f24cd43d090ea9db9a1dc59d9313914c \ - --hash=sha256:785d31851c1ae91f45b3d8fe23b8ae4b5170089021fbb42402d811135f0b7117 \ - --hash=sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa \ - --hash=sha256:a9641e31476d601f83cd602608739a0840e348bda93fec9f1ee816f8b6798b93 \ - --hash=sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2 -setuptools==75.1.0 \ - --hash=sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2 \ - --hash=sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538 +ruff==0.7.0 \ + --hash=sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e \ + --hash=sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06 \ + --hash=sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b \ + --hash=sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737 \ + --hash=sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9 \ + --hash=sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2 +setuptools==75.2.0 \ + --hash=sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec \ + --hash=sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8 shellingham==1.5.4 \ --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ --hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de sniffio==1.3.1 \ --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc +snowballstemmer==2.2.0 \ + --hash=sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 \ + --hash=sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a socksio==1.0.0 \ --hash=sha256:95dc1f15f9b34e8d7b16f06d74b8ccf48f609af32ab33c608d08761c5dcbb1f3 \ --hash=sha256:f88beb3da5b5c38b9890469de67d0cb0f9d494b78b106ca1845f96c10b91c4ac +soupsieve==2.6 \ + --hash=sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb \ + --hash=sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9 +sphinx==8.1.3 \ + --hash=sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2 \ + --hash=sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927 +sphinx-basic-ng==1.0.0b2 \ + --hash=sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9 \ + --hash=sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b +sphinxcontrib-applehelp==2.0.0 \ + --hash=sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1 \ + --hash=sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 +sphinxcontrib-devhelp==2.0.0 \ + --hash=sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad \ + --hash=sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2 +sphinxcontrib-htmlhelp==2.1.0 \ + --hash=sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8 \ + --hash=sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9 +sphinxcontrib-jsmath==1.0.1 \ + --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \ + --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8 +sphinxcontrib-qthelp==2.0.0 \ + --hash=sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab \ + --hash=sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb +sphinxcontrib-serializinghtml==2.0.0 \ + --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ + --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d tomlkit==0.13.2 \ --hash=sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde \ --hash=sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79 -tox==4.21.2 \ - --hash=sha256:13d996adcd792e7c82994b0e116d85efd84f0c6d185254d83d156f73f86b2038 \ - --hash=sha256:49381ff102296753e378fa5ff30e42a35e695f149b4dbf8a2c49d15fdb5797b2 +tox==4.23.0 \ + --hash=sha256:46da40afb660e46238c251280eb910bdaf00b390c7557c8e4bb611f422e9db12 \ + --hash=sha256:a6bd7d54231d755348d3c3a7b450b5bf6563833716d1299a1619587a1b77a3bf tox-gh==1.4.4 \ --hash=sha256:4ea585f66585b90f5826b1677cfc9453747792a0f9ff83d468603bc17556e07b \ --hash=sha256:b962e0f8c4619e98d11c2a135939876691e148b843b7dac4cff7de1dc4f7c215 @@ -211,9 +293,9 @@ uv==0.4.21 \ --hash=sha256:9dcddbb3b6e1662c6db41d63db539742450e2ce17d6c746329c016e3651bfb4a \ --hash=sha256:a1a9a126ce48f0f0893891adb5a9749220425169092f3e4da1216168736ac16d \ --hash=sha256:ba3e3b40cc1d5a980d36589775d6a7e4defa1b33e7e06423af0e395b8e4d9505 -virtualenv==20.26.6 \ - --hash=sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48 \ - --hash=sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2 +virtualenv==20.27.0 \ + --hash=sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2 \ + --hash=sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655 wheel==0.44.0 \ --hash=sha256:2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f \ --hash=sha256:a29c3f2817e95ab89aa4660681ad547c0e9547f20e75b0562fe7723c9a2a9d49 diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..e35d885 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +_build diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/api/index.rst b/docs/api/index.rst new file mode 100644 index 0000000..924876c --- /dev/null +++ b/docs/api/index.rst @@ -0,0 +1,19 @@ +Python API +========== + +.. warning:: + + The Python API is *NOT YET STABLE*. + Function, class, and method names may change between releases + without any deprecation period. + +.. automodule:: venvstacks + + .. rubric:: Modules + + .. autosummary:: + :toctree: + + cli + pack_venv + stacks diff --git a/docs/api/venvstacks.cli.main.rst b/docs/api/venvstacks.cli.main.rst new file mode 100644 index 0000000..2925f3a --- /dev/null +++ b/docs/api/venvstacks.cli.main.rst @@ -0,0 +1,6 @@ +venvstacks.cli.main +=================== + +.. currentmodule:: venvstacks.cli + +.. autofunction:: main \ No newline at end of file diff --git a/docs/api/venvstacks.cli.rst b/docs/api/venvstacks.cli.rst new file mode 100644 index 0000000..dbc55b2 --- /dev/null +++ b/docs/api/venvstacks.cli.rst @@ -0,0 +1,12 @@ +venvstacks.cli +============== + +.. automodule:: venvstacks.cli + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + main diff --git a/docs/api/venvstacks.pack_venv.convert_symlinks.rst b/docs/api/venvstacks.pack_venv.convert_symlinks.rst new file mode 100644 index 0000000..5f4cb09 --- /dev/null +++ b/docs/api/venvstacks.pack_venv.convert_symlinks.rst @@ -0,0 +1,6 @@ +venvstacks.pack\_venv.convert\_symlinks +======================================= + +.. currentmodule:: venvstacks.pack_venv + +.. autofunction:: convert_symlinks \ No newline at end of file diff --git a/docs/api/venvstacks.pack_venv.create_archive.rst b/docs/api/venvstacks.pack_venv.create_archive.rst new file mode 100644 index 0000000..ad073d8 --- /dev/null +++ b/docs/api/venvstacks.pack_venv.create_archive.rst @@ -0,0 +1,6 @@ +venvstacks.pack\_venv.create\_archive +===================================== + +.. currentmodule:: venvstacks.pack_venv + +.. autofunction:: create_archive \ No newline at end of file diff --git a/docs/api/venvstacks.pack_venv.export_venv.rst b/docs/api/venvstacks.pack_venv.export_venv.rst new file mode 100644 index 0000000..0003c3b --- /dev/null +++ b/docs/api/venvstacks.pack_venv.export_venv.rst @@ -0,0 +1,6 @@ +venvstacks.pack\_venv.export\_venv +================================== + +.. currentmodule:: venvstacks.pack_venv + +.. autofunction:: export_venv \ No newline at end of file diff --git a/docs/api/venvstacks.pack_venv.get_archive_path.rst b/docs/api/venvstacks.pack_venv.get_archive_path.rst new file mode 100644 index 0000000..9d11246 --- /dev/null +++ b/docs/api/venvstacks.pack_venv.get_archive_path.rst @@ -0,0 +1,6 @@ +venvstacks.pack\_venv.get\_archive\_path +======================================== + +.. currentmodule:: venvstacks.pack_venv + +.. autofunction:: get_archive_path \ No newline at end of file diff --git a/docs/api/venvstacks.pack_venv.rst b/docs/api/venvstacks.pack_venv.rst new file mode 100644 index 0000000..27cda38 --- /dev/null +++ b/docs/api/venvstacks.pack_venv.rst @@ -0,0 +1,15 @@ +venvstacks.pack\_venv +===================== + +.. automodule:: venvstacks.pack_venv + + + .. rubric:: Functions + + .. autosummary:: + :toctree: + + convert_symlinks + create_archive + export_venv + get_archive_path diff --git a/docs/api/venvstacks.stacks.ApplicationEnv.rst b/docs/api/venvstacks.stacks.ApplicationEnv.rst new file mode 100644 index 0000000..4d69509 --- /dev/null +++ b/docs/api/venvstacks.stacks.ApplicationEnv.rst @@ -0,0 +1,62 @@ +venvstacks.stacks.ApplicationEnv +================================ + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: ApplicationEnv + + + .. automethod:: __init__ + + .. rubric:: Methods + + .. autosummary:: + + ~ApplicationEnv.create_archive + ~ApplicationEnv.create_environment + ~ApplicationEnv.define_archive_build + ~ApplicationEnv.ensure_runtime_dependencies + ~ApplicationEnv.export_environment + ~ApplicationEnv.get_constraint_paths + ~ApplicationEnv.install_build_requirements + ~ApplicationEnv.install_requirements + ~ApplicationEnv.link_base_runtime_paths + ~ApplicationEnv.link_layered_environments + ~ApplicationEnv.lock_requirements + ~ApplicationEnv.remove_build_only_packages + ~ApplicationEnv.report_python_site_details + ~ApplicationEnv.request_export + ~ApplicationEnv.select_operations + + .. rubric:: Attributes + + .. autosummary:: + + ~ApplicationEnv.category + ~ApplicationEnv.env_name + ~ApplicationEnv.env_spec + ~ApplicationEnv.install_target + ~ApplicationEnv.kind + ~ApplicationEnv.launch_module_name + ~ApplicationEnv.linked_constraints_paths + ~ApplicationEnv.linked_dynlib_paths + ~ApplicationEnv.linked_frameworks + ~ApplicationEnv.linked_pylib_paths + ~ApplicationEnv.want_build + ~ApplicationEnv.want_lock + ~ApplicationEnv.want_publish + ~ApplicationEnv.was_built + ~ApplicationEnv.was_created + ~ApplicationEnv.build_path + ~ApplicationEnv.requirements_path + ~ApplicationEnv.index_config + ~ApplicationEnv.env_path + ~ApplicationEnv.pylib_path + ~ApplicationEnv.dynlib_path + ~ApplicationEnv.executables_path + ~ApplicationEnv.python_path + ~ApplicationEnv.env_lock + ~ApplicationEnv.base_python_path + ~ApplicationEnv.tools_python_path + ~ApplicationEnv.py_version + diff --git a/docs/api/venvstacks.stacks.ApplicationSpec.rst b/docs/api/venvstacks.stacks.ApplicationSpec.rst new file mode 100644 index 0000000..5564fc4 --- /dev/null +++ b/docs/api/venvstacks.stacks.ApplicationSpec.rst @@ -0,0 +1,35 @@ +venvstacks.stacks.ApplicationSpec +================================= + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: ApplicationSpec + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~ApplicationSpec.get_requirements_fname + ~ApplicationSpec.get_requirements_path + + .. rubric:: Attributes + + .. autosummary:: + + ~ApplicationSpec.ENV_PREFIX + ~ApplicationSpec.category + ~ApplicationSpec.env_name + ~ApplicationSpec.kind + ~ApplicationSpec.launch_module_path + ~ApplicationSpec.frameworks + ~ApplicationSpec.runtime + ~ApplicationSpec.name + ~ApplicationSpec.versioned + ~ApplicationSpec.requirements + ~ApplicationSpec.build_requirements + ~ApplicationSpec.platforms + diff --git a/docs/api/venvstacks.stacks.ArchiveBuildMetadata.rst b/docs/api/venvstacks.stacks.ArchiveBuildMetadata.rst new file mode 100644 index 0000000..b6fdfc2 --- /dev/null +++ b/docs/api/venvstacks.stacks.ArchiveBuildMetadata.rst @@ -0,0 +1,27 @@ +venvstacks.stacks.ArchiveBuildMetadata +====================================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: ArchiveBuildMetadata + + + .. automethod:: __init__ + + .. rubric:: Attributes + + .. autosummary:: + + ~ArchiveBuildMetadata.layer_name + ~ArchiveBuildMetadata.install_target + ~ArchiveBuildMetadata.requirements_hash + ~ArchiveBuildMetadata.lock_version + ~ArchiveBuildMetadata.locked_at + ~ArchiveBuildMetadata.runtime_name + ~ArchiveBuildMetadata.required_layers + ~ArchiveBuildMetadata.app_launch_module + ~ArchiveBuildMetadata.app_launch_module_hash + ~ArchiveBuildMetadata.archive_build + ~ArchiveBuildMetadata.archive_name + ~ArchiveBuildMetadata.target_platform + diff --git a/docs/api/venvstacks.stacks.ArchiveBuildRequest.rst b/docs/api/venvstacks.stacks.ArchiveBuildRequest.rst new file mode 100644 index 0000000..a428119 --- /dev/null +++ b/docs/api/venvstacks.stacks.ArchiveBuildRequest.rst @@ -0,0 +1,29 @@ +venvstacks.stacks.ArchiveBuildRequest +===================================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: ArchiveBuildRequest + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~ArchiveBuildRequest.create_archive + ~ArchiveBuildRequest.define_build + ~ArchiveBuildRequest.needs_archive_build + + .. rubric:: Attributes + + .. autosummary:: + + ~ArchiveBuildRequest.env_name + ~ArchiveBuildRequest.env_lock + ~ArchiveBuildRequest.archive_base_path + ~ArchiveBuildRequest.build_metadata + ~ArchiveBuildRequest.needs_build + diff --git a/docs/api/venvstacks.stacks.ArchiveHashes.rst b/docs/api/venvstacks.stacks.ArchiveHashes.rst new file mode 100644 index 0000000..9f39536 --- /dev/null +++ b/docs/api/venvstacks.stacks.ArchiveHashes.rst @@ -0,0 +1,15 @@ +venvstacks.stacks.ArchiveHashes +=============================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: ArchiveHashes + + .. automethod:: __init__ + + .. rubric:: Attributes + + .. autosummary:: + + ~ArchiveHashes.sha256 + diff --git a/docs/api/venvstacks.stacks.ArchiveMetadata.rst b/docs/api/venvstacks.stacks.ArchiveMetadata.rst new file mode 100644 index 0000000..c9035ba --- /dev/null +++ b/docs/api/venvstacks.stacks.ArchiveMetadata.rst @@ -0,0 +1,28 @@ +venvstacks.stacks.ArchiveMetadata +================================= + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: ArchiveMetadata + + .. automethod:: __init__ + + .. rubric:: Attributes + + .. autosummary:: + + ~ArchiveMetadata.layer_name + ~ArchiveMetadata.install_target + ~ArchiveMetadata.requirements_hash + ~ArchiveMetadata.lock_version + ~ArchiveMetadata.locked_at + ~ArchiveMetadata.runtime_name + ~ArchiveMetadata.required_layers + ~ArchiveMetadata.app_launch_module + ~ArchiveMetadata.app_launch_module_hash + ~ArchiveMetadata.archive_build + ~ArchiveMetadata.archive_name + ~ArchiveMetadata.target_platform + ~ArchiveMetadata.archive_size + ~ArchiveMetadata.archive_hashes + diff --git a/docs/api/venvstacks.stacks.BuildEnvError.rst b/docs/api/venvstacks.stacks.BuildEnvError.rst new file mode 100644 index 0000000..dee61d4 --- /dev/null +++ b/docs/api/venvstacks.stacks.BuildEnvError.rst @@ -0,0 +1,6 @@ +venvstacks.stacks.BuildEnvError +=============================== + +.. currentmodule:: venvstacks.stacks + +.. autoexception:: BuildEnvError \ No newline at end of file diff --git a/docs/api/venvstacks.stacks.BuildEnvironment.rst b/docs/api/venvstacks.stacks.BuildEnvironment.rst new file mode 100644 index 0000000..4b11373 --- /dev/null +++ b/docs/api/venvstacks.stacks.BuildEnvironment.rst @@ -0,0 +1,52 @@ +venvstacks.stacks.BuildEnvironment +================================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: BuildEnvironment + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~BuildEnvironment.all_environments + ~BuildEnvironment.built_environments + ~BuildEnvironment.create_environments + ~BuildEnvironment.environments_to_build + ~BuildEnvironment.environments_to_lock + ~BuildEnvironment.environments_to_publish + ~BuildEnvironment.export_environments + ~BuildEnvironment.get_unmatched_patterns + ~BuildEnvironment.load_archive_metadata + ~BuildEnvironment.load_export_metadata + ~BuildEnvironment.lock_environments + ~BuildEnvironment.publish_artifacts + ~BuildEnvironment.runtimes_to_build + ~BuildEnvironment.runtimes_to_lock + ~BuildEnvironment.select_layers + ~BuildEnvironment.select_operations + ~BuildEnvironment.venvstacks_to_build + ~BuildEnvironment.write_archive_metadata + ~BuildEnvironment.write_artifacts_manifest + ~BuildEnvironment.write_env_metadata + ~BuildEnvironment.write_export_manifest + + .. rubric:: Attributes + + .. autosummary:: + + ~BuildEnvironment.METADATA_DIR + ~BuildEnvironment.METADATA_ENV_DIR + ~BuildEnvironment.METADATA_MANIFEST + ~BuildEnvironment.build_platform + ~BuildEnvironment.requirements_dir_path + ~BuildEnvironment.stack_spec + ~BuildEnvironment.runtimes + ~BuildEnvironment.frameworks + ~BuildEnvironment.applications + ~BuildEnvironment.build_path + diff --git a/docs/api/venvstacks.stacks.EnvStackError.rst b/docs/api/venvstacks.stacks.EnvStackError.rst new file mode 100644 index 0000000..cd421b6 --- /dev/null +++ b/docs/api/venvstacks.stacks.EnvStackError.rst @@ -0,0 +1,6 @@ +venvstacks.stacks.EnvStackError +=============================== + +.. currentmodule:: venvstacks.stacks + +.. autoexception:: EnvStackError \ No newline at end of file diff --git a/docs/api/venvstacks.stacks.EnvironmentExportRequest.rst b/docs/api/venvstacks.stacks.EnvironmentExportRequest.rst new file mode 100644 index 0000000..3f253a0 --- /dev/null +++ b/docs/api/venvstacks.stacks.EnvironmentExportRequest.rst @@ -0,0 +1,29 @@ +venvstacks.stacks.EnvironmentExportRequest +========================================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: EnvironmentExportRequest + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~EnvironmentExportRequest.define_export + ~EnvironmentExportRequest.export_environment + ~EnvironmentExportRequest.needs_new_export + + .. rubric:: Attributes + + .. autosummary:: + + ~EnvironmentExportRequest.env_name + ~EnvironmentExportRequest.env_lock + ~EnvironmentExportRequest.export_path + ~EnvironmentExportRequest.export_metadata + ~EnvironmentExportRequest.needs_export + diff --git a/docs/api/venvstacks.stacks.EnvironmentLock.rst b/docs/api/venvstacks.stacks.EnvironmentLock.rst new file mode 100644 index 0000000..6382e6e --- /dev/null +++ b/docs/api/venvstacks.stacks.EnvironmentLock.rst @@ -0,0 +1,32 @@ +venvstacks.stacks.EnvironmentLock +================================= + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: EnvironmentLock + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~EnvironmentLock.get_deployed_name + ~EnvironmentLock.load_valid_metadata + ~EnvironmentLock.update_lock_metadata + + .. rubric:: Attributes + + .. autosummary:: + + ~EnvironmentLock.is_locked + ~EnvironmentLock.last_locked + ~EnvironmentLock.lock_version + ~EnvironmentLock.locked_at + ~EnvironmentLock.requirements_hash + ~EnvironmentLock.requirements_path + ~EnvironmentLock.versioned + ~EnvironmentLock.lock_metadata_path + diff --git a/docs/api/venvstacks.stacks.EnvironmentLockMetadata.rst b/docs/api/venvstacks.stacks.EnvironmentLockMetadata.rst new file mode 100644 index 0000000..a8f20f6 --- /dev/null +++ b/docs/api/venvstacks.stacks.EnvironmentLockMetadata.rst @@ -0,0 +1,18 @@ +venvstacks.stacks.EnvironmentLockMetadata +========================================= + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: EnvironmentLockMetadata + + + .. automethod:: __init__ + + .. rubric:: Attributes + + .. autosummary:: + + ~EnvironmentLockMetadata.locked_at + ~EnvironmentLockMetadata.requirements_hash + ~EnvironmentLockMetadata.lock_version + diff --git a/docs/api/venvstacks.stacks.ExportMetadata.rst b/docs/api/venvstacks.stacks.ExportMetadata.rst new file mode 100644 index 0000000..6881e39 --- /dev/null +++ b/docs/api/venvstacks.stacks.ExportMetadata.rst @@ -0,0 +1,24 @@ +venvstacks.stacks.ExportMetadata +================================ + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: ExportMetadata + + + .. automethod:: __init__ + + .. rubric:: Attributes + + .. autosummary:: + + ~ExportMetadata.layer_name + ~ExportMetadata.install_target + ~ExportMetadata.requirements_hash + ~ExportMetadata.lock_version + ~ExportMetadata.locked_at + ~ExportMetadata.runtime_name + ~ExportMetadata.required_layers + ~ExportMetadata.app_launch_module + ~ExportMetadata.app_launch_module_hash + diff --git a/docs/api/venvstacks.stacks.ExportedEnvironmentPaths.rst b/docs/api/venvstacks.stacks.ExportedEnvironmentPaths.rst new file mode 100644 index 0000000..9cb30cb --- /dev/null +++ b/docs/api/venvstacks.stacks.ExportedEnvironmentPaths.rst @@ -0,0 +1,18 @@ +venvstacks.stacks.ExportedEnvironmentPaths +========================================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: ExportedEnvironmentPaths + + + .. automethod:: __init__ + + .. rubric:: Attributes + + .. autosummary:: + + ~ExportedEnvironmentPaths.env_paths + ~ExportedEnvironmentPaths.metadata_path + ~ExportedEnvironmentPaths.snippet_paths + diff --git a/docs/api/venvstacks.stacks.FrameworkEnv.rst b/docs/api/venvstacks.stacks.FrameworkEnv.rst new file mode 100644 index 0000000..09368fe --- /dev/null +++ b/docs/api/venvstacks.stacks.FrameworkEnv.rst @@ -0,0 +1,58 @@ +venvstacks.stacks.FrameworkEnv +============================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: FrameworkEnv + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~FrameworkEnv.create_archive + ~FrameworkEnv.create_environment + ~FrameworkEnv.define_archive_build + ~FrameworkEnv.ensure_runtime_dependencies + ~FrameworkEnv.export_environment + ~FrameworkEnv.get_constraint_paths + ~FrameworkEnv.install_build_requirements + ~FrameworkEnv.install_requirements + ~FrameworkEnv.link_base_runtime_paths + ~FrameworkEnv.lock_requirements + ~FrameworkEnv.remove_build_only_packages + ~FrameworkEnv.report_python_site_details + ~FrameworkEnv.request_export + ~FrameworkEnv.select_operations + + .. rubric:: Attributes + + .. autosummary:: + + ~FrameworkEnv.category + ~FrameworkEnv.env_name + ~FrameworkEnv.env_spec + ~FrameworkEnv.install_target + ~FrameworkEnv.kind + ~FrameworkEnv.linked_constraints_paths + ~FrameworkEnv.want_build + ~FrameworkEnv.want_lock + ~FrameworkEnv.want_publish + ~FrameworkEnv.was_built + ~FrameworkEnv.was_created + ~FrameworkEnv.build_path + ~FrameworkEnv.requirements_path + ~FrameworkEnv.index_config + ~FrameworkEnv.env_path + ~FrameworkEnv.pylib_path + ~FrameworkEnv.dynlib_path + ~FrameworkEnv.executables_path + ~FrameworkEnv.python_path + ~FrameworkEnv.env_lock + ~FrameworkEnv.base_python_path + ~FrameworkEnv.tools_python_path + ~FrameworkEnv.py_version + diff --git a/docs/api/venvstacks.stacks.FrameworkSpec.rst b/docs/api/venvstacks.stacks.FrameworkSpec.rst new file mode 100644 index 0000000..cd226b7 --- /dev/null +++ b/docs/api/venvstacks.stacks.FrameworkSpec.rst @@ -0,0 +1,33 @@ +venvstacks.stacks.FrameworkSpec +=============================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: FrameworkSpec + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~FrameworkSpec.get_requirements_fname + ~FrameworkSpec.get_requirements_path + + .. rubric:: Attributes + + .. autosummary:: + + ~FrameworkSpec.ENV_PREFIX + ~FrameworkSpec.category + ~FrameworkSpec.env_name + ~FrameworkSpec.kind + ~FrameworkSpec.runtime + ~FrameworkSpec.name + ~FrameworkSpec.versioned + ~FrameworkSpec.requirements + ~FrameworkSpec.build_requirements + ~FrameworkSpec.platforms + diff --git a/docs/api/venvstacks.stacks.IndexConfig.rst b/docs/api/venvstacks.stacks.IndexConfig.rst new file mode 100644 index 0000000..df39f67 --- /dev/null +++ b/docs/api/venvstacks.stacks.IndexConfig.rst @@ -0,0 +1,28 @@ +venvstacks.stacks.IndexConfig +============================= + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: IndexConfig + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~IndexConfig.disabled + ~IndexConfig.resolve_lexical_paths + + + .. rubric:: Attributes + + .. autosummary:: + + ~IndexConfig.allow_source_builds + ~IndexConfig.local_wheel_dirs + ~IndexConfig.query_default_index + ~IndexConfig.local_wheel_paths + diff --git a/docs/api/venvstacks.stacks.LayerCategories.rst b/docs/api/venvstacks.stacks.LayerCategories.rst new file mode 100644 index 0000000..cf56500 --- /dev/null +++ b/docs/api/venvstacks.stacks.LayerCategories.rst @@ -0,0 +1,18 @@ +venvstacks.stacks.LayerCategories +================================= + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: LayerCategories + + + .. automethod:: __init__ + + .. rubric:: Attributes + + .. autosummary:: + + ~LayerCategories.RUNTIMES + ~LayerCategories.FRAMEWORKS + ~LayerCategories.APPLICATIONS + diff --git a/docs/api/venvstacks.stacks.LayerSpecError.rst b/docs/api/venvstacks.stacks.LayerSpecError.rst new file mode 100644 index 0000000..e31007e --- /dev/null +++ b/docs/api/venvstacks.stacks.LayerSpecError.rst @@ -0,0 +1,6 @@ +venvstacks.stacks.LayerSpecError +================================ + +.. currentmodule:: venvstacks.stacks + +.. autoexception:: LayerSpecError \ No newline at end of file diff --git a/docs/api/venvstacks.stacks.LayerSpecMetadata.rst b/docs/api/venvstacks.stacks.LayerSpecMetadata.rst new file mode 100644 index 0000000..a6b4ddc --- /dev/null +++ b/docs/api/venvstacks.stacks.LayerSpecMetadata.rst @@ -0,0 +1,24 @@ +venvstacks.stacks.LayerSpecMetadata +=================================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: LayerSpecMetadata + + + .. automethod:: __init__ + + .. rubric:: Attributes + + .. autosummary:: + + ~LayerSpecMetadata.layer_name + ~LayerSpecMetadata.install_target + ~LayerSpecMetadata.requirements_hash + ~LayerSpecMetadata.lock_version + ~LayerSpecMetadata.locked_at + ~LayerSpecMetadata.runtime_name + ~LayerSpecMetadata.required_layers + ~LayerSpecMetadata.app_launch_module + ~LayerSpecMetadata.app_launch_module_hash + diff --git a/docs/api/venvstacks.stacks.LayerVariants.rst b/docs/api/venvstacks.stacks.LayerVariants.rst new file mode 100644 index 0000000..33cfb24 --- /dev/null +++ b/docs/api/venvstacks.stacks.LayerVariants.rst @@ -0,0 +1,18 @@ +venvstacks.stacks.LayerVariants +=============================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: LayerVariants + + + .. automethod:: __init__ + + .. rubric:: Attributes + + .. autosummary:: + + ~LayerVariants.RUNTIME + ~LayerVariants.FRAMEWORK + ~LayerVariants.APPLICATION + diff --git a/docs/api/venvstacks.stacks.PublishedArchivePaths.rst b/docs/api/venvstacks.stacks.PublishedArchivePaths.rst new file mode 100644 index 0000000..bfbbfe1 --- /dev/null +++ b/docs/api/venvstacks.stacks.PublishedArchivePaths.rst @@ -0,0 +1,15 @@ +venvstacks.stacks.PublishedArchivePaths +======================================= + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: PublishedArchivePaths + + .. rubric:: Attributes + + .. autosummary:: + + ~PublishedArchivePaths.archive_paths + ~PublishedArchivePaths.metadata_path + ~PublishedArchivePaths.snippet_paths + diff --git a/docs/api/venvstacks.stacks.RuntimeEnv.rst b/docs/api/venvstacks.stacks.RuntimeEnv.rst new file mode 100644 index 0000000..a8bf5ad --- /dev/null +++ b/docs/api/venvstacks.stacks.RuntimeEnv.rst @@ -0,0 +1,57 @@ +venvstacks.stacks.RuntimeEnv +============================ + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: RuntimeEnv + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~RuntimeEnv.create_archive + ~RuntimeEnv.create_build_environment + ~RuntimeEnv.create_environment + ~RuntimeEnv.define_archive_build + ~RuntimeEnv.ensure_runtime_dependencies + ~RuntimeEnv.export_environment + ~RuntimeEnv.get_constraint_paths + ~RuntimeEnv.install_build_requirements + ~RuntimeEnv.install_requirements + ~RuntimeEnv.lock_requirements + ~RuntimeEnv.remove_build_only_packages + ~RuntimeEnv.report_python_site_details + ~RuntimeEnv.request_export + ~RuntimeEnv.select_operations + + .. rubric:: Attributes + + .. autosummary:: + + ~RuntimeEnv.category + ~RuntimeEnv.env_name + ~RuntimeEnv.env_spec + ~RuntimeEnv.install_target + ~RuntimeEnv.kind + ~RuntimeEnv.want_build + ~RuntimeEnv.want_lock + ~RuntimeEnv.want_publish + ~RuntimeEnv.was_built + ~RuntimeEnv.was_created + ~RuntimeEnv.build_path + ~RuntimeEnv.requirements_path + ~RuntimeEnv.index_config + ~RuntimeEnv.env_path + ~RuntimeEnv.pylib_path + ~RuntimeEnv.dynlib_path + ~RuntimeEnv.executables_path + ~RuntimeEnv.python_path + ~RuntimeEnv.env_lock + ~RuntimeEnv.base_python_path + ~RuntimeEnv.tools_python_path + ~RuntimeEnv.py_version + diff --git a/docs/api/venvstacks.stacks.RuntimeSpec.rst b/docs/api/venvstacks.stacks.RuntimeSpec.rst new file mode 100644 index 0000000..5d14888 --- /dev/null +++ b/docs/api/venvstacks.stacks.RuntimeSpec.rst @@ -0,0 +1,34 @@ +venvstacks.stacks.RuntimeSpec +============================= + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: RuntimeSpec + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~RuntimeSpec.get_requirements_fname + ~RuntimeSpec.get_requirements_path + + .. rubric:: Attributes + + .. autosummary:: + + ~RuntimeSpec.ENV_PREFIX + ~RuntimeSpec.category + ~RuntimeSpec.env_name + ~RuntimeSpec.kind + ~RuntimeSpec.py_version + ~RuntimeSpec.fully_versioned_name + ~RuntimeSpec.name + ~RuntimeSpec.versioned + ~RuntimeSpec.requirements + ~RuntimeSpec.build_requirements + ~RuntimeSpec.platforms + diff --git a/docs/api/venvstacks.stacks.StackExportRequest.rst b/docs/api/venvstacks.stacks.StackExportRequest.rst new file mode 100644 index 0000000..560b0ac --- /dev/null +++ b/docs/api/venvstacks.stacks.StackExportRequest.rst @@ -0,0 +1,13 @@ +venvstacks.stacks.StackExportRequest +==================================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: StackExportRequest + + .. rubric:: Attributes + + .. autosummary:: + + ~StackExportRequest.layers + diff --git a/docs/api/venvstacks.stacks.StackPublishingRequest.rst b/docs/api/venvstacks.stacks.StackPublishingRequest.rst new file mode 100644 index 0000000..0c06b84 --- /dev/null +++ b/docs/api/venvstacks.stacks.StackPublishingRequest.rst @@ -0,0 +1,13 @@ +venvstacks.stacks.StackPublishingRequest +======================================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: StackPublishingRequest + + .. rubric:: Attributes + + .. autosummary:: + + ~StackPublishingRequest.layers + diff --git a/docs/api/venvstacks.stacks.StackPublishingResult.rst b/docs/api/venvstacks.stacks.StackPublishingResult.rst new file mode 100644 index 0000000..c68203e --- /dev/null +++ b/docs/api/venvstacks.stacks.StackPublishingResult.rst @@ -0,0 +1,13 @@ +venvstacks.stacks.StackPublishingResult +======================================= + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: StackPublishingResult + + .. rubric:: Attributes + + .. autosummary:: + + ~StackPublishingResult.layers + diff --git a/docs/api/venvstacks.stacks.StackSpec.rst b/docs/api/venvstacks.stacks.StackSpec.rst new file mode 100644 index 0000000..dfa0841 --- /dev/null +++ b/docs/api/venvstacks.stacks.StackSpec.rst @@ -0,0 +1,29 @@ +venvstacks.stacks.StackSpec +=========================== + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: StackSpec + + .. automethod:: __init__ + + .. rubric:: Methods + + .. autosummary:: + + ~StackSpec.all_environment_specs + ~StackSpec.define_build_environment + ~StackSpec.load + ~StackSpec.resolve_lexical_path + + .. rubric:: Attributes + + .. autosummary:: + + ~StackSpec.spec_path + ~StackSpec.runtimes + ~StackSpec.frameworks + ~StackSpec.applications + ~StackSpec.requirements_dir_path + ~StackSpec.build_platform + diff --git a/docs/api/venvstacks.stacks.TargetPlatform.rst b/docs/api/venvstacks.stacks.TargetPlatform.rst new file mode 100644 index 0000000..861b951 --- /dev/null +++ b/docs/api/venvstacks.stacks.TargetPlatform.rst @@ -0,0 +1,16 @@ +venvstacks.stacks.TargetPlatform +================================ + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: TargetPlatform + + .. rubric:: Attributes + + .. autosummary:: + + ~TargetPlatform.WINDOWS + ~TargetPlatform.LINUX + ~TargetPlatform.MACOS_APPLE + ~TargetPlatform.MACOS_INTEL + diff --git a/docs/api/venvstacks.stacks.TargetPlatforms.rst b/docs/api/venvstacks.stacks.TargetPlatforms.rst new file mode 100644 index 0000000..8c994b5 --- /dev/null +++ b/docs/api/venvstacks.stacks.TargetPlatforms.rst @@ -0,0 +1,16 @@ +venvstacks.stacks.TargetPlatforms +================================= + +.. currentmodule:: venvstacks.stacks + +.. autoclass:: TargetPlatforms + + .. rubric:: Attributes + + .. autosummary:: + + ~TargetPlatforms.WINDOWS + ~TargetPlatforms.LINUX + ~TargetPlatforms.MACOS_APPLE + ~TargetPlatforms.MACOS_INTEL + diff --git a/docs/api/venvstacks.stacks.rst b/docs/api/venvstacks.stacks.rst new file mode 100644 index 0000000..c87621d --- /dev/null +++ b/docs/api/venvstacks.stacks.rst @@ -0,0 +1,47 @@ +venvstacks.stacks +================= + +.. automodule:: venvstacks.stacks + + + .. rubric:: Classes + + .. autosummary:: + :toctree: + + ApplicationEnv + ApplicationSpec + ArchiveBuildMetadata + ArchiveBuildRequest + ArchiveHashes + ArchiveMetadata + BuildEnvironment + EnvironmentExportRequest + EnvironmentLock + EnvironmentLockMetadata + ExportMetadata + ExportedEnvironmentPaths + FrameworkEnv + FrameworkSpec + IndexConfig + LayerCategories + LayerSpecMetadata + LayerVariants + PublishedArchivePaths + RuntimeEnv + RuntimeSpec + StackExportRequest + StackPublishingRequest + StackPublishingResult + StackSpec + TargetPlatform + TargetPlatforms + + .. rubric:: Exceptions + + .. autosummary:: + :toctree: + + BuildEnvError + EnvStackError + LayerSpecError diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..1a4d755 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,61 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "venvstacks" +copyright = "2024, LM Studio" +author = "LM Studio" +release = "0.1" + + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + # first-party extensions + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.duration", + "sphinx.ext.extlinks", + "sphinx.ext.intersphinx", +] + +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "furo" +html_static_path = ["_static"] + +# Disable the generation of the various indexes +html_use_modindex = False +html_use_index = False + + +# -- Options for intersphinx ---------------------------------------------------------- + +# Run `tox -e regen-apidocs` to regenerate the API stub pages +autosummary_generate = False + +# -- Options for intersphinx ---------------------------------------------------------- + +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "pypug": ("https://packaging.python.org", None), +} + + +# -- Options for extlinks ------------------------------------------------------------- + +extlinks = { + "issue": ("https://github.com/lmstudio/venvstacks/issues/%s", "#%s"), + "pr": ("https://github.com/lmstudio/venvstacks/pull/%s", "PR #%s"), + "pypi": ("https://pypi.org/project/%s/", "%s"), +} diff --git a/docs/development/index.rst b/docs/development/index.rst new file mode 100644 index 0000000..df93041 --- /dev/null +++ b/docs/development/index.rst @@ -0,0 +1,184 @@ +Development +=========== + +(With thanks to pip's `Getting Started`_ guide for the general structure here!) + +This document aims to get you setup to work on venvstacks and to act as a guide +and reference to the development setup. If you face any issues during this +process, please `open an issue`_ about it on the issue tracker. + + +Get the source code +------------------- + +To work on venvstacks, you first need to get the source code. The source code is +available on `GitHub`_. + +.. code-block:: console + + $ git clone https://github.com/lmstudio/venvstacks + $ cd venvstacks + + +Development Environment +----------------------- + +In order to work on venvstacks, you need to install +:pypi:`pdm`, :pypi:`tox`, and :pypi:`tox-pdm`. + +Given these tools, the default development environment can be set up +and other commands executed as described below. + + +Running from the source tree +---------------------------- + +To run venvstacks from your source tree during development, use pdm +to set up an editable install in the default venv: + +.. code-block:: console + + $ pdm sync --dev + +venvstacks can then be executed via the ``-m`` switch: + +.. code-block:: console + + $ .venv/bin/python -m venvstacks --help + + Usage: python -m venvstacks [OPTIONS] COMMAND [ARGS]... + + Lock, build, and publish Python virtual environment stacks. + + ╭─ Options ───────────────────────────────────────────────────────────────────────╮ + │ --help Show this message and exit. │ + ╰─────────────────────────────────────────────────────────────────────────────────╯ + ╭─ Commands ──────────────────────────────────────────────────────────────────────╮ + │ build Build (/lock/publish) Python virtual environment stacks. │ + │ local-export Export layer environments for Python virtual environment stacks. │ + │ lock Lock layer requirements for Python virtual environment stacks. │ + │ publish Publish layer archives for Python virtual environment stacks. │ + ╰─────────────────────────────────────────────────────────────────────────────────╯ + + +Code consistency checks +----------------------- + +The project source code is autoformatted and linted using :pypi:`ruff`. +It also uses :pypi:`mypy` in strict mode to statically check that Python APIs +are being accessed as expected. + +All of these commands can be invoked via tox: + +.. code-block:: console + + $ tox -e format + +.. code-block:: console + + $ tox -e lint + +.. code-block:: console + + $ tox -e typecheck + +.. note:: + + Avoid using ``# noqa`` comments to suppress these warnings - wherever + possible, warnings should be fixed instead. ``# noqa`` comments are + reserved for rare cases where the recommended style causes severe + readability problems, and there isn't a more explicit mechanism + (such as ``typing.cast``) to indicate which check is being skipped. + + ``# fmt: off/on`` and ``# fmt: skip`` comments may be used as needed + when the autoformatter makes readability worse instead of better + (for example, collapsing lists to a single line when they intentionally + cover multiple lines, or ) + + +Running tests locally +--------------------- + +The project's tests are written using the :pypi:`pytest` test framework and the +standard library's :mod:`unittest` module. :pypi:`tox` is used to automate the +setup and execution of these tests across multiple Python versions. + +Some of the tests build and deploy full environment stacks, which makes them +take a long time to run (5+ minutes for the sample project build and export, +even with fully cached dependencies). + +Local test runs will usually want to skip these slow tests: + +.. code-block:: console + + $ tox -m test -- -m "not slow" + +The example above runs tests against the default Python version configured in +``tox.ini``. You can also use other defined versions by specifying the target +environment directly: + +.. code-block:: console + + $ tox -e py3.11 -- -m "not slow" + +``tox`` has been configured to forward any additional arguments it is given to +``pytest`` (as shown in the examples). This enables the use of pytest's `rich CLI`_. +In particular, you can select tests using all the optionts that pytest provides: + +.. code-block:: console + + $ # Using file name + $ tox -m test -- tests/test_basics.py + $ # Using markers + $ tox -m test -- -m "not slow" + $ # Using keyword text search + $ tox -m test -- -k "lock and not publish" + +Additional notes on running and updating the tests can be found in the +`testing README file`_. + + +Tests with committed expected output +'''''''''''''''''''''''''''''''''''' + +The "sample project" test cases primarily work by checking that relocking and +rebuilding the sample project produces the same locked requirements +files and the same publication metadata. + +This means those test cases will fail when the expected output is changed +intentionally, such as choosing a new baseline date for the sample project +lockfiles, adding new fields to the expected metadata, or changing the +expected contents of the defined environment layers. + +PRs that modify the ``tests/expected-output-config.yml`` file will trigger +a GitHub workflows that checks all other tests pass, and then generates a +new PR targeting the triggering PR branch. The changes to the expected +output files can then be reviewed to confirm they match the expected +impact of the changes that were (for example, launch module changes +should only affect the hashes and sizes of the application layer +archives that include those launch modules). + +If the original PR is not correct, then it can be retriggered by +closing and reopening the PR once the relevants fixes have been +implemented. + + +Building Documentation +---------------------- + +pip's documentation is built using :pypi:`Sphinx`. The documentation is written +in reStructuredText. + +To build it locally, run: + +.. code-block:: console + + $ tox -e docs + +The built documentation can be found in the ``docs/_build`` folder. + +.. _`Getting Started`: https://pip.pypa.io/en/stable/development/getting-started/ +.. _`open an issue`: https://github.com/lmstudio/venvstacks/issues/new?title=Trouble+with+development+environment +.. _`rich CLI`: https://docs.pytest.org/en/stable/how-to/usage.html#specifying-which-tests-to-run +.. _`GitHub`: https://github.com/lmstudio/venvstacks +.. _`testing README file`: https://github.com/lmstudio-ai/venvstacks/blob/main/tests/README.md diff --git a/docs/glossary.rst b/docs/glossary.rst new file mode 100644 index 0000000..522634d --- /dev/null +++ b/docs/glossary.rst @@ -0,0 +1,67 @@ +Essential Terms and Concepts +============================ + +.. glossary:: + + archive + A packed environment layer for distribution and deployment. Contains + either a fully built base runtime environment :term:`layer`, or + else a built layered environment that depends on the other + layers specified in its metadata. + + environment + build environment + deployed environment + layered environment + A base runtime environment (built from a base runtime layer definition), + or a layered virtual environment (built from an application or framework + layer definition). + May be a build environment, or a deployed environment. + Deployed environments may be created either directly (via local export), + or indirectly (via archive creation and unpacking). + Exported environments and archive deployments contain slightly + different metadata (since there are no archive details in the + exported environment metadata). + + export + local export + Locally publishing an environment on the same machine, + skipping the archive-and-unpack step, and automatically + running the post-installation step. Primarily intended + to speed up development iteration cycles when testing + stack builds and application layer launch modules, but may + also be used to export environments that normally use symlinks + to target filesystems which don't support them (such as USB keys). + (Note that transferring USB keys between systems is still likely + to run into problems related to absolute paths no longer being + correct, as Windows drive letters and POSIX mount points are + highly likely to differ across machines). + + layer + application layer + base runtime layer + framework layer + A definition of a set of Python requirements which will be pinned + for building and publication as a single consolidated :term:`archive`. + Layer definitions are categorised as follows: + + * *base runtime layers*: these layers specify a base Python runtime which + is used as a foundation for one or more environment stacks. Any + requirements specified as part of a base runtime layer are installed + directly into the base runtime (there is no virtual environment defined). + * *framework layers*: these layers primarily contain large dependencies + (such as :pypi:`pytorch`) which should not be published multiple times, + even when they are used by multiple applications. Applications are + constrained to use the versions of any packages installed in the + framework layers they depend on. Each framework layer depends on a + specific runtime layer. + * *application layers*: these layers specify the actual deployed Python + applications which embedding applications will invoke. Applications + depend on one or more framework layers + + stack + environment stack + An application layer with its supporting framework and base runtime layers. + + stack specification + A ``venvstacks.toml`` file that definez one or more environment stacks. diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..1177a79 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,15 @@ +.. venvstacks documentation master file, created by + sphinx-quickstart on Mon Oct 21 20:08:31 2024. + +====================================== +Welcome to venvstacks's documentation! +====================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + overview + glossary + api/index + development/index diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..32bb245 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/overview.rst b/docs/overview.rst new file mode 100644 index 0000000..8fb5b59 --- /dev/null +++ b/docs/overview.rst @@ -0,0 +1,4 @@ +Layered Virtual Environment Stacks +================================== + +TODO: Overview text... \ No newline at end of file diff --git a/docs/regen-api-docs.sh b/docs/regen-api-docs.sh new file mode 100755 index 0000000..241c285 --- /dev/null +++ b/docs/regen-api-docs.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# See http://redsymbol.net/articles/unofficial-bash-strict-mode/ for benefit of these options +set -euo pipefail +IFS=$'\n\t' + +echo "API docs regen disabled by default (as it overwrites existing edits)" +exit 1 + +# sphinx-autogen -o docs/api docs/api/venvstacks.*.rst diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..13cb5df --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,81 @@ +# This file is @generated by PDM. +# Please do not edit it manually. + +alabaster==1.0.0 +anyio==4.6.2.post1 +attrs==24.2.0 +babel==2.16.0 +beautifulsoup4==4.12.3 +blinker==1.8.2 +build==1.2.2.post1 +cachetools==5.5.0 +certifi==2024.8.30 +chardet==5.2.0 +charset-normalizer==3.4.0 +click==8.1.7 +colorama==0.4.6 +dep-logic==0.4.9 +distlib==0.3.9 +docutils==0.21.2 +filelock==3.16.1 +findpython==0.6.2 +furo==2024.8.6 +h11==0.14.0 +hishel==0.0.33 +httpcore==1.0.6 +httpx[socks]==0.27.2 +idna==3.10 +imagesize==1.4.1 +iniconfig==2.0.0 +installer==0.7.0 +jinja2==3.1.4 +markdown-it-py==3.0.0 +markupsafe==3.0.2 +mdurl==0.1.2 +msgpack==1.1.0 +mypy==1.12.1 +mypy-extensions==1.0.0 +packaging==24.1 +pbs-installer==2024.10.10 +pdm==2.19.3 +pip==24.2 +pip-tools==7.4.1 +platformdirs==4.3.6 +pluggy==1.5.0 +pygments==2.18.0 +pyproject-api==1.8.0 +pyproject-hooks==1.2.0 +pytest==8.3.3 +pytest-subtests==0.13.1 +python-dotenv==1.0.1 +requests==2.32.3 +resolvelib==1.0.1 +rich==13.9.2 +ruff==0.7.0 +setuptools==75.2.0 +shellingham==1.5.4 +sniffio==1.3.1 +snowballstemmer==2.2.0 +socksio==1.0.0 +soupsieve==2.6 +sphinx==8.1.3 +sphinx-basic-ng==1.0.0b2 +sphinxcontrib-applehelp==2.0.0 +sphinxcontrib-devhelp==2.0.0 +sphinxcontrib-htmlhelp==2.1.0 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==2.0.0 +sphinxcontrib-serializinghtml==2.0.0 +tomlkit==0.13.2 +tox==4.23.0 +tox-gh==1.4.4 +tox-pdm==0.7.2 +truststore==0.9.2 +typer-slim==0.12.5 +typing-extensions==4.12.2 +unearth==0.17.2 +urllib3==2.2.3 +uv==0.4.21 +virtualenv==20.27.0 +wheel==0.44.0 +-e . # this package diff --git a/lock_dev_venv.sh b/lock_dev_venv.sh index e0a7fc4..bd1a145 100755 --- a/lock_dev_venv.sh +++ b/lock_dev_venv.sh @@ -16,3 +16,7 @@ echo "Exported $ci_bootstrap_file" ci_constraints_file="ci-constraints.txt" pdm export --dev --no-extras -o "$ci_constraints_file" echo "Exported $ci_constraints_file" +# Export the docs build dependencies for the sphinx build +docs_requirements_file="docs/requirements.txt" +pdm export --dev --editable-self --no-hashes -o "$docs_requirements_file" +echo "Exported $docs_requirements_file" diff --git a/pdm.lock b/pdm.lock index 8bfda6e..2e58dcb 100644 --- a/pdm.lock +++ b/pdm.lock @@ -2,10 +2,10 @@ # It is not intended for manual editing. [metadata] -groups = ["default", "bootstrap", "dev", "git"] +groups = ["default", "bootstrap", "dev", "docs"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:33249953f549d76f22722b4a6287cfa47235e550ffdf44b4a9202cd38e9f9c37" +content_hash = "sha256:4282beefc4ca59510cc96299ef8d8d087145393f52982332332f43ad12843a3b" [[metadata.targets]] requires_python = ">=3.11" @@ -31,6 +31,17 @@ platform = "macos_12_0_x86_64" requires_python = ">=3.11" platform = "macos_12_0_arm64" +[[package]] +name = "alabaster" +version = "1.0.0" +requires_python = ">=3.10" +summary = "A light, configurable Sphinx theme" +groups = ["docs"] +files = [ + {file = "alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"}, + {file = "alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"}, +] + [[package]] name = "anyio" version = "4.6.2.post1" @@ -62,6 +73,34 @@ files = [ {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] +[[package]] +name = "babel" +version = "2.16.0" +requires_python = ">=3.8" +summary = "Internationalization utilities" +groups = ["docs"] +dependencies = [ + "pytz>=2015.7; python_version < \"3.9\"", +] +files = [ + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +requires_python = ">=3.6.0" +summary = "Screen-scraping library" +groups = ["docs"] +dependencies = [ + "soupsieve>1.2", +] +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + [[package]] name = "blinker" version = "1.8.2" @@ -107,7 +146,7 @@ name = "certifi" version = "2024.8.30" requires_python = ">=3.6" summary = "Python package for providing Mozilla's CA Bundle." -groups = ["default", "bootstrap"] +groups = ["default", "bootstrap", "docs"] files = [ {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, @@ -124,6 +163,32 @@ files = [ {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, ] +[[package]] +name = "charset-normalizer" +version = "3.4.0" +requires_python = ">=3.7.0" +summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +groups = ["docs"] +files = [ + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +] + [[package]] name = "click" version = "8.1.7" @@ -144,7 +209,7 @@ name = "colorama" version = "0.4.6" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" summary = "Cross-platform colored terminal text." -groups = ["default", "dev"] +groups = ["default", "dev", "docs"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -175,24 +240,14 @@ files = [ ] [[package]] -name = "dulwich" -version = "0.22.1" -requires_python = ">=3.7" -summary = "Python Git Library" -groups = ["git"] -dependencies = [ - "setuptools; python_version >= \"3.12\"", - "typing-extensions; python_version <= \"3.7\"", - "urllib3>=1.25", -] +name = "docutils" +version = "0.21.2" +requires_python = ">=3.9" +summary = "Docutils -- Python Documentation Utilities" +groups = ["docs"] files = [ - {file = "dulwich-0.22.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:82f26e592e9a36ab33bcdb419c7d53320e26c85dfc254cdb84f5f561a2fcaabf"}, - {file = "dulwich-0.22.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e90b8a2f24149c5803b733a24f1a016a2943b1f5a9ab2360db545e4638354c35"}, - {file = "dulwich-0.22.1-cp311-cp311-win_amd64.whl", hash = "sha256:a18d1392eabd02f337dcba23d723a4dcca87274ce8693cf88e6320f38bc3fdcd"}, - {file = "dulwich-0.22.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:12482e318895da9acabea7c0cc70b35d36833e7cb2def511ab3a63617f5c1af3"}, - {file = "dulwich-0.22.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dc42afedc8cda4f2fd15a06d2e9e41281074a02cdf31bb2e0dde4d80766a408"}, - {file = "dulwich-0.22.1-cp312-cp312-win_amd64.whl", hash = "sha256:9d19f04ecd4628a0e4587b4c4e98e040b87924c1362ae5aa27420435f05d5dd8"}, - {file = "dulwich-0.22.1.tar.gz", hash = "sha256:e36d85967cfbf25da1c7bc3d6921adc5baa976969d926aaf1582bd5fd7e94758"}, + {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"}, + {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"}, ] [[package]] @@ -208,7 +263,7 @@ files = [ [[package]] name = "findpython" -version = "0.6.1" +version = "0.6.2" requires_python = ">=3.8" summary = "A utility to find python versions on your system" groups = ["default", "bootstrap"] @@ -216,8 +271,25 @@ dependencies = [ "packaging>=20", ] files = [ - {file = "findpython-0.6.1-py3-none-any.whl", hash = "sha256:1fb4d709205de185b0561900267dfff64a841c910fe28d6038b2394ff925a81a"}, - {file = "findpython-0.6.1.tar.gz", hash = "sha256:56e52b409a92bcbd495cf981c85acf137f3b3e51cc769b46eba219bb1ab7533c"}, + {file = "findpython-0.6.2-py3-none-any.whl", hash = "sha256:bda62477f858ea623ef2269f5e734469a018104a5f6c0fd9317ba238464ddb76"}, + {file = "findpython-0.6.2.tar.gz", hash = "sha256:e0c75ba9f35a7f9bb4423eb31bd17358cccf15761b6837317719177aeff46723"}, +] + +[[package]] +name = "furo" +version = "2024.8.6" +requires_python = ">=3.8" +summary = "A clean customisable Sphinx documentation theme." +groups = ["docs"] +dependencies = [ + "beautifulsoup4", + "pygments>=2.7", + "sphinx-basic-ng>=1.0.0.beta2", + "sphinx<9.0,>=6.0", +] +files = [ + {file = "furo-2024.8.6-py3-none-any.whl", hash = "sha256:6cd97c58b47813d3619e63e9081169880fbe331f0ca883c871ff1f3f11814f5c"}, + {file = "furo-2024.8.6.tar.gz", hash = "sha256:b63e4cee8abfc3136d3bc03a3d45a76a850bada4d6374d24c1716b0e01394a01"}, ] [[package]] @@ -303,12 +375,23 @@ name = "idna" version = "3.10" requires_python = ">=3.6" summary = "Internationalized Domain Names in Applications (IDNA)" -groups = ["default", "bootstrap"] +groups = ["default", "bootstrap", "docs"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[[package]] +name = "imagesize" +version = "1.4.1" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +summary = "Getting image size from png/jpeg/jpeg2000/gif file" +groups = ["docs"] +files = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] + [[package]] name = "iniconfig" version = "2.0.0" @@ -331,6 +414,20 @@ files = [ {file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"}, ] +[[package]] +name = "jinja2" +version = "3.1.4" +requires_python = ">=3.7" +summary = "A very fast and expressive template engine." +groups = ["docs"] +dependencies = [ + "MarkupSafe>=2.0", +] +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + [[package]] name = "markdown-it-py" version = "3.0.0" @@ -345,6 +442,32 @@ files = [ {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, ] +[[package]] +name = "markupsafe" +version = "3.0.2" +requires_python = ">=3.9" +summary = "Safely add untrusted strings to HTML/XML markup." +groups = ["docs"] +files = [ + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -383,7 +506,7 @@ files = [ [[package]] name = "mypy" -version = "1.12.0" +version = "1.12.1" requires_python = ">=3.8" summary = "Optional static typing for Python" groups = ["dev"] @@ -393,23 +516,23 @@ dependencies = [ "typing-extensions>=4.6.0", ] files = [ - {file = "mypy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b86de37a0da945f6d48cf110d5206c5ed514b1ca2614d7ad652d4bf099c7de7"}, - {file = "mypy-1.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20c7c5ce0c1be0b0aea628374e6cf68b420bcc772d85c3c974f675b88e3e6e57"}, - {file = "mypy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a64ee25f05fc2d3d8474985c58042b6759100a475f8237da1f4faf7fcd7e6309"}, - {file = "mypy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:faca7ab947c9f457a08dcb8d9a8664fd438080e002b0fa3e41b0535335edcf7f"}, - {file = "mypy-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:5bc81701d52cc8767005fdd2a08c19980de9ec61a25dbd2a937dfb1338a826f9"}, - {file = "mypy-1.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8462655b6694feb1c99e433ea905d46c478041a8b8f0c33f1dab00ae881b2164"}, - {file = "mypy-1.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:923ea66d282d8af9e0f9c21ffc6653643abb95b658c3a8a32dca1eff09c06475"}, - {file = "mypy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ebf9e796521f99d61864ed89d1fb2926d9ab6a5fab421e457cd9c7e4dd65aa9"}, - {file = "mypy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e478601cc3e3fa9d6734d255a59c7a2e5c2934da4378f3dd1e3411ea8a248642"}, - {file = "mypy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:c72861b7139a4f738344faa0e150834467521a3fba42dc98264e5aa9507dd601"}, - {file = "mypy-1.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52b9e1492e47e1790360a43755fa04101a7ac72287b1a53ce817f35899ba0521"}, - {file = "mypy-1.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:48d3e37dd7d9403e38fa86c46191de72705166d40b8c9f91a3de77350daa0893"}, - {file = "mypy-1.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f106db5ccb60681b622ac768455743ee0e6a857724d648c9629a9bd2ac3f721"}, - {file = "mypy-1.12.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:233e11b3f73ee1f10efada2e6da0f555b2f3a5316e9d8a4a1224acc10e7181d3"}, - {file = "mypy-1.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:4ae8959c21abcf9d73aa6c74a313c45c0b5a188752bf37dace564e29f06e9c1b"}, - {file = "mypy-1.12.0-py3-none-any.whl", hash = "sha256:fd313226af375d52e1e36c383f39bf3836e1f192801116b31b090dfcd3ec5266"}, - {file = "mypy-1.12.0.tar.gz", hash = "sha256:65a22d87e757ccd95cbbf6f7e181e6caa87128255eb2b6be901bb71b26d8a99d"}, + {file = "mypy-1.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1230048fec1380faf240be6385e709c8570604d2d27ec6ca7e573e3bc09c3735"}, + {file = "mypy-1.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:02dcfe270c6ea13338210908f8cadc8d31af0f04cee8ca996438fe6a97b4ec66"}, + {file = "mypy-1.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5a437c9102a6a252d9e3a63edc191a3aed5f2fcb786d614722ee3f4472e33f6"}, + {file = "mypy-1.12.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:186e0c8346efc027ee1f9acf5ca734425fc4f7dc2b60144f0fbe27cc19dc7931"}, + {file = "mypy-1.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:673ba1140a478b50e6d265c03391702fa11a5c5aff3f54d69a62a48da32cb811"}, + {file = "mypy-1.12.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9fb83a7be97c498176fb7486cafbb81decccaef1ac339d837c377b0ce3743a7f"}, + {file = "mypy-1.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:389e307e333879c571029d5b93932cf838b811d3f5395ed1ad05086b52148fb0"}, + {file = "mypy-1.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94b2048a95a21f7a9ebc9fbd075a4fcd310410d078aa0228dbbad7f71335e042"}, + {file = "mypy-1.12.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ee5932370ccf7ebf83f79d1c157a5929d7ea36313027b0d70a488493dc1b179"}, + {file = "mypy-1.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:19bf51f87a295e7ab2894f1d8167622b063492d754e69c3c2fed6563268cb42a"}, + {file = "mypy-1.12.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d34167d43613ffb1d6c6cdc0cc043bb106cac0aa5d6a4171f77ab92a3c758bcc"}, + {file = "mypy-1.12.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:427878aa54f2e2c5d8db31fa9010c599ed9f994b3b49e64ae9cd9990c40bd635"}, + {file = "mypy-1.12.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5fcde63ea2c9f69d6be859a1e6dd35955e87fa81de95bc240143cf00de1f7f81"}, + {file = "mypy-1.12.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d54d840f6c052929f4a3d2aab2066af0f45a020b085fe0e40d4583db52aab4e4"}, + {file = "mypy-1.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:20db6eb1ca3d1de8ece00033b12f793f1ea9da767334b7e8c626a4872090cf02"}, + {file = "mypy-1.12.1-py3-none-any.whl", hash = "sha256:ce561a09e3bb9863ab77edf29ae3a50e65685ad74bba1431278185b7e5d5486e"}, + {file = "mypy-1.12.1.tar.gz", hash = "sha256:f5b3936f7a6d0e8280c9bdef94c7ce4847f5cdfc258fbb2c29a8c1711e8bb96d"}, ] [[package]] @@ -428,7 +551,7 @@ name = "packaging" version = "24.1" requires_python = ">=3.8" summary = "Core utilities for Python packages" -groups = ["default", "bootstrap", "dev"] +groups = ["default", "bootstrap", "dev", "docs"] files = [ {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, @@ -447,7 +570,7 @@ files = [ [[package]] name = "pdm" -version = "2.19.2" +version = "2.19.3" requires_python = ">=3.8" summary = "A modern Python package and dependency manager supporting the latest PEP standards" groups = ["default", "bootstrap"] @@ -477,8 +600,8 @@ dependencies = [ "virtualenv>=20", ] files = [ - {file = "pdm-2.19.2-py3-none-any.whl", hash = "sha256:42af4e0897b139656e003767e99c4f77014bf36d9a7b759d3e09b49ee5979143"}, - {file = "pdm-2.19.2.tar.gz", hash = "sha256:efb39264569181d0375536ef81c556648f16b540d429a53715730490a2283567"}, + {file = "pdm-2.19.3-py3-none-any.whl", hash = "sha256:80594e5d6167fb17ea724df09b68cdfe9c601ad7f218f1beea2c032b61bf30e9"}, + {file = "pdm-2.19.3.tar.gz", hash = "sha256:a9cc7f2078cd3b25ac645ffb5eca9d6b3d5dfcd788eaddfb6083432da71c97c2"}, ] [[package]] @@ -539,7 +662,7 @@ name = "pygments" version = "2.18.0" requires_python = ">=3.8" summary = "Pygments is a syntax highlighting package written in Python." -groups = ["default", "bootstrap"] +groups = ["default", "bootstrap", "docs"] files = [ {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, @@ -617,6 +740,23 @@ files = [ {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, ] +[[package]] +name = "requests" +version = "2.32.3" +requires_python = ">=3.8" +summary = "Python HTTP for Humans." +groups = ["docs"] +dependencies = [ + "certifi>=2017.4.17", + "charset-normalizer<4,>=2", + "idna<4,>=2.5", + "urllib3<3,>=1.21.1", +] +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + [[package]] name = "resolvelib" version = "1.0.1" @@ -645,28 +785,28 @@ files = [ [[package]] name = "ruff" -version = "0.6.9" +version = "0.7.0" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.6.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:140d4b5c9f5fc7a7b074908a78ab8d384dd7f6510402267bc76c37195c02a7ec"}, - {file = "ruff-0.6.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53fd8ca5e82bdee8da7f506d7b03a261f24cd43d090ea9db9a1dc59d9313914c"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa"}, - {file = "ruff-0.6.9-py3-none-win_amd64.whl", hash = "sha256:785d31851c1ae91f45b3d8fe23b8ae4b5170089021fbb42402d811135f0b7117"}, - {file = "ruff-0.6.9-py3-none-win_arm64.whl", hash = "sha256:a9641e31476d601f83cd602608739a0840e348bda93fec9f1ee816f8b6798b93"}, - {file = "ruff-0.6.9.tar.gz", hash = "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2"}, + {file = "ruff-0.7.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737"}, + {file = "ruff-0.7.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9"}, + {file = "ruff-0.7.0-py3-none-win_amd64.whl", hash = "sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2"}, + {file = "ruff-0.7.0-py3-none-win_arm64.whl", hash = "sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e"}, + {file = "ruff-0.7.0.tar.gz", hash = "sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b"}, ] [[package]] name = "setuptools" -version = "75.1.0" +version = "75.2.0" requires_python = ">=3.8" summary = "Easily download, build, install, upgrade, and uninstall Python packages" -groups = ["default", "git"] +groups = ["default"] files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, + {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, ] [[package]] @@ -691,6 +831,16 @@ files = [ {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] +[[package]] +name = "snowballstemmer" +version = "2.2.0" +summary = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +groups = ["docs"] +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] + [[package]] name = "socksio" version = "1.0.0" @@ -702,6 +852,127 @@ files = [ {file = "socksio-1.0.0.tar.gz", hash = "sha256:f88beb3da5b5c38b9890469de67d0cb0f9d494b78b106ca1845f96c10b91c4ac"}, ] +[[package]] +name = "soupsieve" +version = "2.6" +requires_python = ">=3.8" +summary = "A modern CSS selector implementation for Beautiful Soup." +groups = ["docs"] +files = [ + {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, + {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, +] + +[[package]] +name = "sphinx" +version = "8.1.3" +requires_python = ">=3.10" +summary = "Python documentation generator" +groups = ["docs"] +dependencies = [ + "Jinja2>=3.1", + "Pygments>=2.17", + "alabaster>=0.7.14", + "babel>=2.13", + "colorama>=0.4.6; sys_platform == \"win32\"", + "docutils<0.22,>=0.20", + "imagesize>=1.3", + "packaging>=23.0", + "requests>=2.30.0", + "snowballstemmer>=2.2", + "sphinxcontrib-applehelp>=1.0.7", + "sphinxcontrib-devhelp>=1.0.6", + "sphinxcontrib-htmlhelp>=2.0.6", + "sphinxcontrib-jsmath>=1.0.1", + "sphinxcontrib-qthelp>=1.0.6", + "sphinxcontrib-serializinghtml>=1.1.9", + "tomli>=2; python_version < \"3.11\"", +] +files = [ + {file = "sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2"}, + {file = "sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927"}, +] + +[[package]] +name = "sphinx-basic-ng" +version = "1.0.0b2" +requires_python = ">=3.7" +summary = "A modern skeleton for Sphinx themes." +groups = ["docs"] +dependencies = [ + "sphinx>=4.0", +] +files = [ + {file = "sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b"}, + {file = "sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9"}, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +requires_python = ">=3.9" +summary = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +groups = ["docs"] +files = [ + {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, + {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +requires_python = ">=3.9" +summary = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" +groups = ["docs"] +files = [ + {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, + {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +requires_python = ">=3.9" +summary = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +groups = ["docs"] +files = [ + {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, + {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +requires_python = ">=3.5" +summary = "A sphinx extension which renders display math in HTML via JavaScript" +groups = ["docs"] +files = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +requires_python = ">=3.9" +summary = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" +groups = ["docs"] +files = [ + {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, + {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +requires_python = ">=3.9" +summary = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" +groups = ["docs"] +files = [ + {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, + {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, +] + [[package]] name = "tomlkit" version = "0.13.2" @@ -715,7 +986,7 @@ files = [ [[package]] name = "tox" -version = "4.21.2" +version = "4.23.0" requires_python = ">=3.8" summary = "tox is a generic virtualenv management and test command line tool" groups = ["dev"] @@ -733,8 +1004,8 @@ dependencies = [ "virtualenv>=20.26.6", ] files = [ - {file = "tox-4.21.2-py3-none-any.whl", hash = "sha256:13d996adcd792e7c82994b0e116d85efd84f0c6d185254d83d156f73f86b2038"}, - {file = "tox-4.21.2.tar.gz", hash = "sha256:49381ff102296753e378fa5ff30e42a35e695f149b4dbf8a2c49d15fdb5797b2"}, + {file = "tox-4.23.0-py3-none-any.whl", hash = "sha256:46da40afb660e46238c251280eb910bdaf00b390c7557c8e4bb611f422e9db12"}, + {file = "tox-4.23.0.tar.gz", hash = "sha256:a6bd7d54231d755348d3c3a7b450b5bf6563833716d1299a1619587a1b77a3bf"}, ] [[package]] @@ -823,7 +1094,7 @@ name = "urllib3" version = "2.2.3" requires_python = ">=3.8" summary = "HTTP library with thread-safe connection pooling, file post, and more." -groups = ["git"] +groups = ["docs"] files = [ {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, @@ -846,8 +1117,8 @@ files = [ [[package]] name = "virtualenv" -version = "20.26.6" -requires_python = ">=3.7" +version = "20.27.0" +requires_python = ">=3.8" summary = "Virtual Python Environment builder" groups = ["default", "bootstrap", "dev"] dependencies = [ @@ -857,8 +1128,8 @@ dependencies = [ "platformdirs<5,>=3.9.1", ] files = [ - {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"}, - {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"}, + {file = "virtualenv-20.27.0-py3-none-any.whl", hash = "sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655"}, + {file = "virtualenv-20.27.0.tar.gz", hash = "sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index 86a2fa2..f28a85e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,13 +59,13 @@ dev = [ # Uses exact pin for dev as lock file regeneration is sensitive to the exact uv version "uv==0.4.21", ] -git = [ - # Used by `misc/add_lock_metadata.py` to generate missing lock metadata files - "dulwich>=0.22.1", -] bootstrap = [ "pdm>=2.16.1", ] +docs = [ + "sphinx>=8.1.3", + "furo>=2024.8.6", +] [tool.pytest.ini_options] # Allow skipping slow tests for local testing diff --git a/tests/README.md b/tests/README.md index e61a163..44fad74 100644 --- a/tests/README.md +++ b/tests/README.md @@ -20,19 +20,19 @@ Running checks locally Static analysis: - tox -e lint,typecheck + tox -m static -Full test suite (py3.11 testing is also defined): +Full test suite (using the default target Python version): - tox -e py3.12 + tox -m test Skip slow tests (options after `--` are passed to `pytest`): - tox -e py3.12 -- -m "not slow" + tox -m test -- -m "not slow" Specific tests (options after `--` are passed to `pytest`): - tox -e py3.12 -- -k test_minimal_project + tox -m test -- -k test_minimal_project Refer to https://docs.pytest.org/en/6.2.x/usage.html#specifying-tests-selecting-tests for additional details on how to select which tests to run. @@ -47,14 +47,28 @@ Tests which take more than a few seconds to run should be marked as slow: def test_locking_and_publishing(self) -> None: ... +Marking tests with committed output files +----------------------------------------- + +Some tests work by comparing freshly generated outputs with expected outputs +committed to the repository (usually locked requirements files and expected +artifact metadata files). + +Tests which work this way must be marked as defined expected outputs: + + @pytest.mark.slow + def test_locking_and_publishing(self) -> None: + ... + Updating metadata and examining built artifacts ----------------------------------------------- -To generate a full local build to update metadata or to debug failures: +To generate a full local sample project build to help debug failures: $ cd /path/to/repo/src/ - $ ../.venv/bin/python -m venvstacks build --publish ../tests/sample_project/venvstacks.toml ~/path/to/output/folder + $ ../.venv/bin/python -m venvstacks build --publish \ + ../tests/sample_project/venvstacks.toml ~/path/to/output/folder (use `../.venv/Scripts/python` on Windows) @@ -66,9 +80,9 @@ built artifacts from the running test suite: VENVSTACKS_EXPORT_TEST_ARTIFACTS="~/path/to/output/folder" VENVSTACKS_FORCE_TEST_EXPORT=1 -The test suite can then be executed via `tox -e py3.11` or `tox -e py3.12` (the generated -metadata and artifacts should be identical regardless of which version of Python is used -to run `venvstacks`). +The test suite can then be executed via `tox --m test` (the generated metadata and +artifacts should be identical regardless of which version of Python is used to run +`venvstacks`). If the forced export env var is not set or is set to the empty string, artifacts will only be exported when test cases fail. Forcing exports can be useful for generating reference @@ -81,6 +95,8 @@ reference artifacts for debugging purposes. Debugging test suite failures related to artifact reproducibility ----------------------------------------------------------------- -`diffoscope` is a very helpful utility when trying to track down artifact discrepancies -(only available for non-Windows systems, but can be used in WSL or another Linux environment -to examine artifacts produced on Windows). +[`diffoscope`](https://pypi.org/project/diffoscope/) is a very helpful utility +when trying to track down artifact discrepancies. + +While it is only available for non-Windows systems, it can be used in WSL or +another non-Windows environment to examine artifacts produced on Windows. diff --git a/tox.ini b/tox.ini index 06a64ab..dc66148 100644 --- a/tox.ini +++ b/tox.ini @@ -28,11 +28,32 @@ commands = ruff check --exclude 'tests/sample_project' {posargs} src/ tests/ misc/ [testenv:typecheck] -groups = dev,git +groups = dev allowlist_externals = mypy commands = mypy --strict --exclude 'tests/sample_project' {posargs} src/ tests/ misc/ +[testenv:docs] +groups = [] +deps = -r docs/requirements.txt +allowlist_externals = sphinx-build +commands = + sphinx-build -b dirhtml {posargs} docs/ docs/_build + +[testenv:linkcheck] +groups = [] +deps = -r docs/requirements.txt +allowlist_externals = sphinx-build +commands = + sphinx-build -b linkcheck {posargs} docs/ docs/_build + +[testenv:regen-api-docs] +groups = [] +deps = -r docs/requirements.txt +allowlist_externals = docs/regen-api-docs.sh +commands = + docs/regen-api-docs.sh + [gh] python = 3.11 = py3.11