Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

incremental CLI script #113

Merged
merged 1 commit into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Theory of Operation
- A version number has the form YY.MM.PATCH.
- If your project is named "Shrubbery", its code is found in ``shrubbery/`` or ``src/shrubbery/``.
- Incremental stores your project's version number in ``{src/}shrubbery/_version.py``.
- To update the version, run ``python -m incremental.update Shrubbery``, passing ``--rc`` and/or ``--patch`` as appropriate (see `Updating`_, below).
- To update the version, run ``incremental update Shrubbery``, passing ``--rc`` and/or ``--patch`` as appropriate (see `Updating`_, below).
- Changing the version also updates any `indeterminate versions`_ in your codebase, like "Shrubbery NEXT", so you can reference the upcoming release in documentation.
That's how Incremental supports the future.

Expand Down Expand Up @@ -86,7 +86,7 @@ activate Incremental's Hatchling plugin by altering your ``pyproject.toml``:
Incremental can be configured as usual in an optional ``[tool.incremental]`` table.

The ``hatch version`` command will report the Incremental-managed version.
Use the ``python -m incremental.update`` command to change the version (setting it with ``hatch version`` is not supported).
Use the ``incremental update`` command to change the version (setting it with ``hatch version`` is not supported).

Next, `initialize the project`_.

Expand All @@ -112,8 +112,8 @@ Then `initialize the project`_.
Initialize the project
~~~~~~~~~~~~~~~~~~~~~~

Install Incremental to your local environment with ``pip install incremental[scripts]``.
Then run ``python -m incremental.update <projectname> --create``.
Install Incremental to your local environment with ``pipx install incremental``.
Then run ``incremental update <projectname> --create``.
It will create a file in your package named ``_version.py`` like this:

.. code:: python
Expand All @@ -124,15 +124,26 @@ It will create a file in your package named ``_version.py`` like this:
__all__ = ["__version__"]


Then, so users of your project can find your version, in your root package's ``__init__.py`` add:
Subsequent installations of your project will then use Incremental for versioning.


Runtime integration
~~~~~~~~~~~~~~~~~~~

You may expose the ``incremental.Version`` from ``_version.py`` in your package's API.
To do so, add to your root package's ``__init__.py``:

.. code:: python

from ._version import __version__

.. note::

Subsequent installations of your project will then use Incremental for versioning.
Providing a ``__version__`` attribute is falling out of fashion following the introduction of `importlib.metadata.version() <https://docs.python.org/3/library/importlib.metadata.html#distribution-versions>`_ in Python 3.6, which can retrieve an installed package's version.

If you don't expose this object publicly, nor make use of it within your package,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just asking ?

If you don't make use of incremental inside your package, what's the point of using incremental ?

I find that incremental is usefull to track NEXT version to make it easy to do relase candidates and autoamtically have the version updated in your codebase.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have it exactly right — in 2024 Incremental's value is:

  1. Managing CalVer versions
  2. Updating indeterminate versions within the codebase

I view the runtime API (incremental.Version) as a legacy feature. There's no need to remove or deprecate it (it's part of the public API of a bunch of Twisted packages, that would just cause churn) but I don't want to advise new users adopt it as a matter of course. importlib.metadata is a better solution.

Here I'm trying to rework the docs to emphasize the new way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's anything wrong with not caring about Version, but does importlib.metadata even provide a version object somewhere? It looks like it just returns strings.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, importlib.metadata is just strings AFAIK. There are use cases that only need strings, though, like displaying the versions of everything installed, so I think that's a reasonable way to scope it. If you want a Version of whatever flavor it's easy enough to parse the string.

then there is no need to depend on Incremental at runtime.
You can remove it from your project's ``dependencies`` array (or, in ``setup.py``, from ``install_requires``).


Incremental Versions
Expand All @@ -155,12 +166,12 @@ Calling ``repr()`` with a ``Version`` will give a Python-source-code representat
Updating
--------

Incremental includes a tool to automate updating your Incremental-using project's version called ``incremental.update``.
Incremental includes a tool to automate updating your Incremental-using project's version called ``incremental``.
It updates the ``_version.py`` file and automatically updates some uses of Incremental versions from an indeterminate version to the current one.
It requires ``click`` from PyPI.

``python -m incremental.update <projectname>`` will perform updates on that package.
The commands that can be given after that will determine what the next version is.
``incremental update <projectname>`` will perform updates on that package.
The commands that can be given after that determine what the next version is.

- ``--newversion=<version>``, to set the project version to a fully-specified version (like 1.2.3, or 17.1.0dev1).
- ``--rc``, to set the project version to ``<year-2000>.<month>.0rc1`` if the current version is not a release candidate, or bump the release candidate number by 1 if it is.
Expand All @@ -178,7 +189,7 @@ Incremental supports "indeterminate" versions, as a stand-in for the next "full"
- ``Version("<projectname>", "NEXT", 0, 0)``
- ``<projectname> NEXT``

When you run ``python -m incremental.update <projectname> --rc``, these will be updated to real versions (assuming the target final version is 17.1.0):
When you run ``incremental update <projectname> --rc``, these will be updated to real versions (assuming the target final version is 17.1.0):

- ``Version("<projectname>", 17, 1, 0, release_candidate=1)``
- ``<projectname> 17.1.0rc1``
Expand Down
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ dependencies = [

[project.optional-dependencies]
scripts = [
"click>=6.0",
# This extra remains for backwards compatibility.
]

[project.urls]
Expand All @@ -45,6 +45,9 @@ Documentation = "https://twisted.org/incremental/docs/"
Issues = "https://github.com/twisted/incremental/issues"
Changelog = "https://github.com/twisted/incremental/blob/trunk/NEWS.rst"

[project.scripts]
incremental = "incremental.update:_main"

[project.entry-points."distutils.setup_keywords"]
use_incremental = "incremental:_get_distutils_version"
[project.entry-points."setuptools.finalize_distribution_options"]
Expand Down
6 changes: 4 additions & 2 deletions src/incremental/_hatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ def get_version_data(self) -> _VersionData: # type: ignore[override]
return {"version": _existing_version(config.version_path).public()}

def set_version(self, version: str, version_data: Dict[Any, Any]) -> None:
path = os.path.join(self.root, "./pyproject.toml") # TODO: #111 Delete this.
config = _load_pyproject_toml(path)
raise NotImplementedError(
f"Run `python -m incremental.version --newversion"
f"Run `incremental update {shlex.quote(config.package)} --newversion"
f" {shlex.quote(version)}` to set the version.\n\n"
f" See `python -m incremental.version --help` for more options."
f" See `incremental --help` for more options."
)


Expand Down
2 changes: 2 additions & 0 deletions src/incremental/newsfragments/99.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Incremental now provides a CLI script, ``incremental``, allowing you to run it with ``pipx run incremental``.
The ``incremental update`` subcommand offers the same functionality as ``python -m incremental.update``.
2 changes: 2 additions & 0 deletions src/incremental/newsfragments/99.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Incremental's CLI no longer depends on Click, so you no longer need to install ``incremental[scripts]`` for it to function.
The ``scripts`` extra is deprecated.
Loading