diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 0000000..f08ce6e --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,36 @@ +.. _changelog: + +--------- +Changelog +--------- + +.. note:: + + Until the Python API has stabilised, ``venvstacks`` is using + `ZeroVer `__ (starting from 0.1.0). + + Refer to the :ref:`version-numbering` for additional details + on the way releases are versioned. + + +Unreleased +========== + +See the fragment files in the `changelog.d directory`_. + +.. _changelog.d directory: https://github.com/lmstudio-ai/venvstacks/tree/master/changelog.d + + +.. scriv-insert-here + +.. _changelog-0.1.0rc1: + +0.1.0rc1 — 2024-10-29 +===================== + +Added +----- + +- Initial export of `venvstacks` from Project Amphibian. + +- Adopted ``scriv`` for ``CHANGELOG`` management. diff --git a/changelog.d/README.txt b/changelog.d/README.txt new file mode 100644 index 0000000..528bf4b --- /dev/null +++ b/changelog.d/README.txt @@ -0,0 +1 @@ +Unpublished CHANGELOG entries (managed via scriv) diff --git a/changelog.d/ghrel_template.md.j2 b/changelog.d/ghrel_template.md.j2 new file mode 100644 index 0000000..65cb742 --- /dev/null +++ b/changelog.d/ghrel_template.md.j2 @@ -0,0 +1,3 @@ +:arrow_right:  PyPI page: [ venvstacks {{version}}](https://pypi.org/project/venvstacks/{{version}}). + +{{body}} diff --git a/ci-bootstrap-requirements.txt b/ci-bootstrap-requirements.txt index 3efc673..080a4a2 100644 --- a/ci-bootstrap-requirements.txt +++ b/ci-bootstrap-requirements.txt @@ -111,6 +111,6 @@ typing-extensions==4.12.2 \ unearth==0.17.2 \ --hash=sha256:0b8a2afd3476f1ab6155fc579501ac47fffe43547d88a70e5a5b76a7fe6caa2c \ --hash=sha256:4d21af1238a583835fca156322f7225382e718cdcc42d6278050a88e605c4ad5 -virtualenv==20.27.0 \ - --hash=sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2 \ - --hash=sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655 +virtualenv==20.27.1 \ + --hash=sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba \ + --hash=sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4 diff --git a/ci-constraints.txt b/ci-constraints.txt index ce7f547..abe3b5a 100644 --- a/ci-constraints.txt +++ b/ci-constraints.txt @@ -49,6 +49,9 @@ charset-normalizer==3.4.0 \ click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de +click-log==0.4.0 \ + --hash=sha256:3970f8570ac54491237bcdb3d8ab5e3eef6c057df29f8c3d1151a51a9c23b975 \ + --hash=sha256:a43e394b528d52112af599f2fc9e4b7cf3c15f94e53581f74fa6867e68c91756 colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 @@ -229,6 +232,9 @@ ruff==0.7.1 \ --hash=sha256:79d3af9dca4c56043e738a4d6dd1e9444b6d6c10598ac52d146e331eb155a8ad \ --hash=sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4 \ --hash=sha256:f38c41fcde1728736b4eb2b18850f6d1e3eedd9678c914dede554a70d5241307 +scriv==1.5.1 \ + --hash=sha256:30ae9ff8d144f8e0cf394c4e1d379542f1b3823767642955b54ec40dc00b32b6 \ + --hash=sha256:a3adc657733b4124fcb54527a5f3daab0d3c300de82d0fd2b9b297b243151b78 shellingham==1.5.4 \ --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ --hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de @@ -302,6 +308,6 @@ uv==0.4.21 \ --hash=sha256:9dcddbb3b6e1662c6db41d63db539742450e2ce17d6c746329c016e3651bfb4a \ --hash=sha256:a1a9a126ce48f0f0893891adb5a9749220425169092f3e4da1216168736ac16d \ --hash=sha256:ba3e3b40cc1d5a980d36589775d6a7e4defa1b33e7e06423af0e395b8e4d9505 -virtualenv==20.27.0 \ - --hash=sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2 \ - --hash=sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655 +virtualenv==20.27.1 \ + --hash=sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba \ + --hash=sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4 diff --git a/docs/api/index.rst b/docs/api/index.rst index 924876c..490eb36 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -1,5 +1,6 @@ +---------- Python API -========== +---------- .. warning:: diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 0000000..565b052 --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1 @@ +.. include:: ../CHANGELOG.rst diff --git a/docs/conf.py b/docs/conf.py index 9bae84c..4b81529 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -48,6 +48,7 @@ intersphinx_mapping = { "py": ("https://docs.python.org/3", None), + "packaging": ("https://packaging.python.org/en/latest/", None), } diff --git a/docs/design.rst b/docs/design.rst index b170b4c..02666c8 100644 --- a/docs/design.rst +++ b/docs/design.rst @@ -1,5 +1,9 @@ +----------------- Design Discussion -================= +----------------- + +Project +======= Why does ``venvstacks`` exist? ------------------------------ @@ -37,7 +41,7 @@ environments, it doesn't refer to being able combine ``sys.path`` across multiple environments. Splitting environments into layers the way ``venvstacks`` does -really doesn't align well with the way the ``conda`` dependency +also doesn't align well with the way the ``conda`` dependency resolver works, so it ended up making more sense to design ``venvstacks`` to work with ``venv`` and ``pip``. @@ -47,6 +51,10 @@ archives were eliminated from consideration as they lacked the ability to readily share the large common framework components that feature heavily in the Python AI ecosystem across different applications. + +Technical +========= + Why use ``python-build-standalone`` for the base runtimes? ---------------------------------------------------------- diff --git a/docs/development/index.rst b/docs/development/index.rst index ff8a954..73422d5 100644 --- a/docs/development/index.rst +++ b/docs/development/index.rst @@ -1,7 +1,12 @@ .. _dev-guide: +----------- Development -=========== +----------- + + +Getting Started +=============== (With thanks to pip's `Getting Started`_ guide for the general structure here!) @@ -32,6 +37,29 @@ Given these tools, the default development environment can be set up and other commands executed as described below. +Changelog Entries +----------------- + +The ``venvstacks`` changelog is managed with :pypi:`scriv`. + +Entries are written in ``.rst`` format by default, so they +can use semantic references to the rest of the documentation. +However, ``.md`` fragments are entirely fine if internal +semantic links aren't needed. + +All changes which may affect ``venvstacks`` users should be +given a user facing changelog entry with ``scriv create``. + +Refer to the +`"per-user" settings `__ +in the ``scriv`` documentation for details on how to customise the +local behaviour of ``scriv create``. + +The project level ``scriv`` settings are stored in +``pyproject.toml`` (but the project largely relies on the default +settings) + + Running from the source tree ---------------------------- @@ -62,6 +90,22 @@ venvstacks can then be executed via the ``-m`` switch: │ publish Publish layer archives for Python virtual environment stacks. │ ╰─────────────────────────────────────────────────────────────────────────────────╯ +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. + +Automated Testing +================= Code consistency checks ----------------------- @@ -95,7 +139,7 @@ All of these commands can be invoked via tox: ``# 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 ) + cover multiple lines, or breaking alignment of end-of-line comments). Running tests locally @@ -183,19 +227,51 @@ closing and reopening the PR once the relevants fixes have been implemented. -Building Documentation +Release Management +================== + +.. _version-numbering: + +Version Numbering +----------------- + +Until the Python API has stabilised, ``venvstacks`` is using +`ZeroVer `__ (starting from 0.1.0). + +The versioning scheme to be used after the leading zero is +dropped has not yet been decided (see +:external+packaging:ref:`versioning` +for some of the options being considered). + +Except for when a release is being prepared, the nominal version on +``main`` will have ``.dev0`` appended to indicate it is not a +release build. + +Most releases are expected to be published directly without a prior +release candidate build, but one may be used if it is deemed +necessary (for example, ``0.1.0rc1`` was published in order to +test the release pipeline prior to publishing ``0.1.0``). + + +Preparing New Releases ---------------------- -pip's documentation is built using :pypi:`Sphinx`. The documentation is written -in reStructuredText. +Prior to release: -To build it locally, run: +* Update the version in ``pyproject.toml`` to remove the pre-release suffix +* Run ``scriv collect`` to update ``CHANGELOG.rst`` +* Create a PR for the collected change log updates +* Check the updated docs after the PR has been merged -.. code-block:: console +Release (requires ``pandoc``): - $ tox -e docs +* Run ``scriv github-release --dry-run`` to check what would be published +* Run ``scriv github-release`` to make the release tag -The built documentation can be found in the ``docs/_build`` folder. +After release: + +* Check the release GitHub Action has published to PyPI correctly +* Bump the version in ``pyproject.toml`` and add a ``.dev0`` suffix .. _`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 diff --git a/docs/glossary.rst b/docs/glossary.rst index 522634d..618e433 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -1,5 +1,6 @@ +---------------------------- Essential Terms and Concepts -============================ +---------------------------- .. glossary:: diff --git a/docs/index.rst b/docs/index.rst index 06bc82c..1afcf6f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,3 +14,4 @@ Welcome to ``venvstacks``'s documentation! design api/index development/index + changelog diff --git a/docs/overview.rst b/docs/overview.rst index 6b8211d..3a61833 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -1,5 +1,6 @@ +---------------------------------- Layered Virtual Environment Stacks -================================== +---------------------------------- ``venvstacks`` uses Python's ``sitecustomize.py`` environment setup feature to chain together three layers of Python virtual environments: @@ -14,7 +15,7 @@ and the framework layers to share dependencies installed in the runtime layers. Installing ----------- +========== ``venvstacks`` is available from the :pypi:`Python Package Index `, and can be installed with :pypi:`pipx` (or similar tools): @@ -59,6 +60,9 @@ The command line help also provides additional usage information: :issue:`supported in a future release <26>`. +Working with environment stacks +=============================== + Defining environment stacks --------------------------- @@ -178,7 +182,7 @@ but the details related specifically to the published archive (such as its size contents hash) are necessarily omitted. Contributing to ``venvstacks`` development ------------------------------------------- +========================================== ``venvstacks`` is MIT Licensed and `developed on GitHub `__. diff --git a/docs/requirements.txt b/docs/requirements.txt index fba43bd..6853425 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -12,6 +12,7 @@ certifi==2024.8.30 chardet==5.2.0 charset-normalizer==3.4.0 click==8.1.7 +click-log==0.4.0 colorama==0.4.6 coverage[toml]==7.6.4 dep-logic==0.4.9 @@ -51,6 +52,7 @@ requests==2.32.3 resolvelib==1.0.1 rich==13.9.3 ruff==0.7.1 +scriv[toml]==1.5.1 shellingham==1.5.4 sniffio==1.3.1 snowballstemmer==2.2.0 @@ -74,5 +76,5 @@ typing-extensions==4.12.2 unearth==0.17.2 urllib3==2.2.3 uv==0.4.21 -virtualenv==20.27.0 +virtualenv==20.27.1 . # this package diff --git a/pdm.lock b/pdm.lock index 41bd8d7..5f7543e 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "bootstrap", "dev", "docs"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:b87d49f37d3f661dbd8fc83049b4430eaa012c35b3de694fd1f309d371a7fd1e" +content_hash = "sha256:6aeecbbca3ae78365eaedbfdb879aac15904991e06a0edac3a51a347814071bd" [[metadata.targets]] requires_python = ">=3.11" @@ -128,7 +128,7 @@ name = "certifi" version = "2024.8.30" requires_python = ">=3.6" summary = "Python package for providing Mozilla's CA Bundle." -groups = ["default", "bootstrap", "docs"] +groups = ["default", "bootstrap", "dev", "docs"] files = [ {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, @@ -150,7 +150,7 @@ 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"] +groups = ["dev", "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"}, @@ -176,7 +176,7 @@ name = "click" version = "8.1.7" requires_python = ">=3.7" summary = "Composable command line interface toolkit" -groups = ["default"] +groups = ["default", "dev"] dependencies = [ "colorama; platform_system == \"Windows\"", "importlib-metadata; python_version < \"3.8\"", @@ -186,6 +186,19 @@ files = [ {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] +[[package]] +name = "click-log" +version = "0.4.0" +summary = "Logging integration for Click" +groups = ["dev"] +dependencies = [ + "click", +] +files = [ + {file = "click-log-0.4.0.tar.gz", hash = "sha256:3970f8570ac54491237bcdb3d8ab5e3eef6c057df29f8c3d1151a51a9c23b975"}, + {file = "click_log-0.4.0-py2.py3-none-any.whl", hash = "sha256:a43e394b528d52112af599f2fc9e4b7cf3c15f94e53581f74fa6867e68c91756"}, +] + [[package]] name = "colorama" version = "0.4.6" @@ -414,7 +427,7 @@ name = "idna" version = "3.10" requires_python = ">=3.6" summary = "Internationalized Domain Names in Applications (IDNA)" -groups = ["default", "bootstrap", "docs"] +groups = ["default", "bootstrap", "dev", "docs"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -458,7 +471,7 @@ name = "jinja2" version = "3.1.4" requires_python = ">=3.7" summary = "A very fast and expressive template engine." -groups = ["docs"] +groups = ["dev", "docs"] dependencies = [ "MarkupSafe>=2.0", ] @@ -472,7 +485,7 @@ name = "markdown-it-py" version = "3.0.0" requires_python = ">=3.8" summary = "Python port of markdown-it. Markdown parsing, done right!" -groups = ["default", "bootstrap"] +groups = ["default", "bootstrap", "dev"] dependencies = [ "mdurl~=0.1", ] @@ -486,7 +499,7 @@ name = "markupsafe" version = "3.0.2" requires_python = ">=3.9" summary = "Safely add untrusted strings to HTML/XML markup." -groups = ["docs"] +groups = ["dev", "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"}, @@ -512,7 +525,7 @@ name = "mdurl" version = "0.1.2" requires_python = ">=3.7" summary = "Markdown URL utilities" -groups = ["default", "bootstrap"] +groups = ["default", "bootstrap", "dev"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -764,7 +777,7 @@ name = "requests" version = "2.32.3" requires_python = ">=3.8" summary = "Python HTTP for Humans." -groups = ["docs"] +groups = ["dev", "docs"] dependencies = [ "certifi>=2017.4.17", "charset-normalizer<4,>=2", @@ -817,6 +830,39 @@ files = [ {file = "ruff-0.7.1.tar.gz", hash = "sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4"}, ] +[[package]] +name = "scriv" +version = "1.5.1" +summary = "Scriv changelog management tool" +groups = ["dev"] +dependencies = [ + "attrs", + "click", + "click-log", + "jinja2", + "markdown-it-py", + "requests", +] +files = [ + {file = "scriv-1.5.1-py2.py3-none-any.whl", hash = "sha256:a3adc657733b4124fcb54527a5f3daab0d3c300de82d0fd2b9b297b243151b78"}, + {file = "scriv-1.5.1.tar.gz", hash = "sha256:30ae9ff8d144f8e0cf394c4e1d379542f1b3823767642955b54ec40dc00b32b6"}, +] + +[[package]] +name = "scriv" +version = "1.5.1" +extras = ["toml"] +summary = "Scriv changelog management tool" +groups = ["dev"] +dependencies = [ + "scriv==1.5.1", + "tomli; python_version < \"3.11\"", +] +files = [ + {file = "scriv-1.5.1-py2.py3-none-any.whl", hash = "sha256:a3adc657733b4124fcb54527a5f3daab0d3c300de82d0fd2b9b297b243151b78"}, + {file = "scriv-1.5.1.tar.gz", hash = "sha256:30ae9ff8d144f8e0cf394c4e1d379542f1b3823767642955b54ec40dc00b32b6"}, +] + [[package]] name = "shellingham" version = "1.5.4" @@ -1102,7 +1148,7 @@ name = "urllib3" version = "2.2.3" requires_python = ">=3.8" summary = "HTTP library with thread-safe connection pooling, file post, and more." -groups = ["docs"] +groups = ["dev", "docs"] files = [ {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, @@ -1125,7 +1171,7 @@ files = [ [[package]] name = "virtualenv" -version = "20.27.0" +version = "20.27.1" requires_python = ">=3.8" summary = "Virtual Python Environment builder" groups = ["default", "bootstrap", "dev"] @@ -1136,6 +1182,6 @@ dependencies = [ "platformdirs<5,>=3.9.1", ] files = [ - {file = "virtualenv-20.27.0-py3-none-any.whl", hash = "sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655"}, - {file = "virtualenv-20.27.0.tar.gz", hash = "sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2"}, + {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, + {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, ] diff --git a/pyproject.toml b/pyproject.toml index 27d26d4..aa9f61a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,6 +70,7 @@ dev = [ "pbs-installer==2024.10.10", # Uses exact pin for dev as lock file regeneration is sensitive to the exact uv version "uv==0.4.21", + "scriv[toml]>=1.5.1", ] bootstrap = [ "pdm>=2.16.1", @@ -115,3 +116,7 @@ source = [ [tool.ruff] # Assume Python 3.11 target-version = "py311" + +[tool.scriv] +version = "literal: pyproject.toml: project.version" +ghrel_template = "file: ghrel_template.md.j2"