{"id":13725090,"url":"https://github.com/twisted/incremental","last_synced_at":"2025-06-10T13:08:59.872Z","repository":{"id":48076130,"uuid":"47066144","full_name":"twisted/incremental","owner":"twisted","description":"A library for versioning your Python projects.","archived":false,"fork":false,"pushed_at":"2025-05-31T01:24:23.000Z","size":1377,"stargazers_count":141,"open_issues_count":7,"forks_count":22,"subscribers_count":15,"default_branch":"trunk","last_synced_at":"2025-06-01T20:05:08.699Z","etag":null,"topics":["python","versioning"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/twisted.png","metadata":{"files":{"readme":"README.rst","changelog":"NEWS.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-11-29T14:15:56.000Z","updated_at":"2025-05-31T01:24:26.000Z","dependencies_parsed_at":"2024-03-31T06:31:36.771Z","dependency_job_id":"f726bc29-af9b-45af-b5de-b1480476e634","html_url":"https://github.com/twisted/incremental","commit_stats":{"total_commits":178,"total_committers":12,"mean_commits":"14.833333333333334","dds":0.4943820224719101,"last_synced_commit":"19a308d70d72d0aa95380125988d60abb23b64e3"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twisted%2Fincremental","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twisted%2Fincremental/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twisted%2Fincremental/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twisted%2Fincremental/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/twisted","download_url":"https://codeload.github.com/twisted/incremental/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twisted%2Fincremental/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":258735176,"owners_count":22749487,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python","versioning"],"created_at":"2024-08-03T01:02:12.670Z","updated_at":"2025-06-10T13:08:59.825Z","avatar_url":"https://github.com/twisted.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"Incremental\n===========\n\n|pypi|\n|calver|\n|gha|\n|coverage|\n\nIncremental is a `CalVer \u003chttps://calver.org/\u003e`_ version manager supports the future.\n\nAPI documentation can be found `here \u003chttps://twisted.org/incremental/docs/\u003e`_.\nNarrative documentation follows.\n\n.. contents::\n\nTheory of Operation\n-------------------\n\n- A version number has the form YY.MM.PATCH.\n- If your project is named \"Shrubbery\", its code is found in ``shrubbery/`` or ``src/shrubbery/``.\n- Incremental stores your project's version number in ``{src/}shrubbery/_version.py``.\n- To update the version, run ``incremental update Shrubbery``, passing ``--rc`` and/or ``--patch`` as appropriate (see `Updating`_, below).\n- Changing the version also updates any `indeterminate versions`_ in your codebase, like \"Shrubbery NEXT\", so you can reference the upcoming release in documentation.\n  That's how Incremental supports the future.\n\n\nQuick Start\n-----------\n\nUsing setuptools\n~~~~~~~~~~~~~~~~\n\nAdd Incremental to your ``pyproject.toml``:\n\n.. code-block:: toml\n\n    [build-system]\n    requires = [\n        \"setuptools\",\n        \"incremental\u003e=24.7.2\",  # ← Add incremental as a build dependency\n    ]\n    build-backend = \"setuptools.build_meta\"\n\n    [project]\n    name = \"\u003cprojectname\u003e\"\n    dynamic = [\"version\"]       # ← Mark the version dynamic\n    dependencies = [\n        \"incremental\u003e=24.7.2\",  # ← Depend on incremental at runtime\n    ]\n    # ...\n\n    [tool.incremental]          # ← Activate Incremental's setuptools plugin\n\nIt's fine if the ``[tool.incremental]`` table is empty, but it must be present.\n\nRemove any ``[project] version =`` entry and any ``[tool.setuptools.dynamic] version =`` entry.\n\nNext, `initialize the project`_.\n\nUsing Hatchling\n~~~~~~~~~~~~~~~\n\nIf you're using `Hatchling \u003chttps://hatch.pypa.io/\u003e`_ to package your project,\nactivate Incremental's Hatchling plugin by altering your ``pyproject.toml``:\n\n.. code:: toml\n\n    [build-system]\n    requires = [\n        \"hatchling\",\n        \"incremental\u003e=24.7.2\",  # ← Add incremental as a build dependency\n    ]\n    build-backend = \"hatchling.build\"\n\n    [project]\n    name = \"\u003cprojectname\u003e\"\n    dynamic = [\"version\"]       # ← Mark the version dynamic\n    dependencies = [\n        \"incremental\u003e=24.7.2\",  # ← Depend on incremental at runtime\n    ]\n    # ...\n\n    [tool.hatch.version]\n    source = \"incremental\"      # ← Activate Incremental's Hatchling plugin\n\nIncremental can be configured as usual in an optional ``[tool.incremental]`` table.\n\nThe ``hatch version`` command will report the Incremental-managed version.\nUse the ``incremental update`` command to change the version (setting it with ``hatch version`` is not supported).\n\nNext, `initialize the project`_.\n\n\nUsing ``setup.py``\n~~~~~~~~~~~~~~~~~~\n\nIncremental may be used from ``setup.py`` instead of ``pyproject.toml``.\nAdd this to your ``setup()`` call, removing any other versioning arguments:\n\n.. code:: python\n\n   setup(\n       use_incremental=True,\n       setup_requires=['incremental'],\n       install_requires=['incremental'], # along with any other install dependencies\n       ...\n   }\n\nThen `initialize the project`_.\n\n\nInitialize the project\n~~~~~~~~~~~~~~~~~~~~~~\n\nInstall Incremental to your local environment with ``pipx install incremental``.\nThen run ``incremental update \u003cprojectname\u003e --create``.\nIt will create a file in your package named ``_version.py`` like this:\n\n.. code:: python\n\n   from incremental import Version\n\n   __version__ = Version(\"\u003cprojectname\u003e\", 24, 1, 0)\n   __all__ = [\"__version__\"]\n\n\nSubsequent installations of your project will then use Incremental for versioning.\n\n\nRuntime integration\n~~~~~~~~~~~~~~~~~~~\n\nYou may expose the ``incremental.Version`` from ``_version.py`` in your package's API.\nTo do so, add to your root package's ``__init__.py``:\n\n.. code:: python\n\n   from ._version import __version__\n\n.. note::\n\n    Providing a ``__version__`` attribute is falling out of fashion following the introduction of `importlib.metadata.version() \u003chttps://docs.python.org/3/library/importlib.metadata.html#distribution-versions\u003e`_ in Python 3.6, which can retrieve an installed package's version.\n\nIf you don't expose this object publicly, nor make use of it within your package,\nthen there is no need to depend on Incremental at runtime.\nYou can remove it from your project's ``dependencies`` array (or, in ``setup.py``, from ``install_requires``).\n\n\nIncremental Versions\n--------------------\n\n``incremental.Version`` is a class that represents a version of a given project.\nIt is made up of the following elements (which are given during instantiation):\n\n- ``package`` (required), the name of the package this ``Version`` represents.\n- ``major``, ``minor``, ``micro`` (all required), the X.Y.Z of your project's ``Version``.\n- ``release_candidate`` (optional), set to 0 or higher to mark this ``Version`` being of a release candidate (also sometimes called a \"prerelease\").\n- ``post`` (optional), set to 0 or higher to mark this ``Version`` as a postrelease.\n- ``dev`` (optional), set to 0 or higher to mark this ``Version`` as a development release.\n\nYou can extract a PEP-440 compatible version string by using the ``.public()`` method, which returns a ``str`` containing the full version. This is the version you should provide to users, or publicly use. An example output would be ``\"13.2.0\"``, ``\"17.1.2dev1\"``, or ``\"18.8.0rc2\"``.\n\nCalling ``repr()`` with a ``Version`` will give a Python-source-code representation of it, and calling ``str()`` on a ``Version`` produces a string like ``'[Incremental, version 16.10.1]'``.\n\n\nUpdating\n--------\n\nIncremental includes a tool to automate updating your Incremental-using project's version called ``incremental``.\nIt updates the ``_version.py`` file and automatically updates some uses of Incremental versions from an indeterminate version to the current one.\nIt requires ``click`` from PyPI.\n\n``incremental update \u003cprojectname\u003e`` will perform updates on that package.\nThe commands that can be given after that determine what the next version is.\n\n- ``--newversion=\u003cversion\u003e``, to set the project version to a fully-specified version (like 1.2.3, or 17.1.0dev1).\n- ``--rc``, to set the project version to ``\u003cyear-2000\u003e.\u003cmonth\u003e.0rc1`` if the current version is not a release candidate, or bump the release candidate number by 1 if it is.\n- ``--dev``, to set the project development release number to 0 if it is not a development release, or bump the development release number by 1 if it is.\n- ``--patch``, to increment the patch number of the release. This will also reset the release candidate number, pass ``--rc`` at the same time to increment the patch number and make it a release candidate.\n- ``--post``, to set the project postrelease number to 0 if it is not a postrelease, or bump the postrelease number by 1 if it is. This will also reset the release candidate and development release numbers.\n\nIf you give no arguments, it will strip the release candidate number, making it a \"full release\".\n\nIndeterminate Versions\n----------------------\n\nIncremental supports \"indeterminate\" versions, as a stand-in for the next \"full\" version. This can be used when the version which will be displayed to the end-user is unknown (for example \"introduced in\" or \"deprecated in\"). Incremental supports the following indeterminate versions:\n\n- ``Version(\"\u003cprojectname\u003e\", \"NEXT\", 0, 0)``\n- ``\u003cprojectname\u003e NEXT``\n\nWhen you run ``incremental update \u003cprojectname\u003e --rc``, these will be updated to real versions (assuming the target final version is 17.1.0):\n\n- ``Version(\"\u003cprojectname\u003e\", 17, 1, 0, release_candidate=1)``\n- ``\u003cprojectname\u003e 17.1.0rc1``\n\nOnce the final version is made, it will become:\n\n- ``Version(\"\u003cprojectname\u003e\", 17, 1, 0)``\n- ``\u003cprojectname\u003e 17.1.0``\n\n\n.. |pypi| image:: http://img.shields.io/pypi/v/incremental.svg\n    :alt: PyPI\n    :target: https://pypi.org/project/incremental/\n\n.. |calver| image:: https://img.shields.io/badge/calver-YY.MM.MICRO-22bfda.svg\n    :alt: calver: YY.MM.MICRO\n    :target: https://calver.org/\n\n.. |gha| image:: https://github.com/twisted/incremental/actions/workflows/tests.yaml/badge.svg\n    :alt: Tests\n    :target: https://github.com/twisted/incremental/actions/workflows/tests.yaml\n\n.. |coverage| image:: https://img.shields.io/badge/Coverage-100%25-green\n    :alt: Coverage: 100%\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwisted%2Fincremental","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftwisted%2Fincremental","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwisted%2Fincremental/lists"}