diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-08-09 14:09:23 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-08-09 14:18:03 +0300 |
commit | fc4431b2298b392e5ab598032f69123586c808e1 (patch) | |
tree | c9f8f753f0726a88d40bedd49a7da4e5f05f9adb /contrib/python | |
parent | 65146091795a50027474976479e03e0b64f9dbda (diff) | |
download | ydb-fc4431b2298b392e5ab598032f69123586c808e1.tar.gz |
Intermediate changes
Diffstat (limited to 'contrib/python')
-rw-r--r-- | contrib/python/incremental/py3/.dist-info/METADATA | 126 | ||||
-rw-r--r-- | contrib/python/incremental/py3/.dist-info/entry_points.txt | 8 | ||||
-rw-r--r-- | contrib/python/incremental/py3/README.rst | 91 | ||||
-rw-r--r-- | contrib/python/incremental/py3/incremental/__init__.py | 322 | ||||
-rw-r--r-- | contrib/python/incremental/py3/incremental/_hatch.py | 37 | ||||
-rw-r--r-- | contrib/python/incremental/py3/incremental/_version.py | 2 | ||||
-rw-r--r-- | contrib/python/incremental/py3/incremental/update.py | 156 | ||||
-rw-r--r-- | contrib/python/incremental/py3/ya.make | 8 |
8 files changed, 509 insertions, 241 deletions
diff --git a/contrib/python/incremental/py3/.dist-info/METADATA b/contrib/python/incremental/py3/.dist-info/METADATA index c4a9409082..2bbcbfdc36 100644 --- a/contrib/python/incremental/py3/.dist-info/METADATA +++ b/contrib/python/incremental/py3/.dist-info/METADATA @@ -1,30 +1,29 @@ Metadata-Version: 2.1 Name: incremental -Version: 22.10.0 -Summary: "A small library that versions your Python projects." -Home-page: https://github.com/twisted/incremental -Maintainer: Amber Brown -Maintainer-email: hawkowl@twistedmatrix.com -License: MIT +Version: 24.7.0 +Summary: A small library that versions your Python projects. +Maintainer-email: Amber Brown <hawkowl@twistedmatrix.com> +Project-URL: Homepage, https://github.com/twisted/incremental +Project-URL: Documentation, https://twisted.org/incremental/docs/ +Project-URL: Issues, https://github.com/twisted/incremental/issues +Project-URL: Changelog, https://github.com/twisted/incremental/blob/trunk/NEWS.rst Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 +Classifier: Framework :: Hatch +Classifier: Framework :: Setuptools Plugin Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst License-File: LICENSE -Provides-Extra: mypy -Requires-Dist: click (>=6.0) ; extra == 'mypy' -Requires-Dist: twisted (>=16.4.0) ; extra == 'mypy' -Requires-Dist: mypy (==0.812) ; extra == 'mypy' +Requires-Dist: setuptools >=61.0 +Requires-Dist: tomli ; python_version < "3.11" Provides-Extra: scripts -Requires-Dist: click (>=6.0) ; extra == 'scripts' -Requires-Dist: twisted (>=16.4.0) ; extra == 'scripts' +Requires-Dist: click >=6.0 ; extra == 'scripts' Incremental =========== @@ -35,15 +34,84 @@ Incremental Incremental is a small library that versions your Python projects. -API documentation can be found `here <https://twisted.github.io/incremental/docs/>`_. +API documentation can be found `here <https://twisted.org/incremental/docs/>`_. +.. contents:: Quick Start ----------- -Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versioning arguments: +Using setuptools +~~~~~~~~~~~~~~~~ -.. code:: +Add Incremental to your ``pyproject.toml``: + +.. code-block:: toml + + [build-system] + requires = [ + "setuptools", + "incremental>=24.7.0", # ← Add incremental as a build dependency + ] + build-backend = "setuptools.build_meta" + + [project] + name = "<projectname>" + dynamic = ["version"] # ← Mark the version dynamic + dependencies = [ + "incremental>=24.7.0", # ← Depend on incremental at runtime + ] + # ... + + [tool.incremental] # ← Activate Incremental's setuptools plugin + +It's fine if the ``[tool.incremental]`` table is empty, but it must be present. + +Remove any ``[project] version =`` entry and any ``[tool.setuptools.dynamic] version =`` entry. + +Next, `initialize the project`_. + +Using Hatchling +~~~~~~~~~~~~~~~ + +If you're using `Hatchling <https://hatch.pypa.io/>`_ to package your project, +activate Incremental's Hatchling plugin by altering your ``pyproject.toml``: + +.. code:: toml + + [build-system] + requires = [ + "hatchling", + "incremental>=24.7.0", # ← Add incremental as a build dependency + ] + build-backend = "hatchling.build" + + [project] + name = "<projectname>" + dynamic = ["version"] # ← Mark the version dynamic + dependencies = [ + "incremental>=24.7.0", # ← Depend on incremental at runtime + ] + # ... + + [tool.hatch.version] + source = "incremental" # ← Activate Incremental's Hatchling plugin + +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). + +Next, `initialize the project`_. + + +Using ``setup.py`` +~~~~~~~~~~~~~~~~~~ + +Incremental may be used from ``setup.py`` instead of ``pyproject.toml``. +Add this to your ``setup()`` call, removing any other versioning arguments: + +.. code:: python setup( use_incremental=True, @@ -52,22 +120,27 @@ Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versionin ... } +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``. -It will create a file in your package named ``_version.py`` and look like this: +It will create a file in your package named ``_version.py`` like this: -.. code:: +.. code:: python from incremental import Version - __version__ = Version("widgetbox", 17, 1, 0) + __version__ = Version("<projectname>", 24, 1, 0) __all__ = ["__version__"] Then, so users of your project can find your version, in your root package's ``__init__.py`` add: -.. code:: +.. code:: python from ._version import __version__ @@ -75,6 +148,7 @@ Then, so users of your project can find your version, in your root package's ``_ Subsequent installations of your project will then use Incremental for versioning. + Incremental Versions -------------------- @@ -89,7 +163,7 @@ It is made up of the following elements (which are given during instantiation): You 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"``. -Calling ``repr()`` with a ``Version`` will give a Python-source-code representation of it, and calling ``str()`` with a ``Version`` will provide a string similar to ``'[Incremental, version 16.10.1]'``. +Calling ``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]'``. Updating diff --git a/contrib/python/incremental/py3/.dist-info/entry_points.txt b/contrib/python/incremental/py3/.dist-info/entry_points.txt index 1c7b4877c1..5e1e6d9974 100644 --- a/contrib/python/incremental/py3/.dist-info/entry_points.txt +++ b/contrib/python/incremental/py3/.dist-info/entry_points.txt @@ -1,2 +1,8 @@ [distutils.setup_keywords] -use_incremental = incremental:_get_version +use_incremental = incremental:_get_distutils_version + +[hatch] +incremental = incremental._hatch + +[setuptools.finalize_distribution_options] +incremental = incremental:_get_setuptools_version diff --git a/contrib/python/incremental/py3/README.rst b/contrib/python/incremental/py3/README.rst index 7a20d077af..56baba2fca 100644 --- a/contrib/python/incremental/py3/README.rst +++ b/contrib/python/incremental/py3/README.rst @@ -7,15 +7,84 @@ Incremental Incremental is a small library that versions your Python projects. -API documentation can be found `here <https://twisted.github.io/incremental/docs/>`_. +API documentation can be found `here <https://twisted.org/incremental/docs/>`_. +.. contents:: Quick Start ----------- -Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versioning arguments: +Using setuptools +~~~~~~~~~~~~~~~~ -.. code:: +Add Incremental to your ``pyproject.toml``: + +.. code-block:: toml + + [build-system] + requires = [ + "setuptools", + "incremental>=24.7.0", # ← Add incremental as a build dependency + ] + build-backend = "setuptools.build_meta" + + [project] + name = "<projectname>" + dynamic = ["version"] # ← Mark the version dynamic + dependencies = [ + "incremental>=24.7.0", # ← Depend on incremental at runtime + ] + # ... + + [tool.incremental] # ← Activate Incremental's setuptools plugin + +It's fine if the ``[tool.incremental]`` table is empty, but it must be present. + +Remove any ``[project] version =`` entry and any ``[tool.setuptools.dynamic] version =`` entry. + +Next, `initialize the project`_. + +Using Hatchling +~~~~~~~~~~~~~~~ + +If you're using `Hatchling <https://hatch.pypa.io/>`_ to package your project, +activate Incremental's Hatchling plugin by altering your ``pyproject.toml``: + +.. code:: toml + + [build-system] + requires = [ + "hatchling", + "incremental>=24.7.0", # ← Add incremental as a build dependency + ] + build-backend = "hatchling.build" + + [project] + name = "<projectname>" + dynamic = ["version"] # ← Mark the version dynamic + dependencies = [ + "incremental>=24.7.0", # ← Depend on incremental at runtime + ] + # ... + + [tool.hatch.version] + source = "incremental" # ← Activate Incremental's Hatchling plugin + +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). + +Next, `initialize the project`_. + + +Using ``setup.py`` +~~~~~~~~~~~~~~~~~~ + +Incremental may be used from ``setup.py`` instead of ``pyproject.toml``. +Add this to your ``setup()`` call, removing any other versioning arguments: + +.. code:: python setup( use_incremental=True, @@ -24,22 +93,27 @@ Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versionin ... } +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``. -It will create a file in your package named ``_version.py`` and look like this: +It will create a file in your package named ``_version.py`` like this: -.. code:: +.. code:: python from incremental import Version - __version__ = Version("widgetbox", 17, 1, 0) + __version__ = Version("<projectname>", 24, 1, 0) __all__ = ["__version__"] Then, so users of your project can find your version, in your root package's ``__init__.py`` add: -.. code:: +.. code:: python from ._version import __version__ @@ -47,6 +121,7 @@ Then, so users of your project can find your version, in your root package's ``_ Subsequent installations of your project will then use Incremental for versioning. + Incremental Versions -------------------- @@ -61,7 +136,7 @@ It is made up of the following elements (which are given during instantiation): You 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"``. -Calling ``repr()`` with a ``Version`` will give a Python-source-code representation of it, and calling ``str()`` with a ``Version`` will provide a string similar to ``'[Incremental, version 16.10.1]'``. +Calling ``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]'``. Updating diff --git a/contrib/python/incremental/py3/incremental/__init__.py b/contrib/python/incremental/py3/incremental/__init__.py index c0c06c0ae1..b10d5be033 100644 --- a/contrib/python/incremental/py3/incremental/__init__.py +++ b/contrib/python/incremental/py3/incremental/__init__.py @@ -9,44 +9,37 @@ See L{Version}. from __future__ import division, absolute_import +import os import sys import warnings -from typing import TYPE_CHECKING, Any, TypeVar, Union, Optional, Dict - -# -# Compat functions -# - -_T = TypeVar("_T", contravariant=True) +from typing import TYPE_CHECKING, Any, TypeVar, Union, Optional, Dict, BinaryIO +from dataclasses import dataclass if TYPE_CHECKING: + import io from typing_extensions import Literal from distutils.dist import Distribution as _Distribution -else: - _Distribution = object - -if sys.version_info > (3,): - - def _cmp(a, b): # type: (Any, Any) -> int - """ - Compare two objects. +# +# Compat functions +# - Returns a negative number if C{a < b}, zero if they are equal, and a - positive number if C{a > b}. - """ - if a < b: - return -1 - elif a == b: - return 0 - else: - return 1 +def _cmp(a, b): # type: (Any, Any) -> int + """ + Compare two objects. -else: - _cmp = cmp # noqa: F821 + Returns a negative number if C{a < b}, zero if they are equal, and a + positive number if C{a > b}. + """ + if a < b: + return -1 + elif a == b: + return 0 + else: + return 1 # @@ -71,19 +64,17 @@ class _Inf(object): return 0 return 1 - if sys.version_info >= (3,): - - def __lt__(self, other): # type: (object) -> bool - return self.__cmp__(other) < 0 + def __lt__(self, other): # type: (object) -> bool + return self.__cmp__(other) < 0 - def __le__(self, other): # type: (object) -> bool - return self.__cmp__(other) <= 0 + def __le__(self, other): # type: (object) -> bool + return self.__cmp__(other) <= 0 - def __gt__(self, other): # type: (object) -> bool - return self.__cmp__(other) > 0 + def __gt__(self, other): # type: (object) -> bool + return self.__cmp__(other) > 0 - def __ge__(self, other): # type: (object) -> bool - return self.__cmp__(other) >= 0 + def __ge__(self, other): # type: (object) -> bool + return self.__cmp__(other) >= 0 _inf = _Inf() @@ -167,7 +158,7 @@ class Version(object): "Version.release_candidate instead.", DeprecationWarning, stacklevel=2, - ), + ) return self.release_candidate def public(self): # type: () -> str @@ -187,7 +178,7 @@ class Version(object): if self.release_candidate is None: rc = "" else: - rc = ".rc%s" % (self.release_candidate,) + rc = "rc%s" % (self.release_candidate,) if self.post is None: post = "" @@ -206,7 +197,6 @@ class Version(object): local = public def __repr__(self): # type: () -> str - if self.release_candidate is None: release_candidate = "" else: @@ -236,7 +226,7 @@ class Version(object): def __str__(self): # type: () -> str return "[%s, version %s]" % (self.package, self.short()) - def __cmp__(self, other): # type: (Version) -> int + def __cmp__(self, other): # type: (object) -> int """ Compare two versions, considering major versions, minor versions, micro versions, then release candidates, then postreleases, then dev @@ -310,43 +300,41 @@ class Version(object): ) return x - if sys.version_info >= (3,): - - def __eq__(self, other): # type: (Any) -> bool - c = self.__cmp__(other) - if c is NotImplemented: - return c # type: ignore[return-value] - return c == 0 - - def __ne__(self, other): # type: (Any) -> bool - c = self.__cmp__(other) - if c is NotImplemented: - return c # type: ignore[return-value] - return c != 0 - - def __lt__(self, other): # type: (Version) -> bool - c = self.__cmp__(other) - if c is NotImplemented: - return c # type: ignore[return-value] - return c < 0 - - def __le__(self, other): # type: (Version) -> bool - c = self.__cmp__(other) - if c is NotImplemented: - return c # type: ignore[return-value] - return c <= 0 - - def __gt__(self, other): # type: (Version) -> bool - c = self.__cmp__(other) - if c is NotImplemented: - return c # type: ignore[return-value] - return c > 0 - - def __ge__(self, other): # type: (Version) -> bool - c = self.__cmp__(other) - if c is NotImplemented: - return c # type: ignore[return-value] - return c >= 0 + def __eq__(self, other): # type: (object) -> bool + c = self.__cmp__(other) + if c is NotImplemented: + return c # type: ignore[return-value] + return c == 0 + + def __ne__(self, other): # type: (object) -> bool + c = self.__cmp__(other) + if c is NotImplemented: + return c # type: ignore[return-value] + return c != 0 + + def __lt__(self, other): # type: (object) -> bool + c = self.__cmp__(other) + if c is NotImplemented: + return c # type: ignore[return-value] + return c < 0 + + def __le__(self, other): # type: (object) -> bool + c = self.__cmp__(other) + if c is NotImplemented: + return c # type: ignore[return-value] + return c <= 0 + + def __gt__(self, other): # type: (object) -> bool + c = self.__cmp__(other) + if c is NotImplemented: + return c # type: ignore[return-value] + return c > 0 + + def __ge__(self, other): # type: (object) -> bool + c = self.__cmp__(other) + if c is NotImplemented: + return c # type: ignore[return-value] + return c >= 0 def getVersionString(version): # type: (Version) -> str @@ -360,36 +348,192 @@ def getVersionString(version): # type: (Version) -> str return result -def _get_version(dist, keyword, value): # type: (_Distribution, object, object) -> None +def _findPath(path, package): # type: (str, str) -> str """ - Get the version from the package listed in the Distribution. + Determine the package root directory. + + The result is one of: + + - src/{package} + - {package} + + Where {package} is downcased. + """ + src_dir = os.path.join(path, "src", package.lower()) + current_dir = os.path.join(path, package.lower()) + + if os.path.isdir(src_dir): + return src_dir + elif os.path.isdir(current_dir): + return current_dir + else: + raise ValueError( + "Can't find the directory of package {}: I looked in {} and {}".format( + package, src_dir, current_dir + ) + ) + + +def _existing_version(path): # type: (str) -> Version + """ + Load the current version from {path}/_version.py. + """ + version_info = {} # type: Dict[str, Version] + + versionpath = os.path.join(path, "_version.py") + with open(versionpath, "r") as f: + exec(f.read(), version_info) + + return version_info["__version__"] + + +def _get_setuptools_version(dist): # type: (_Distribution) -> None """ - if not value: + Setuptools integration: load the version from the working directory + + This function is registered as a setuptools.finalize_distribution_options + entry point [1]. It is a no-op unless there is a pyproject.toml containing + an empty [tool.incremental] section. + + @param dist: An empty C{setuptools.Distribution} instance to mutate. + + [1]: https://setuptools.pypa.io/en/latest/userguide/extension.html#customizing-distribution-options + """ + config = _load_pyproject_toml("./pyproject.toml") + if not config or not config.has_tool_incremental: return - from distutils.command import build_py + dist.metadata.version = _existing_version(config.path).public() + + +def _get_distutils_version(dist, keyword, value): # type: (_Distribution, object, object) -> None + """ + Distutils integration: get the version from the package listed in the Distribution. + + This function is invoked when a C{setup.py} calls C{setup(use_incremental=True)}. + + @see: https://setuptools.pypa.io/en/latest/userguide/extension.html#adding-arguments + """ + if not value: # use_incremental=False + return # pragma: no cover + + from setuptools.command import build_py # type: ignore sp_command = build_py.build_py(dist) sp_command.finalize_options() - for item in sp_command.find_all_modules(): # type: ignore[attr-defined] + for item in sp_command.find_all_modules(): if item[1] == "_version": - version_file = {} # type: Dict[str, Version] + package_path = os.path.dirname(item[2]) + dist.metadata.version = _existing_version(package_path).public() + return + + raise Exception("No _version.py found.") # pragma: no cover + + +def _load_toml(f): # type: (BinaryIO) -> Any + """ + Read the content of a TOML file. + """ + # This import is deferred to avoid a hard dependency on tomli + # when no pyproject.toml is present. + if sys.version_info > (3, 11): + import tomllib + else: + import tomli as tomllib + + return tomllib.load(f) + + +@dataclass(frozen=True) +class _IncrementalConfig: + """ + Configuration loaded from a ``pyproject.toml`` file. + """ + + has_tool_incremental: bool + """ + Does the pyproject.toml file contain a [tool.incremental] + section? This indicates that the package has explicitly + opted-in to Incremental versioning. + """ + + package: str + """The package name, capitalized as in the package metadata.""" + + path: str + """Path to the package root""" + + +def _load_pyproject_toml(toml_path): # type: (str) -> Optional[_IncrementalConfig] + """ + Load Incremental configuration from a ``pyproject.toml`` + + If the [tool.incremental] section is empty we take the project name + from the [project] section. Otherwise we require only a C{name} key + specifying the project name. Other keys are forbidden to allow future + extension and catch typos. + """ + try: + with open(toml_path, "rb") as f: + data = _load_toml(f) + except FileNotFoundError: + return None + + tool_incremental = _extract_tool_incremental(data) + + if tool_incremental is None or tool_incremental == {}: + try: + package = data["project"]["name"] + except KeyError: + raise ValueError("""\ +Couldn't extract the package name from pyproject.toml. Specify it like: + + [project] + name = "Foo" + +Or: + + [tool.incremental] + name = "Foo" +""") + elif tool_incremental.keys() == {"name"}: + package = tool_incremental["name"] + else: + raise ValueError("Unexpected key(s) in [tool.incremental]") + + if not isinstance(package, str): + raise TypeError( + "Package name must be a string, but found {}".format(type(package)) + ) + + return _IncrementalConfig( + has_tool_incremental=tool_incremental is not None, + package=package, + path=_findPath(os.path.dirname(toml_path), package), + ) + - with open(item[2]) as f: - exec(f.read(), version_file) +def _extract_tool_incremental(data): # type: (Dict[str, object]) -> Optional[Dict[str, object]] + if "tool" not in data: + return None + if not isinstance(data["tool"], dict): + raise ValueError("[tool] must be a table") + if "incremental" not in data["tool"]: + return None - dist.metadata.version = version_file["__version__"].public() - return None + tool_incremental = data["tool"]["incremental"] + if not isinstance(tool_incremental, dict): + raise ValueError("[tool.incremental] must be a table") - raise Exception("No _version.py found.") + return tool_incremental from ._version import __version__ # noqa: E402 def _setuptools_version(): # type: () -> str - return __version__.public() + return __version__.public() # pragma: no cover __all__ = ["__version__", "Version", "getVersionString"] diff --git a/contrib/python/incremental/py3/incremental/_hatch.py b/contrib/python/incremental/py3/incremental/_hatch.py new file mode 100644 index 0000000000..8d677c4b9d --- /dev/null +++ b/contrib/python/incremental/py3/incremental/_hatch.py @@ -0,0 +1,37 @@ +# Copyright (c) Twisted Matrix Laboratories. +# See LICENSE for details. + +import os +import shlex +from typing import Any, Dict, List, Type, TypedDict + +from hatchling.version.source.plugin.interface import VersionSourceInterface +from hatchling.plugin import hookimpl + +from incremental import _load_pyproject_toml, _existing_version + + +class _VersionData(TypedDict): + version: str + + +class IncrementalVersionSource(VersionSourceInterface): + PLUGIN_NAME = "incremental" + + def get_version_data(self) -> _VersionData: # type: ignore[override] + path = os.path.join(self.root, "./pyproject.toml") + config = _load_pyproject_toml(path) + assert config is not None, "Failed to read {}".format(path) + return {"version": _existing_version(config.path).public()} + + def set_version(self, version: str, version_data: Dict[Any, Any]) -> None: + raise NotImplementedError( + f"Run `python -m incremental.version --newversion" + f" {shlex.quote(version)}` to set the version.\n\n" + f" See `python -m incremental.version --help` for more options." + ) + + +@hookimpl +def hatch_register_version_source() -> List[Type[VersionSourceInterface]]: + return [IncrementalVersionSource] diff --git a/contrib/python/incremental/py3/incremental/_version.py b/contrib/python/incremental/py3/incremental/_version.py index 12cb1b8151..672cfb7961 100644 --- a/contrib/python/incremental/py3/incremental/_version.py +++ b/contrib/python/incremental/py3/incremental/_version.py @@ -7,5 +7,5 @@ Provides Incremental version information. from incremental import Version -__version__ = Version("Incremental", 22, 10, 0) +__version__ = Version("Incremental", 24, 7, 0) __all__ = ["__version__"] diff --git a/contrib/python/incremental/py3/incremental/update.py b/contrib/python/incremental/py3/incremental/update.py index 64a5cc84e7..f3e33ee003 100644 --- a/contrib/python/incremental/py3/incremental/update.py +++ b/contrib/python/incremental/py3/incremental/update.py @@ -6,53 +6,9 @@ from __future__ import absolute_import, division, print_function import click import os import datetime -from typing import TYPE_CHECKING, Dict, Optional, Callable, Iterable +from typing import Dict, Optional, Callable -from incremental import Version - -if TYPE_CHECKING: - from typing_extensions import Protocol - - class _ReadableWritable(Protocol): - def read(self): # type: () -> bytes - pass - - def write(self, v): # type: (bytes) -> object - pass - - def __enter__(self): # type: () -> _ReadableWritable - pass - - def __exit__(self, *args, **kwargs): # type: (object, object) -> Optional[bool] - pass - - # FilePath is missing type annotations - # https://twistedmatrix.com/trac/ticket/10148 - class FilePath(object): - def __init__(self, path): # type: (str) -> None - self.path = path - - def child(self, v): # type: (str) -> FilePath - pass - - def isdir(self): # type: () -> bool - pass - - def isfile(self): # type: () -> bool - pass - - def getContent(self): # type: () -> bytes - pass - - def open(self, mode): # type: (str) -> _ReadableWritable - pass - - def walk(self): # type: () -> Iterable[FilePath] - pass - - -else: - from twisted.python.filepath import FilePath +from incremental import Version, _findPath, _existing_version _VERSIONPY_TEMPLATE = '''""" Provides {package} version information. @@ -70,35 +26,6 @@ __all__ = ["__version__"] _YEAR_START = 2000 -def _findPath(path, package): # type: (str, str) -> FilePath - - cwd = FilePath(path) - - src_dir = cwd.child("src").child(package.lower()) - current_dir = cwd.child(package.lower()) - - if src_dir.isdir(): - return src_dir - elif current_dir.isdir(): - return current_dir - else: - raise ValueError( - "Can't find under `./src` or `./`. Check the " - "package name is right (note that we expect your " - "package name to be lower cased), or pass it using " - "'--path'." - ) - - -def _existing_version(path): # type: (FilePath) -> Version - version_info = {} # type: Dict[str, Version] - - with path.child("_version.py").open("r") as f: - exec(f.read(), version_info) - - return version_info["__version__"] - - def _run( package, # type: str path, # type: Optional[str] @@ -112,17 +39,14 @@ def _run( _getcwd=None, # type: Optional[Callable[[], str]] _print=print, # type: Callable[[object], object] ): # type: (...) -> None - if not _getcwd: _getcwd = os.getcwd if not _date: _date = datetime.date.today() - if type(package) != str: - package = package.encode("utf8") # type: ignore[assignment] - - _path = FilePath(path) if path else _findPath(_getcwd(), package) + if not path: + path = _findPath(_getcwd(), package) if ( newversion @@ -156,7 +80,7 @@ def _run( if newversion: from pkg_resources import parse_version - existing = _existing_version(_path) + existing = _existing_version(path) st_version = parse_version(newversion)._version # type: ignore[attr-defined] release = list(st_version.release) @@ -185,7 +109,7 @@ def _run( existing = v elif rc and not patch: - existing = _existing_version(_path) + existing = _existing_version(path) if existing.release_candidate: v = Version( @@ -199,7 +123,7 @@ def _run( v = Version(package, _date.year - _YEAR_START, _date.month, 0, 1) elif patch: - existing = _existing_version(_path) + existing = _existing_version(path) v = Version( package, existing.major, @@ -209,7 +133,7 @@ def _run( ) elif post: - existing = _existing_version(_path) + existing = _existing_version(path) if existing.post is None: _post = 0 @@ -219,7 +143,7 @@ def _run( v = Version(package, existing.major, existing.minor, existing.micro, post=_post) elif dev: - existing = _existing_version(_path) + existing = _existing_version(path) if existing.dev is None: _dev = 0 @@ -236,7 +160,7 @@ def _run( ) else: - existing = _existing_version(_path) + existing = _existing_version(path) if existing.release_candidate: v = Version(package, existing.major, existing.minor, existing.micro) @@ -254,41 +178,43 @@ def _run( _print("Updating codebase to %s" % (v.public())) - for x in _path.walk(): - - if not x.isfile(): - continue - - original_content = x.getContent() - content = original_content + for dirpath, dirnames, filenames in os.walk(path): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + with open(filepath, "rb") as f: + original_content = f.read() + content = original_content + + # Replace previous release_candidate calls to the new one + if existing.release_candidate: + content = content.replace( + existing_version_repr_bytes, version_repr_bytes + ) + content = content.replace( + (package.encode("utf8") + b" " + existing.public().encode("utf8")), + (package.encode("utf8") + b" " + v.public().encode("utf8")), + ) + + # Replace NEXT Version calls with the new one + content = content.replace(NEXT_repr_bytes, version_repr_bytes) + content = content.replace( + NEXT_repr_bytes.replace(b"'", b'"'), version_repr_bytes + ) - # Replace previous release_candidate calls to the new one - if existing.release_candidate: - content = content.replace(existing_version_repr_bytes, version_repr_bytes) + # Replace <package> NEXT with <package> <public> content = content.replace( - (package.encode("utf8") + b" " + existing.public().encode("utf8")), + package.encode("utf8") + b" NEXT", (package.encode("utf8") + b" " + v.public().encode("utf8")), ) - # Replace NEXT Version calls with the new one - content = content.replace(NEXT_repr_bytes, version_repr_bytes) - content = content.replace( - NEXT_repr_bytes.replace(b"'", b'"'), version_repr_bytes - ) - - # Replace <package> NEXT with <package> <public> - content = content.replace( - package.encode("utf8") + b" NEXT", - (package.encode("utf8") + b" " + v.public().encode("utf8")), - ) - - if content != original_content: - _print("Updating %s" % (x.path,)) - with x.open("w") as f: - f.write(content) + if content != original_content: + _print("Updating %s" % (filepath,)) + with open(filepath, "wb") as f: + f.write(content) - _print("Updating %s/_version.py" % (_path.path)) - with _path.child("_version.py").open("w") as f: + versionpath = os.path.join(path, "_version.py") + _print("Updating %s" % (versionpath,)) + with open(versionpath, "wb") as f: f.write( ( _VERSIONPY_TEMPLATE.format(package=package, version_repr=version_repr) diff --git a/contrib/python/incremental/py3/ya.make b/contrib/python/incremental/py3/ya.make index 57846dd33a..66ee789b70 100644 --- a/contrib/python/incremental/py3/ya.make +++ b/contrib/python/incremental/py3/ya.make @@ -2,19 +2,25 @@ PY3_LIBRARY() -VERSION(22.10.0) +VERSION(24.7.0) LICENSE(MIT) +PEERDIR( + contrib/python/setuptools +) + NO_LINT() NO_CHECK_IMPORTS( + incremental._hatch incremental.update ) PY_SRCS( TOP_LEVEL incremental/__init__.py + incremental/_hatch.py incremental/_version.py incremental/update.py ) |