././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1665819619.2449765 incremental-22.10.0/0000755000076500000240000000000014322461743013231 5ustar00glyphstaff././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1664918161.0 incremental-22.10.0/.coveragerc0000644000076500000240000000042214317121221015334 0ustar00glyphstaff[run] # List of package names. source_pkgs = incremental # List of directory names. source = tests branch = True [paths] source = src/ .tox/*/lib/python*/site-packages/ .tox/pypy*/site-packages/ [report] exclude_lines = pragma: no cover if TYPE_CHECKING: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1557354603.0 incremental-22.10.0/LICENSE0000644000076500000240000000363113464654153014246 0ustar00glyphstaffIncremental ----------- This project includes code from the Twisted Project, which is licensed as below. Copyright (c) 2001-2015 Allen Short Amber Hawkie Brown Andrew Bennetts Andy Gayton Antoine Pitrou Apple Computer, Inc. Ashwini Oruganti Benjamin Bruheim Bob Ippolito Canonical Limited Christopher Armstrong David Reid Divmod Inc. Donovan Preston Eric Mangold Eyal Lotem Google Inc. Hybrid Logic Ltd. Hynek Schlawack Itamar Turner-Trauring James Knight Jason A. Mobarak Jean-Paul Calderone Jessica McKellar Jonathan D. Simms Jonathan Jacobs Jonathan Lange Julian Berman Jürgen Hermann Kevin Horn Kevin Turner Laurens Van Houtven Mary Gardiner Massachusetts Institute of Technology Matthew Lefkowitz Moshe Zadka Paul Swartz Pavel Pergamenshchik Rackspace, US Inc. Ralph Meijer Richard Wall Sean Riley Software Freedom Conservancy Tavendo GmbH Thijs Triemstra Thomas Herve Timothy Allen Tom Prince Travis B. Hartwell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1616468082.0 incremental-22.10.0/MANIFEST.in0000644000076500000240000000044414026254162014765 0ustar00glyphstaffinclude .coveragerc include LICENSE include NEWS.rst include towncrier.ini include tox.ini exclude mypy.ini include src/incremental/py.typed recursive-include src/incremental *.py prune .travis prune tests exclude examplesetup.py prune src/exampleproj prune src/incremental/newsfragments ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1665819494.0 incremental-22.10.0/NEWS.rst0000644000076500000240000000334614322461546014546 0ustar00glyphstaffIncremental 22.10.0 (2022-10-15) ================================ No significant changes. Incremental 22.10.0.rc1 (2022-10-04) ==================================== Features -------- - Incremental now supports type-checking with Mypy (#69) Incremental 21.3.0 (2021-03-01) =============================== Bugfixes -------- - The output of incremental is now compatible with Black (#56, #60) - Incremental now properly supports PEP 440-compliant dev, rc, post suffixes (#62) - Incremental now properly supports PEP 440-compliant post releases (#37) Incremental 17.5.0 (2017-05-20) =============================== Deprecations and Removals ------------------------- - Incremental will no longer attempt to read git or svn repositories to see if the project is running from a checkout. (#30, #31, #32) Incremental 16.10.1 (2016-10-20) ================================ Bugfixes -------- - Comparisons of Versions now compare the lowercased forms of both version packages, rather than being case sensitive. (#23) Incremental 16.10.0 (2016-10-10) ================================ Bugfixes -------- - incremental.update now adds a docstring to the autogenerated file. (#18) Misc ---- - #20 Incremental 16.9.1 (2016-09-21) =============================== Bugfixes -------- - python -m incremental.update --dev now starts a dev-less package at 0, not 1. (#15) Incremental 16.9.0 (2016-09-18) =============================== Features -------- - Incremental now uses 'rcX' instead of 'pre' for prereleases/release candidates, to match PEP440. (#4) - If you reference " NEXT" and use `python -m incremental.update`, it will automatically be updated to the next release version number. (#7) Misc ---- - #1, #10 ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1665819619.245026 incremental-22.10.0/PKG-INFO0000644000076500000240000001323314322461743014330 0ustar00glyphstaffMetadata-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 Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 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 Provides-Extra: scripts Provides-Extra: mypy License-File: LICENSE Incremental =========== |gha| |pypi| |coverage| Incremental is a small library that versions your Python projects. API documentation can be found `here `_. Quick Start ----------- Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versioning arguments: .. code:: setup( use_incremental=True, setup_requires=['incremental'], install_requires=['incremental'], # along with any other install dependencies ... } Install Incremental to your local environment with ``pip install incremental[scripts]``. Then run ``python -m incremental.update --create``. It will create a file in your package named ``_version.py`` and look like this: .. code:: from incremental import Version __version__ = Version("widgetbox", 17, 1, 0) __all__ = ["__version__"] Then, so users of your project can find your version, in your root package's ``__init__.py`` add: .. code:: from ._version import __version__ Subsequent installations of your project will then use Incremental for versioning. Incremental Versions -------------------- ``incremental.Version`` is a class that represents a version of a given project. It is made up of the following elements (which are given during instantiation): - ``package`` (required), the name of the package this ``Version`` represents. - ``major``, ``minor``, ``micro`` (all required), the X.Y.Z of your project's ``Version``. - ``release_candidate`` (optional), set to 0 or higher to mark this ``Version`` being of a release candidate (also sometimes called a "prerelease"). - ``post`` (optional), set to 0 or higher to mark this ``Version`` as a postrelease. - ``dev`` (optional), set to 0 or higher to mark this ``Version`` as a development release. 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]'``. Updating -------- Incremental includes a tool to automate updating your Incremental-using project's version called ``incremental.update``. 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 `` will perform updates on that package. The commands that can be given after that will determine what the next version is. - ``--newversion=``, 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 ``..0rc1`` if the current version is not a release candidate, or bump the release candidate number by 1 if it is. - ``--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. - ``--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. - ``--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. If you give no arguments, it will strip the release candidate number, making it a "full release". Incremental 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: - ``Version("", "NEXT", 0, 0)`` - `` NEXT`` When you run ``python -m incremental.update --rc``, these will be updated to real versions (assuming the target final version is 17.1.0): - ``Version("", 17, 1, 0, release_candidate=1)`` - `` 17.1.0rc1`` Once the final version is made, it will become: - ``Version("", 17, 1, 0)`` - `` 17.1.0`` .. |coverage| image:: https://codecov.io/gh/twisted/incremental/branch/master/graph/badge.svg?token=K2ieeL887X .. _coverage: https://codecov.io/gh/twisted/incremental .. |gha| image:: https://github.com/twisted/incremental/actions/workflows/tests.yaml/badge.svg .. _gha: https://github.com/twisted/incremental/actions/workflows/tests.yaml .. |pypi| image:: http://img.shields.io/pypi/v/incremental.svg .. _pypi: https://pypi.python.org/pypi/incremental ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1664918161.0 incremental-22.10.0/README.rst0000644000076500000240000001147714317121221014716 0ustar00glyphstaffIncremental =========== |gha| |pypi| |coverage| Incremental is a small library that versions your Python projects. API documentation can be found `here `_. Quick Start ----------- Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versioning arguments: .. code:: setup( use_incremental=True, setup_requires=['incremental'], install_requires=['incremental'], # along with any other install dependencies ... } Install Incremental to your local environment with ``pip install incremental[scripts]``. Then run ``python -m incremental.update --create``. It will create a file in your package named ``_version.py`` and look like this: .. code:: from incremental import Version __version__ = Version("widgetbox", 17, 1, 0) __all__ = ["__version__"] Then, so users of your project can find your version, in your root package's ``__init__.py`` add: .. code:: from ._version import __version__ Subsequent installations of your project will then use Incremental for versioning. Incremental Versions -------------------- ``incremental.Version`` is a class that represents a version of a given project. It is made up of the following elements (which are given during instantiation): - ``package`` (required), the name of the package this ``Version`` represents. - ``major``, ``minor``, ``micro`` (all required), the X.Y.Z of your project's ``Version``. - ``release_candidate`` (optional), set to 0 or higher to mark this ``Version`` being of a release candidate (also sometimes called a "prerelease"). - ``post`` (optional), set to 0 or higher to mark this ``Version`` as a postrelease. - ``dev`` (optional), set to 0 or higher to mark this ``Version`` as a development release. 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]'``. Updating -------- Incremental includes a tool to automate updating your Incremental-using project's version called ``incremental.update``. 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 `` will perform updates on that package. The commands that can be given after that will determine what the next version is. - ``--newversion=``, 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 ``..0rc1`` if the current version is not a release candidate, or bump the release candidate number by 1 if it is. - ``--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. - ``--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. - ``--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. If you give no arguments, it will strip the release candidate number, making it a "full release". Incremental 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: - ``Version("", "NEXT", 0, 0)`` - `` NEXT`` When you run ``python -m incremental.update --rc``, these will be updated to real versions (assuming the target final version is 17.1.0): - ``Version("", 17, 1, 0, release_candidate=1)`` - `` 17.1.0rc1`` Once the final version is made, it will become: - ``Version("", 17, 1, 0)`` - `` 17.1.0`` .. |coverage| image:: https://codecov.io/gh/twisted/incremental/branch/master/graph/badge.svg?token=K2ieeL887X .. _coverage: https://codecov.io/gh/twisted/incremental .. |gha| image:: https://github.com/twisted/incremental/actions/workflows/tests.yaml/badge.svg .. _gha: https://github.com/twisted/incremental/actions/workflows/tests.yaml .. |pypi| image:: http://img.shields.io/pypi/v/incremental.svg .. _pypi: https://pypi.python.org/pypi/incremental ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1664918618.0 incremental-22.10.0/pyproject.toml0000644000076500000240000000047714317122132016143 0ustar00glyphstaff[build-system] requires = [ "setuptools >= 44.1.1", "wheel >= 0.36.2", "typing >= 3.7.4.3; python_version < '3.5'", ] build-backend = "setuptools.build_meta" [tool.black] target-version = ['py27', 'py36', 'py37', 'py38'] [tool.towncrier] filename = "NEWS.rst" package_dir = "src/" package = "incremental" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1665819619.245299 incremental-22.10.0/setup.cfg0000644000076500000240000000254414322461743015057 0ustar00glyphstaff[metadata] name = incremental version = attr: incremental._setuptools_version maintainer = Amber Brown maintainer_email = hawkowl@twistedmatrix.com url = https://github.com/twisted/incremental classifiers = Intended Audience :: Developers License :: OSI Approved :: MIT License Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.4 Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 license = MIT description = "A small library that versions your Python projects." long_description = file: README.rst install_requires = setuptools typing >= 3.7.4.3; python_version < '3.5' [options] packages = find: package_dir = =src zip_safe = False [options.packages.find] where = src exclude = exampleproj [options.package_data] incremental = py.typed [options.entry_points] distutils.setup_keywords = use_incremental = incremental:_get_version [options.extras_require] scripts = click>=6.0 twisted>=16.4.0 mypy = %(scripts)s mypy==0.812 [bdist_wheel] universal = 1 [flake8] max-line-length = 88 extend-ignore = E203, # whitespace before : is not PEP8 compliant (& conflicts with black) [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1616468082.0 incremental-22.10.0/setup.py0000644000076500000240000000007614026254162014742 0ustar00glyphstafffrom setuptools import setup # type: ignore[import] setup() ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1665819619.241943 incremental-22.10.0/src/0000755000076500000240000000000014322461743014020 5ustar00glyphstaff././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1665819619.2436488 incremental-22.10.0/src/incremental/0000755000076500000240000000000014322461743016321 5ustar00glyphstaff././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1664918161.0 incremental-22.10.0/src/incremental/__init__.py0000644000076500000240000002552514317121221020427 0ustar00glyphstaff# Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. """ Versions for Python packages. See L{Version}. """ from __future__ import division, absolute_import import sys import warnings from typing import TYPE_CHECKING, Any, TypeVar, Union, Optional, Dict # # Compat functions # _T = TypeVar("_T", contravariant=True) if TYPE_CHECKING: 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. 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 else: _cmp = cmp # noqa: F821 # # Versioning # class _Inf(object): """ An object that is bigger than all other objects. """ def __cmp__(self, other): # type: (object) -> int """ @param other: Another object. @type other: any @return: 0 if other is inf, 1 otherwise. @rtype: C{int} """ if other is _inf: return 0 return 1 if sys.version_info >= (3,): 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 __gt__(self, other): # type: (object) -> bool return self.__cmp__(other) > 0 def __ge__(self, other): # type: (object) -> bool return self.__cmp__(other) >= 0 _inf = _Inf() class IncomparableVersions(TypeError): """ Two versions could not be compared. """ class Version(object): """ An encapsulation of a version for a project, with support for outputting PEP-440 compatible version strings. This class supports the standard major.minor.micro[rcN] scheme of versioning. """ def __init__( self, package, # type: str major, # type: Union[Literal["NEXT"], int] minor, # type: int micro, # type: int release_candidate=None, # type: Optional[int] prerelease=None, # type: Optional[int] post=None, # type: Optional[int] dev=None, # type: Optional[int] ): """ @param package: Name of the package that this is a version of. @type package: C{str} @param major: The major version number. @type major: C{int} or C{str} (for the "NEXT" symbol) @param minor: The minor version number. @type minor: C{int} @param micro: The micro version number. @type micro: C{int} @param release_candidate: The release candidate number. @type release_candidate: C{int} @param prerelease: The prerelease number. (Deprecated) @type prerelease: C{int} @param post: The postrelease number. @type post: C{int} @param dev: The development release number. @type dev: C{int} """ if release_candidate and prerelease: raise ValueError("Please only return one of these.") elif prerelease and not release_candidate: release_candidate = prerelease warnings.warn( "Passing prerelease to incremental.Version was " "deprecated in Incremental 16.9.0. Please pass " "release_candidate instead.", DeprecationWarning, stacklevel=2, ) if major == "NEXT": if minor or micro or release_candidate or post or dev: raise ValueError( "When using NEXT, all other values except Package must be 0." ) self.package = package self.major = major self.minor = minor self.micro = micro self.release_candidate = release_candidate self.post = post self.dev = dev @property def prerelease(self): # type: () -> Optional[int] warnings.warn( "Accessing incremental.Version.prerelease was " "deprecated in Incremental 16.9.0. Use " "Version.release_candidate instead.", DeprecationWarning, stacklevel=2, ), return self.release_candidate def public(self): # type: () -> str """ Return a PEP440-compatible "public" representation of this L{Version}. Examples: - 14.4.0 - 1.2.3rc1 - 14.2.1rc1dev9 - 16.04.0dev0 """ if self.major == "NEXT": return self.major if self.release_candidate is None: rc = "" else: rc = ".rc%s" % (self.release_candidate,) if self.post is None: post = "" else: post = ".post%s" % (self.post,) if self.dev is None: dev = "" else: dev = ".dev%s" % (self.dev,) return "%r.%d.%d%s%s%s" % (self.major, self.minor, self.micro, rc, post, dev) base = public short = public local = public def __repr__(self): # type: () -> str if self.release_candidate is None: release_candidate = "" else: release_candidate = ", release_candidate=%r" % (self.release_candidate,) if self.post is None: post = "" else: post = ", post=%r" % (self.post,) if self.dev is None: dev = "" else: dev = ", dev=%r" % (self.dev,) return "%s(%r, %r, %d, %d%s%s%s)" % ( self.__class__.__name__, self.package, self.major, self.minor, self.micro, release_candidate, post, dev, ) def __str__(self): # type: () -> str return "[%s, version %s]" % (self.package, self.short()) def __cmp__(self, other): # type: (Version) -> int """ Compare two versions, considering major versions, minor versions, micro versions, then release candidates, then postreleases, then dev releases. Package names are case insensitive. A version with a release candidate is always less than a version without a release candidate. If both versions have release candidates, they will be included in the comparison. Likewise, a version with a dev release is always less than a version without a dev release. If both versions have dev releases, they will be included in the comparison. @param other: Another version. @type other: L{Version} @return: NotImplemented when the other object is not a Version, or one of -1, 0, or 1. @raise IncomparableVersions: when the package names of the versions differ. """ if not isinstance(other, self.__class__): return NotImplemented if self.package.lower() != other.package.lower(): raise IncomparableVersions("%r != %r" % (self.package, other.package)) if self.major == "NEXT": major = _inf # type: Union[int, _Inf] else: major = self.major if self.release_candidate is None: release_candidate = _inf # type: Union[int, _Inf] else: release_candidate = self.release_candidate if self.post is None: post = -1 else: post = self.post if self.dev is None: dev = _inf # type: Union[int, _Inf] else: dev = self.dev if other.major == "NEXT": othermajor = _inf # type: Union[int, _Inf] else: othermajor = other.major if other.release_candidate is None: otherrc = _inf # type: Union[int, _Inf] else: otherrc = other.release_candidate if other.post is None: otherpost = -1 else: otherpost = other.post if other.dev is None: otherdev = _inf # type: Union[int, _Inf] else: otherdev = other.dev x = _cmp( (major, self.minor, self.micro, release_candidate, post, dev), (othermajor, other.minor, other.micro, otherrc, otherpost, otherdev), ) 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 getVersionString(version): # type: (Version) -> str """ Get a friendly string for the given version object. @param version: A L{Version} object. @return: A string containing the package and short version number. """ result = "%s %s" % (version.package, version.short()) return result def _get_version(dist, keyword, value): # type: (_Distribution, object, object) -> None """ Get the version from the package listed in the Distribution. """ if not value: return from distutils.command import build_py sp_command = build_py.build_py(dist) sp_command.finalize_options() for item in sp_command.find_all_modules(): # type: ignore[attr-defined] if item[1] == "_version": version_file = {} # type: Dict[str, Version] with open(item[2]) as f: exec(f.read(), version_file) dist.metadata.version = version_file["__version__"].public() return None raise Exception("No _version.py found.") from ._version import __version__ # noqa: E402 def _setuptools_version(): # type: () -> str return __version__.public() __all__ = ["__version__", "Version", "getVersionString"] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1665819487.0 incremental-22.10.0/src/incremental/_version.py0000644000076500000240000000042114322461537020515 0ustar00glyphstaff""" Provides Incremental version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update Incremental` to change this file. from incremental import Version __version__ = Version("Incremental", 22, 10, 0) __all__ = ["__version__"] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1616468082.0 incremental-22.10.0/src/incremental/py.typed0000644000076500000240000000000014026254162020002 0ustar00glyphstaff././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1665819619.2448635 incremental-22.10.0/src/incremental/tests/0000755000076500000240000000000014322461743017463 5ustar00glyphstaff././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1557354603.0 incremental-22.10.0/src/incremental/tests/__init__.py0000644000076500000240000000000013464654153021567 0ustar00glyphstaff././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1616468082.0 incremental-22.10.0/src/incremental/tests/test_update.py0000644000076500000240000010233214026254162022353 0ustar00glyphstaff# Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. """ Tests for L{incremental.update}. """ from __future__ import division, absolute_import import sys import os import datetime from twisted.python.filepath import FilePath from twisted.python.compat import NativeStringIO from twisted.trial.unittest import TestCase from incremental.update import _run, run class NonCreatedUpdateTests(TestCase): def setUp(self): self.srcdir = FilePath(self.mktemp()) self.srcdir.makedirs() packagedir = self.srcdir.child("inctestpkg") packagedir.makedirs() packagedir.child("__init__.py").setContent( b""" from incremental import Version introduced_in = Version("inctestpkg", "NEXT", 0, 0).short() next_released_version = "inctestpkg NEXT" """ ) self.getcwd = lambda: self.srcdir.path self.packagedir = packagedir class Date(object): year = 2016 month = 8 self.date = Date() def test_create(self): """ `incremental.update package --create` initialises the version. """ self.assertFalse(self.packagedir.child("_version.py").exists()) out = [] _run( "inctestpkg", path=None, newversion=None, patch=False, rc=False, post=False, dev=False, create=True, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertTrue(self.packagedir.child("_version.py").exists()) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 16, 8, 0) __all__ = ["__version__"] ''', ) class MissingTests(TestCase): def setUp(self): self.srcdir = FilePath(self.mktemp()) self.srcdir.makedirs() self.srcdir.child("srca").makedirs() packagedir = self.srcdir.child("srca").child("inctestpkg") packagedir.makedirs() packagedir.child("__init__.py").setContent( b""" from incremental import Version introduced_in = Version("inctestpkg", "NEXT", 0, 0).short() next_released_version = "inctestpkg NEXT" """ ) packagedir.child("_version.py").setContent( b""" from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3) __all__ = ["__version__"] """ ) self.getcwd = lambda: self.srcdir.path self.packagedir = packagedir class Date(object): year = 2016 month = 8 self.date = Date() def test_path(self): """ `incremental.update package --dev` raises and quits if it can't find the package. """ out = [] with self.assertRaises(ValueError): _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=False, dev=True, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) class CreatedUpdateInSrcTests(TestCase): def setUp(self): self.srcdir = FilePath(self.mktemp()) self.srcdir.makedirs() self.srcdir.child("src").makedirs() packagedir = self.srcdir.child("src").child("inctestpkg") packagedir.makedirs() packagedir.child("__init__.py").setContent( b""" from incremental import Version introduced_in = Version("inctestpkg", "NEXT", 0, 0).short() next_released_version = "inctestpkg NEXT" """ ) packagedir.child("_version.py").setContent( b""" from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3) __all__ = ["__version__"] """ ) self.getcwd = lambda: self.srcdir.path self.packagedir = packagedir class Date(object): year = 2016 month = 8 self.date = Date() def test_path(self): """ `incremental.update package --path= --dev` increments the dev version of the package on the given path """ out = [] _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=False, dev=True, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertTrue(self.packagedir.child("_version.py").exists()) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, dev=0) __all__ = ["__version__"] ''', ) _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=False, dev=True, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertTrue(self.packagedir.child("_version.py").exists()) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, dev=1) __all__ = ["__version__"] ''', ) class CreatedUpdateTests(TestCase): maxDiff = None def setUp(self): self.srcdir = FilePath(self.mktemp()) self.srcdir.makedirs() packagedir = self.srcdir.child("inctestpkg") packagedir.makedirs() packagedir.child("__init__.py").setContent( b""" from incremental import Version introduced_in = Version("inctestpkg", "NEXT", 0, 0).short() next_released_version = "inctestpkg NEXT" """ ) packagedir.child("_version.py").setContent( b""" from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3) __all__ = ["__version__"] """ ) self.getcwd = lambda: self.srcdir.path self.packagedir = packagedir class Date(object): year = 2016 month = 8 self.date = Date() def test_path(self): """ `incremental.update package --path= --dev` increments the dev version of the package on the given path """ out = [] _run( u"inctestpkg", path=self.packagedir.path, newversion=None, patch=False, rc=False, post=False, dev=True, create=False, _date=self.date, _print=out.append, ) self.assertTrue(self.packagedir.child("_version.py").exists()) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, dev=0) __all__ = ["__version__"] ''', ) def test_dev(self): """ `incremental.update package --dev` increments the dev version. """ out = [] _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=False, dev=True, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertTrue(self.packagedir.child("_version.py").exists()) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, dev=0) __all__ = ["__version__"] ''', ) def test_patch(self): """ `incremental.update package --patch` increments the patch version. """ out = [] _run( u"inctestpkg", path=None, newversion=None, patch=True, rc=False, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 4) __all__ = ["__version__"] ''', ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), b""" from incremental import Version introduced_in = Version("inctestpkg", 1, 2, 4).short() next_released_version = "inctestpkg 1.2.4" """, ) def test_patch_with_prerelease_and_dev(self): """ `incremental.update package --patch` increments the patch version, and disregards any old prerelease/dev versions. """ self.packagedir.child("_version.py").setContent( b""" from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, release_candidate=1, dev=2) __all__ = ["__version__"] """ ) out = [] _run( u"inctestpkg", path=None, newversion=None, patch=True, rc=False, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 4) __all__ = ["__version__"] ''', ) def test_rc_patch(self): """ `incremental.update package --patch --rc` increments the patch version and makes it a release candidate. """ out = [] _run( u"inctestpkg", path=None, newversion=None, patch=True, rc=True, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 4, release_candidate=1) __all__ = ["__version__"] ''', ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), b""" from incremental import Version introduced_in = Version("inctestpkg", 1, 2, 4, release_candidate=1).short() next_released_version = "inctestpkg 1.2.4.rc1" """, ) def test_rc_with_existing_rc(self): """ `incremental.update package --rc` increments the rc version if the existing version is an rc, and discards any dev version. """ self.packagedir.child("_version.py").setContent( b""" from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, release_candidate=1, dev=2) __all__ = ["__version__"] """ ) out = [] _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=True, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, release_candidate=2) __all__ = ["__version__"] ''', ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), b""" from incremental import Version introduced_in = Version("inctestpkg", 1, 2, 3, release_candidate=2).short() next_released_version = "inctestpkg 1.2.3.rc2" """, ) def test_rc_with_no_rc(self): """ `incremental.update package --rc`, when the package is not a release candidate, will issue a new major/minor rc, and disregards the micro and dev. """ self.packagedir.child("_version.py").setContent( b""" from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, dev=2) __all__ = ["__version__"] """ ) out = [] _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=True, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 16, 8, 0, release_candidate=1) __all__ = ["__version__"] ''', ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), b""" from incremental import Version introduced_in = Version("inctestpkg", 16, 8, 0, release_candidate=1).short() next_released_version = "inctestpkg 16.8.0.rc1" """, ) def test_full_with_rc(self): """ `incremental.update package`, when the package is a release candidate, will issue the major/minor, sans release candidate or dev. """ out = [] _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=True, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 16, 8, 0, release_candidate=1) __all__ = ["__version__"] ''', ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), b""" from incremental import Version introduced_in = Version("inctestpkg", 16, 8, 0, release_candidate=1).short() next_released_version = "inctestpkg 16.8.0.rc1" """, ) _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 16, 8, 0) __all__ = ["__version__"] ''', ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), b""" from incremental import Version introduced_in = Version("inctestpkg", 16, 8, 0).short() next_released_version = "inctestpkg 16.8.0" """, ) def test_full_without_rc(self): """ `incremental.update package`, when the package is NOT a release candidate, will raise an error. """ out = [] with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( e.exception.args[0], "You need to issue a rc before updating the major/minor", ) def test_post(self): """ `incremental.update package --post` increments the post version. """ out = [] _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=True, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertTrue(self.packagedir.child("_version.py").exists()) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, post=0) __all__ = ["__version__"] ''', ) def test_post_with_prerelease_and_dev(self): """ `incremental.update package --post` increments the post version, and disregards any old prerelease/dev versions. """ self.packagedir.child("_version.py").setContent( b""" from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, release_candidate=1, dev=2) __all__ = ["__version__"] """ ) out = [] _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=True, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, post=0) __all__ = ["__version__"] ''', ) def test_post_with_existing_post(self): """ `incremental.update package --post` increments the post version if the existing version is an postrelease, and discards any dev version. """ self.packagedir.child("_version.py").setContent( b""" from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, post=1, dev=2) __all__ = ["__version__"] """ ) out = [] _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=True, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, post=2) __all__ = ["__version__"] ''', ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), b""" from incremental import Version introduced_in = Version("inctestpkg", 1, 2, 3, post=2).short() next_released_version = "inctestpkg 1.2.3.post2" """, ) def test_no_mix_newversion(self): """ The `--newversion` flag can't be mixed with --patch, --rc, --post, or --dev. """ out = [] with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion="1", patch=True, rc=False, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --newversion") with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion="1", patch=False, rc=True, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --newversion") with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion="1", patch=False, rc=False, post=True, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --newversion") with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion="1", patch=False, rc=False, post=False, dev=True, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --newversion") def test_no_mix_dev(self): """ The `--dev` flag can't be mixed with --patch, --rc, or --post. """ out = [] with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion=None, patch=True, rc=False, post=False, dev=True, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --dev") with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=True, post=False, dev=True, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --dev") with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=True, dev=True, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --dev") def test_no_mix_create(self): """ The `--create` flag can't be mixed with --patch, --rc, --post, --dev, or --newversion. """ out = [] with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion=None, patch=True, rc=False, post=False, dev=False, create=True, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --create") with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion="1", patch=False, rc=False, post=False, dev=False, create=True, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --create") with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=True, post=False, dev=False, create=True, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --create") with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=True, dev=False, create=True, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --create") with self.assertRaises(ValueError) as e: _run( u"inctestpkg", path=None, newversion=None, patch=False, rc=False, post=False, dev=True, create=True, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual(e.exception.args[0], "Only give --create") def test_newversion(self): """ `incremental.update package --newversion=1.2.3.rc1.post2.dev3`, will set that version in the package. """ out = [] _run( u"inctestpkg", path=None, newversion="1.2.3.rc1.post2.dev3", patch=False, rc=False, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3, ''' b"""release_candidate=1, post=2, dev=3) __all__ = ["__version__"] """, ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), ( b""" from incremental import Version introduced_in = Version("inctestpkg", 1, 2, 3, """ b"""release_candidate=1, post=2, dev=3).short() next_released_version = "inctestpkg 1.2.3.rc1.post2.dev3" """ ), ) def test_newversion_bare(self): """ `incremental.update package --newversion=1`, will set that version in the package. """ out = [] _run( u"inctestpkg", path=None, newversion="1", patch=False, rc=False, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 0, 0) __all__ = ["__version__"] ''', ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), b""" from incremental import Version introduced_in = Version("inctestpkg", 1, 0, 0).short() next_released_version = "inctestpkg 1.0.0" """, ) def test_newversion_bare_major_minor(self): """ `incremental.update package --newversion=1.1`, will set that version in the package. """ out = [] _run( u"inctestpkg", path=None, newversion="1.1", patch=False, rc=False, post=False, dev=False, create=False, _date=self.date, _getcwd=self.getcwd, _print=out.append, ) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 1, 1, 0) __all__ = ["__version__"] ''', ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), b""" from incremental import Version introduced_in = Version("inctestpkg", 1, 1, 0).short() next_released_version = "inctestpkg 1.1.0" """, ) class ScriptTests(TestCase): def setUp(self): self.srcdir = FilePath(self.mktemp()) self.srcdir.makedirs() self.srcdir.child("src").makedirs() packagedir = self.srcdir.child("src").child("inctestpkg") packagedir.makedirs() packagedir.child("__init__.py").setContent( b""" from incremental import Version introduced_in = Version("inctestpkg", "NEXT", 0, 0).short() next_released_version = "inctestpkg NEXT" """ ) packagedir.child("_version.py").setContent( b""" from incremental import Version __version__ = Version("inctestpkg", 1, 2, 3) __all__ = ["__version__"] """ ) self.getcwd = lambda: self.srcdir.path self.packagedir = packagedir class Date(object): year = 2016 month = 8 class DateModule(object): def today(self): return Date() self.date = DateModule() def test_run(self): """ Calling run() with no args will cause it to print help. """ stringio = NativeStringIO() self.patch(sys, "stdout", stringio) with self.assertRaises(SystemExit) as e: run(["--help"]) self.assertEqual(e.exception.args[0], 0) self.assertIn("Show this message and exit", stringio.getvalue()) def test_insufficient_args(self): """ Calling run() with no args will cause it to print help. """ stringio = NativeStringIO() self.patch(sys, "stdout", stringio) self.patch(os, "getcwd", self.getcwd) self.patch(datetime, "date", self.date) with self.assertRaises(SystemExit) as e: run(["inctestpkg", "--rc"]) self.assertEqual(e.exception.args[0], 0) self.assertIn("Updating codebase", stringio.getvalue()) self.assertEqual( self.packagedir.child("_version.py").getContent(), b'''""" Provides inctestpkg version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update inctestpkg` to change this file. from incremental import Version __version__ = Version("inctestpkg", 16, 8, 0, release_candidate=1) __all__ = ["__version__"] ''', ) self.assertEqual( self.packagedir.child("__init__.py").getContent(), b""" from incremental import Version introduced_in = Version("inctestpkg", 16, 8, 0, release_candidate=1).short() next_released_version = "inctestpkg 16.8.0.rc1" """, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1664918161.0 incremental-22.10.0/src/incremental/tests/test_version.py0000644000076500000240000004417214317121221022555 0ustar00glyphstaff# Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. """ Tests for L{incremental}. """ from __future__ import division, absolute_import import sys import unittest import operator from incremental import getVersionString, IncomparableVersions from incremental import Version, _inf from twisted.trial.unittest import TestCase class VersionsTests(TestCase): def test_localIsShort(self): """ The local version is the same as the short version. """ va = Version("dummy", 1, 0, 0, release_candidate=1, post=2, dev=3) self.assertEqual(va.local(), va.short()) def test_versionComparison(self): """ Versions can be compared for equality and order. """ va = Version("dummy", 1, 0, 0) vb = Version("dummy", 0, 1, 0) self.assertTrue(va > vb) self.assertTrue(vb < va) self.assertTrue(va >= vb) self.assertTrue(vb <= va) self.assertTrue(va != vb) self.assertTrue(vb == Version("dummy", 0, 1, 0)) self.assertTrue(vb == vb) @unittest.skipIf(sys.version_info < (3,), "Comparisons do not raise on py2") def test_versionComparisonNonVersion(self): """ Versions can be compared with non-versions. """ v = Version("dummy", 1, 0, 0) o = object() with self.assertRaises(TypeError): v > o with self.assertRaises(TypeError): v < o with self.assertRaises(TypeError): v >= o with self.assertRaises(TypeError): v <= o self.assertFalse(v == o) self.assertTrue(v != o) def test_versionComparisonCaseInsensitive(self): """ Version package names are case insensitive. """ va = Version("dummy", 1, 0, 0) vb = Version("DuMmY", 0, 1, 0) self.assertTrue(va > vb) self.assertTrue(vb < va) self.assertTrue(va >= vb) self.assertTrue(vb <= va) self.assertTrue(va != vb) self.assertTrue(vb == Version("dummy", 0, 1, 0)) self.assertTrue(vb == vb) def test_comparingNEXTReleases(self): """ NEXT releases are always larger than numbered releases. """ va = Version("whatever", "NEXT", 0, 0) vb = Version("whatever", 1, 0, 0) self.assertTrue(va > vb) self.assertFalse(va < vb) self.assertNotEquals(vb, va) def test_NEXTMustBeAlone(self): """ NEXT releases must always have the rest of the numbers set to 0. """ with self.assertRaises(ValueError): Version("whatever", "NEXT", 1, 0, release_candidate=0, post=0, dev=0) with self.assertRaises(ValueError): Version("whatever", "NEXT", 0, 1, release_candidate=0, post=0, dev=0) with self.assertRaises(ValueError): Version("whatever", "NEXT", 0, 0, release_candidate=1, post=0, dev=0) with self.assertRaises(ValueError): Version("whatever", "NEXT", 0, 0, release_candidate=0, post=1, dev=0) with self.assertRaises(ValueError): Version("whatever", "NEXT", 0, 0, release_candidate=0, post=0, dev=1) def test_comparingNEXTReleasesEqual(self): """ NEXT releases are equal to each other. """ va = Version("whatever", "NEXT", 0, 0) vb = Version("whatever", "NEXT", 0, 0) self.assertEquals(vb, va) def test_comparingPrereleasesWithReleases(self): """ Prereleases are always less than versions without prereleases. """ va = Version("whatever", 1, 0, 0, prerelease=1) vb = Version("whatever", 1, 0, 0) self.assertTrue(va < vb) self.assertFalse(va > vb) self.assertNotEquals(vb, va) def test_prereleaseDeprecated(self): """ Passing 'prerelease' to Version is deprecated. """ Version("whatever", 1, 0, 0, prerelease=1) warnings = self.flushWarnings([self.test_prereleaseDeprecated]) self.assertEqual(len(warnings), 1) self.assertEqual( warnings[0]["message"], "Passing prerelease to incremental.Version was deprecated in " "Incremental 16.9.0. Please pass release_candidate instead.", ) def test_prereleaseAttributeDeprecated(self): """ Accessing 'prerelease' on a Version is deprecated. """ va = Version("whatever", 1, 0, 0, release_candidate=1) va.prerelease warnings = self.flushWarnings([self.test_prereleaseAttributeDeprecated]) self.assertEqual(len(warnings), 1) self.assertEqual( warnings[0]["message"], "Accessing incremental.Version.prerelease was deprecated in " "Incremental 16.9.0. Use Version.release_candidate instead.", ) def test_comparingReleaseCandidatesWithReleases(self): """ Release Candidates are always less than versions without release candidates. """ va = Version("whatever", 1, 0, 0, release_candidate=1) vb = Version("whatever", 1, 0, 0) self.assertTrue(va < vb) self.assertFalse(va > vb) self.assertNotEquals(vb, va) def test_comparingPostReleasesWithReleases(self): """ Post releases are always greater than versions without post releases. """ va = Version("whatever", 1, 0, 0, post=1) vb = Version("whatever", 1, 0, 0) self.assertTrue(va > vb) self.assertFalse(va < vb) self.assertNotEquals(vb, va) def test_comparingDevReleasesWithPreviousPostReleases(self): """ Dev releases are always greater than postreleases based on previous releases. """ va = Version("whatever", 1, 0, 1, dev=1) vb = Version("whatever", 1, 0, 0, post=1) self.assertTrue(va > vb) self.assertFalse(va < vb) self.assertNotEquals(vb, va) def test_comparingDevReleasesWithReleases(self): """ Dev releases are always less than versions without dev releases. """ va = Version("whatever", 1, 0, 0, dev=1) vb = Version("whatever", 1, 0, 0) self.assertTrue(va < vb) self.assertFalse(va > vb) self.assertNotEquals(vb, va) def test_rcEqualspre(self): """ Release Candidates are equal to prereleases. """ va = Version("whatever", 1, 0, 0, release_candidate=1) vb = Version("whatever", 1, 0, 0, prerelease=1) self.assertTrue(va == vb) self.assertFalse(va != vb) def test_rcOrpreButNotBoth(self): """ Release Candidate and prerelease can't both be given. """ with self.assertRaises(ValueError): Version("whatever", 1, 0, 0, prerelease=1, release_candidate=1) def test_comparingReleaseCandidates(self): """ The value specified as the release candidate is used in version comparisons. """ va = Version("whatever", 1, 0, 0, release_candidate=1) vb = Version("whatever", 1, 0, 0, release_candidate=2) self.assertTrue(va < vb) self.assertTrue(vb > va) self.assertTrue(va <= vb) self.assertTrue(vb >= va) self.assertTrue(va != vb) self.assertTrue(vb == Version("whatever", 1, 0, 0, release_candidate=2)) self.assertTrue(va == va) def test_comparingPost(self): """ The value specified as the postrelease is used in version comparisons. """ va = Version("whatever", 1, 0, 0, post=1) vb = Version("whatever", 1, 0, 0, post=2) self.assertTrue(va < vb) self.assertTrue(vb > va) self.assertTrue(va <= vb) self.assertTrue(vb >= va) self.assertTrue(va != vb) self.assertTrue(vb == Version("whatever", 1, 0, 0, post=2)) self.assertTrue(va == va) def test_comparingDev(self): """ The value specified as the dev release is used in version comparisons. """ va = Version("whatever", 1, 0, 0, dev=1) vb = Version("whatever", 1, 0, 0, dev=2) self.assertTrue(va < vb) self.assertTrue(vb > va) self.assertTrue(va <= vb) self.assertTrue(vb >= va) self.assertTrue(va != vb) self.assertTrue(vb == Version("whatever", 1, 0, 0, dev=2)) self.assertTrue(va == va) def test_comparingDevAndRC(self): """ The value specified as the dev release and release candidate is used in version comparisons. """ va = Version("whatever", 1, 0, 0, release_candidate=1, dev=1) vb = Version("whatever", 1, 0, 0, release_candidate=1, dev=2) self.assertTrue(va < vb) self.assertTrue(vb > va) self.assertTrue(va <= vb) self.assertTrue(vb >= va) self.assertTrue(va != vb) self.assertTrue(vb == Version("whatever", 1, 0, 0, release_candidate=1, dev=2)) self.assertTrue(va == va) def test_comparingDevAndRCDifferent(self): """ The value specified as the dev release and release candidate is used in version comparisons. """ va = Version("whatever", 1, 0, 0, release_candidate=1, dev=1) vb = Version("whatever", 1, 0, 0, release_candidate=2, dev=1) self.assertTrue(va < vb) self.assertTrue(vb > va) self.assertTrue(va <= vb) self.assertTrue(vb >= va) self.assertTrue(va != vb) self.assertTrue(vb == Version("whatever", 1, 0, 0, release_candidate=2, dev=1)) self.assertTrue(va == va) def test_infComparison(self): """ L{_inf} is equal to L{_inf}. This is a regression test. """ o = object() self.assertEqual(_inf, _inf) self.assertTrue(_inf > o) self.assertFalse(_inf < o) self.assertTrue(_inf >= o) self.assertFalse(_inf <= o) self.assertTrue(_inf != o) self.assertFalse(_inf == o) def test_disallowBuggyComparisons(self): """ The package names of the Version objects need to be the same. """ self.assertRaises( IncomparableVersions, operator.eq, Version("dummy", 1, 0, 0), Version("dumym", 1, 0, 0), ) def test_notImplementedComparisons(self): """ Comparing a L{Version} to some other object type results in C{NotImplemented}. """ va = Version("dummy", 1, 0, 0) vb = ("dummy", 1, 0, 0) # a tuple is not a Version object self.assertEqual(va.__cmp__(vb), NotImplemented) def test_repr(self): """ Calling C{repr} on a version returns a human-readable string representation of the version. """ self.assertEqual(repr(Version("dummy", 1, 2, 3)), "Version('dummy', 1, 2, 3)") def test_reprWithPrerelease(self): """ Calling C{repr} on a version with a prerelease returns a human-readable string representation of the version including the prerelease as a release candidate.. """ self.assertEqual( repr(Version("dummy", 1, 2, 3, prerelease=4)), "Version('dummy', 1, 2, 3, release_candidate=4)", ) def test_reprWithReleaseCandidate(self): """ Calling C{repr} on a version with a release candidate returns a human-readable string representation of the version including the rc. """ self.assertEqual( repr(Version("dummy", 1, 2, 3, release_candidate=4)), "Version('dummy', 1, 2, 3, release_candidate=4)", ) def test_reprWithPost(self): """ Calling C{repr} on a version with a postrelease returns a human-readable string representation of the version including the postrelease. """ self.assertEqual( repr(Version("dummy", 1, 2, 3, post=4)), "Version('dummy', 1, 2, 3, post=4)" ) def test_reprWithDev(self): """ Calling C{repr} on a version with a dev release returns a human-readable string representation of the version including the dev release. """ self.assertEqual( repr(Version("dummy", 1, 2, 3, dev=4)), "Version('dummy', 1, 2, 3, dev=4)" ) def test_str(self): """ Calling C{str} on a version returns a human-readable string representation of the version. """ self.assertEqual(str(Version("dummy", 1, 2, 3)), "[dummy, version 1.2.3]") def test_strWithPrerelease(self): """ Calling C{str} on a version with a prerelease includes the prerelease as a release candidate. """ self.assertEqual( str(Version("dummy", 1, 0, 0, prerelease=1)), "[dummy, version 1.0.0.rc1]" ) def test_strWithReleaseCandidate(self): """ Calling C{str} on a version with a release candidate includes the release candidate. """ self.assertEqual( str(Version("dummy", 1, 0, 0, release_candidate=1)), "[dummy, version 1.0.0.rc1]", ) def test_strWithPost(self): """ Calling C{str} on a version with a postrelease includes the postrelease. """ self.assertEqual( str(Version("dummy", 1, 0, 0, post=1)), "[dummy, version 1.0.0.post1]" ) def test_strWithDevAndReleaseCandidate(self): """ Calling C{str} on a version with a release candidate and dev release includes the release candidate and the dev release. """ self.assertEqual( str(Version("dummy", 1, 0, 0, release_candidate=1, dev=2)), "[dummy, version 1.0.0.rc1.dev2]", ) def test_strWithDev(self): """ Calling C{str} on a version with a dev release includes the dev release. """ self.assertEqual( str(Version("dummy", 1, 0, 0, dev=1)), "[dummy, version 1.0.0.dev1]" ) def test_strWithDevAndPost(self): """ Calling C{str} on a version with a postrelease and dev release includes the postrelease and the dev release. """ self.assertEqual( str(Version("dummy", 1, 0, 0, post=1, dev=2)), "[dummy, version 1.0.0.post1.dev2]", ) def testShort(self): self.assertEqual(Version("dummy", 1, 2, 3).short(), "1.2.3") def test_getVersionString(self): """ L{getVersionString} returns a string with the package name and the short version number. """ self.assertEqual("Twisted 8.0.0", getVersionString(Version("Twisted", 8, 0, 0))) def test_getVersionStringWithPrerelease(self): """ L{getVersionString} includes the prerelease as a release candidate, if any. """ self.assertEqual( getVersionString(Version("whatever", 8, 0, 0, prerelease=1)), "whatever 8.0.0.rc1", ) def test_getVersionStringWithReleaseCandidate(self): """ L{getVersionString} includes the release candidate, if any. """ self.assertEqual( getVersionString(Version("whatever", 8, 0, 0, release_candidate=1)), "whatever 8.0.0.rc1", ) def test_getVersionStringWithPost(self): """ L{getVersionString} includes the postrelease, if any. """ self.assertEqual( getVersionString(Version("whatever", 8, 0, 0, post=1)), "whatever 8.0.0.post1", ) def test_getVersionStringWithDev(self): """ L{getVersionString} includes the dev release, if any. """ self.assertEqual( getVersionString(Version("whatever", 8, 0, 0, dev=1)), "whatever 8.0.0.dev1" ) def test_getVersionStringWithDevAndRC(self): """ L{getVersionString} includes the dev release and release candidate, if any. """ self.assertEqual( getVersionString(Version("whatever", 8, 0, 0, release_candidate=2, dev=1)), "whatever 8.0.0.rc2.dev1", ) def test_getVersionStringWithDevAndPost(self): """ L{getVersionString} includes the dev release and postrelease, if any. """ self.assertEqual( getVersionString(Version("whatever", 8, 0, 0, post=2, dev=1)), "whatever 8.0.0.post2.dev1", ) def test_baseWithNEXT(self): """ The C{base} method returns just "NEXT" when NEXT is the major version. """ self.assertEqual(Version("foo", "NEXT", 0, 0).base(), "NEXT") def test_base(self): """ The C{base} method returns a very simple representation of the version. """ self.assertEqual(Version("foo", 1, 0, 0).base(), "1.0.0") def test_baseWithPrerelease(self): """ The base version includes 'rcX' for versions with prereleases. """ self.assertEqual(Version("foo", 1, 0, 0, prerelease=8).base(), "1.0.0.rc8") def test_baseWithPost(self): """ The base version includes 'postX' for versions with postreleases. """ self.assertEqual(Version("foo", 1, 0, 0, post=8).base(), "1.0.0.post8") def test_baseWithDev(self): """ The base version includes 'devX' for versions with dev releases. """ self.assertEqual(Version("foo", 1, 0, 0, dev=8).base(), "1.0.0.dev8") def test_baseWithReleaseCandidate(self): """ The base version includes 'rcX' for versions with prereleases. """ self.assertEqual( Version("foo", 1, 0, 0, release_candidate=8).base(), "1.0.0.rc8" ) def test_baseWithDevAndRC(self): """ The base version includes 'rcXdevX' for versions with dev releases and a release candidate. """ self.assertEqual( Version("foo", 1, 0, 0, release_candidate=2, dev=8).base(), "1.0.0.rc2.dev8" ) def test_baseWithDevAndPost(self): """ The base version includes 'postXdevX' for versions with dev releases and a postrelease. """ self.assertEqual( Version("foo", 1, 0, 0, post=2, dev=8).base(), "1.0.0.post2.dev8" ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1664918161.0 incremental-22.10.0/src/incremental/update.py0000644000076500000240000002126214317121221020144 0ustar00glyphstaff# Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. from __future__ import absolute_import, division, print_function import click import os import datetime from typing import TYPE_CHECKING, Dict, Optional, Callable, Iterable 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 _VERSIONPY_TEMPLATE = '''""" Provides {package} version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update {package}` to change this file. from incremental import Version __version__ = {version_repr} __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] newversion, # type: Optional[str] patch, # type: bool rc, # type: bool post, # type: bool dev, # type: bool create, # type: bool _date=None, # type: Optional[datetime.date] _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 ( newversion and patch or newversion and dev or newversion and rc or newversion and post ): raise ValueError("Only give --newversion") if dev and patch or dev and rc or dev and post: raise ValueError("Only give --dev") if ( create and dev or create and patch or create and rc or create and post or create and newversion ): raise ValueError("Only give --create") if newversion: from pkg_resources import parse_version existing = _existing_version(_path) st_version = parse_version(newversion)._version # type: ignore[attr-defined] release = list(st_version.release) minor = 0 micro = 0 if len(release) == 1: (major,) = release elif len(release) == 2: major, minor = release else: major, minor, micro = release v = Version( package, major, minor, micro, release_candidate=st_version.pre[1] if st_version.pre else None, post=st_version.post[1] if st_version.post else None, dev=st_version.dev[1] if st_version.dev else None, ) elif create: v = Version(package, _date.year - _YEAR_START, _date.month, 0) existing = v elif rc and not patch: existing = _existing_version(_path) if existing.release_candidate: v = Version( package, existing.major, existing.minor, existing.micro, existing.release_candidate + 1, ) else: v = Version(package, _date.year - _YEAR_START, _date.month, 0, 1) elif patch: existing = _existing_version(_path) v = Version( package, existing.major, existing.minor, existing.micro + 1, 1 if rc else None, ) elif post: existing = _existing_version(_path) if existing.post is None: _post = 0 else: _post = existing.post + 1 v = Version(package, existing.major, existing.minor, existing.micro, post=_post) elif dev: existing = _existing_version(_path) if existing.dev is None: _dev = 0 else: _dev = existing.dev + 1 v = Version( package, existing.major, existing.minor, existing.micro, existing.release_candidate, dev=_dev, ) else: existing = _existing_version(_path) if existing.release_candidate: v = Version(package, existing.major, existing.minor, existing.micro) else: raise ValueError("You need to issue a rc before updating the major/minor") NEXT_repr = repr(Version(package, "NEXT", 0, 0)).split("#")[0].replace("'", '"') NEXT_repr_bytes = NEXT_repr.encode("utf8") version_repr = repr(v).split("#")[0].replace("'", '"') version_repr_bytes = version_repr.encode("utf8") existing_version_repr = repr(existing).split("#")[0].replace("'", '"') existing_version_repr_bytes = existing_version_repr.encode("utf8") _print("Updating codebase to %s" % (v.public())) for x in _path.walk(): if not x.isfile(): continue original_content = x.getContent() 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 NEXT with 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) _print("Updating %s/_version.py" % (_path.path)) with _path.child("_version.py").open("w") as f: f.write( ( _VERSIONPY_TEMPLATE.format(package=package, version_repr=version_repr) ).encode("utf8") ) @click.command() @click.argument("package") @click.option("--path", default=None) @click.option("--newversion", default=None) @click.option("--patch", is_flag=True) @click.option("--rc", is_flag=True) @click.option("--post", is_flag=True) @click.option("--dev", is_flag=True) @click.option("--create", is_flag=True) def run( package, # type: str path, # type: Optional[str] newversion, # type: Optional[str] patch, # type: bool rc, # type: bool post, # type: bool dev, # type: bool create, # type: bool ): # type: (...) -> None return _run( package=package, path=path, newversion=newversion, patch=patch, rc=rc, post=post, dev=dev, create=create, ) if __name__ == "__main__": # pragma: no cover run() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1665819619.2445154 incremental-22.10.0/src/incremental.egg-info/0000755000076500000240000000000014322461743020013 5ustar00glyphstaff././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1665819619.0 incremental-22.10.0/src/incremental.egg-info/PKG-INFO0000644000076500000240000001323314322461743021112 0ustar00glyphstaffMetadata-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 Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 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 Provides-Extra: scripts Provides-Extra: mypy License-File: LICENSE Incremental =========== |gha| |pypi| |coverage| Incremental is a small library that versions your Python projects. API documentation can be found `here `_. Quick Start ----------- Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versioning arguments: .. code:: setup( use_incremental=True, setup_requires=['incremental'], install_requires=['incremental'], # along with any other install dependencies ... } Install Incremental to your local environment with ``pip install incremental[scripts]``. Then run ``python -m incremental.update --create``. It will create a file in your package named ``_version.py`` and look like this: .. code:: from incremental import Version __version__ = Version("widgetbox", 17, 1, 0) __all__ = ["__version__"] Then, so users of your project can find your version, in your root package's ``__init__.py`` add: .. code:: from ._version import __version__ Subsequent installations of your project will then use Incremental for versioning. Incremental Versions -------------------- ``incremental.Version`` is a class that represents a version of a given project. It is made up of the following elements (which are given during instantiation): - ``package`` (required), the name of the package this ``Version`` represents. - ``major``, ``minor``, ``micro`` (all required), the X.Y.Z of your project's ``Version``. - ``release_candidate`` (optional), set to 0 or higher to mark this ``Version`` being of a release candidate (also sometimes called a "prerelease"). - ``post`` (optional), set to 0 or higher to mark this ``Version`` as a postrelease. - ``dev`` (optional), set to 0 or higher to mark this ``Version`` as a development release. 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]'``. Updating -------- Incremental includes a tool to automate updating your Incremental-using project's version called ``incremental.update``. 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 `` will perform updates on that package. The commands that can be given after that will determine what the next version is. - ``--newversion=``, 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 ``..0rc1`` if the current version is not a release candidate, or bump the release candidate number by 1 if it is. - ``--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. - ``--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. - ``--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. If you give no arguments, it will strip the release candidate number, making it a "full release". Incremental 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: - ``Version("", "NEXT", 0, 0)`` - `` NEXT`` When you run ``python -m incremental.update --rc``, these will be updated to real versions (assuming the target final version is 17.1.0): - ``Version("", 17, 1, 0, release_candidate=1)`` - `` 17.1.0rc1`` Once the final version is made, it will become: - ``Version("", 17, 1, 0)`` - `` 17.1.0`` .. |coverage| image:: https://codecov.io/gh/twisted/incremental/branch/master/graph/badge.svg?token=K2ieeL887X .. _coverage: https://codecov.io/gh/twisted/incremental .. |gha| image:: https://github.com/twisted/incremental/actions/workflows/tests.yaml/badge.svg .. _gha: https://github.com/twisted/incremental/actions/workflows/tests.yaml .. |pypi| image:: http://img.shields.io/pypi/v/incremental.svg .. _pypi: https://pypi.python.org/pypi/incremental ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1665819619.0 incremental-22.10.0/src/incremental.egg-info/SOURCES.txt0000644000076500000240000000110714322461743021676 0ustar00glyphstaff.coveragerc LICENSE MANIFEST.in NEWS.rst README.rst pyproject.toml setup.cfg setup.py tox.ini src/incremental/__init__.py src/incremental/_version.py src/incremental/py.typed src/incremental/update.py src/incremental.egg-info/PKG-INFO src/incremental.egg-info/SOURCES.txt src/incremental.egg-info/dependency_links.txt src/incremental.egg-info/entry_points.txt src/incremental.egg-info/not-zip-safe src/incremental.egg-info/requires.txt src/incremental.egg-info/top_level.txt src/incremental/tests/__init__.py src/incremental/tests/test_update.py src/incremental/tests/test_version.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1665819619.0 incremental-22.10.0/src/incremental.egg-info/dependency_links.txt0000644000076500000240000000000114322461743024061 0ustar00glyphstaff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1665819619.0 incremental-22.10.0/src/incremental.egg-info/entry_points.txt0000644000076500000240000000010614322461743023306 0ustar00glyphstaff[distutils.setup_keywords] use_incremental = incremental:_get_version ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1664918289.0 incremental-22.10.0/src/incremental.egg-info/not-zip-safe0000644000076500000240000000000114317121421022227 0ustar00glyphstaff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1665819619.0 incremental-22.10.0/src/incremental.egg-info/requires.txt0000644000076500000240000000012514322461743022411 0ustar00glyphstaff [mypy] click>=6.0 twisted>=16.4.0 mypy==0.812 [scripts] click>=6.0 twisted>=16.4.0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1665819619.0 incremental-22.10.0/src/incremental.egg-info/top_level.txt0000644000076500000240000000001414322461743022540 0ustar00glyphstaffincremental ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1664918161.0 incremental-22.10.0/tox.ini0000644000076500000240000000176614317121221014542 0ustar00glyphstaff[tox] minversion = 3.23.0 requires = virtualenv >= 20.4.3 tox-wheel >= 0.6.0 isolated_build = true envlist = flake8, tests, apidocs [testenv] wheel = true wheel_build_env = build deps = tests: coverage apidocs: pydoctor lint: pre-commit extras = mypy: mypy tests: scripts commands = python -V lint: pre-commit run --all-files --show-diff-on-failure apidocs: pydoctor -q --project-name incremental src/incremental tests: coverage --version tests: {envbindir}/trial --version tests: coverage erase tests: coverage run -p {envbindir}/trial incremental tests: coverage run -p examplesetup.py install tests: coverage run -p {envbindir}/trial tests/test_exampleproj.py tests: coverage combine tests: coverage report tests: coverage html tests: coverage xml mypy: mypy src [testenv:build] # empty environment to build universal wheel once per tox invocation # https://github.com/ionelmc/tox-wheel#build-configuration