incremental-16.10.1/0000755000076500000240000000000013002050765014756 5ustar hawkowlstaff00000000000000incremental-16.10.1/.coveragerc0000644000076500000240000000021412770307651017106 0ustar hawkowlstaff00000000000000[run] source = incremental branch = True [paths] source = src/ .tox/*/lib/python*/site-packages/ .tox/pypy*/site-packages/ incremental-16.10.1/LICENSE0000644000076500000240000000363112770307651016000 0ustar hawkowlstaff00000000000000Incremental ----------- 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. incremental-16.10.1/MANIFEST.in0000644000076500000240000000036212776605303016530 0ustar hawkowlstaff00000000000000include .coveragerc include LICENSE include NEWS.rst include towncrier.ini include tox.ini recursive-include src/incremental *.py prune .travis prune tests exclude examplesetup.py prune src/exampleproj prune src/incremental/newsfragments incremental-16.10.1/NEWS.rst0000644000076500000240000000167013002050622016260 0ustar hawkowlstaff00000000000000Incremental 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 incremental-16.10.1/PKG-INFO0000644000076500000240000000453013002050765016055 0ustar hawkowlstaff00000000000000Metadata-Version: 1.1 Name: incremental Version: 16.10.1 Summary: UNKNOWN Home-page: https://github.com/hawkowl/incremental Author: Amber Brown Author-email: hawkowl@twistedmatrix.com License: MIT Description: Incremental =========== |travis| |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: .. code:: setup( use_incremental=True, setup_requires=['incremental'], install_requires=['incremental'], # along with any other install dependencies ... } Then in your project add a ``_version.py`` that contains: .. code:: from incremental import Version __version__ = Version("widgetbox", 1, 2, 3) __all__ = ["__version__"] Then, so users of your project can find your version, in your project's ``__init__.py`` add: .. code:: from ._version import __version__ Subsequent installations of your project will use incremental for versioning. .. |coverage| image:: https://codecov.io/github/hawkowl/incremental/coverage.svg?branch=master .. _coverage: https://codecov.io/github/hawkowl/incremental .. |travis| image:: https://travis-ci.org/hawkowl/incremental.svg?branch=master .. _travis: http://travis-ci.org/hawkowl/incremental .. |pypi| image:: http://img.shields.io/pypi/v/incremental.svg .. _pypi: https://pypi.python.org/pypi/incremental Platform: UNKNOWN Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 incremental-16.10.1/README.rst0000644000076500000240000000241212770307662016460 0ustar hawkowlstaff00000000000000Incremental =========== |travis| |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: .. code:: setup( use_incremental=True, setup_requires=['incremental'], install_requires=['incremental'], # along with any other install dependencies ... } Then in your project add a ``_version.py`` that contains: .. code:: from incremental import Version __version__ = Version("widgetbox", 1, 2, 3) __all__ = ["__version__"] Then, so users of your project can find your version, in your project's ``__init__.py`` add: .. code:: from ._version import __version__ Subsequent installations of your project will use incremental for versioning. .. |coverage| image:: https://codecov.io/github/hawkowl/incremental/coverage.svg?branch=master .. _coverage: https://codecov.io/github/hawkowl/incremental .. |travis| image:: https://travis-ci.org/hawkowl/incremental.svg?branch=master .. _travis: http://travis-ci.org/hawkowl/incremental .. |pypi| image:: http://img.shields.io/pypi/v/incremental.svg .. _pypi: https://pypi.python.org/pypi/incremental incremental-16.10.1/setup.cfg0000644000076500000240000000012213002050765016572 0ustar hawkowlstaff00000000000000[wheel] universal = 1 [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 incremental-16.10.1/setup.py0000644000076500000240000000252112776576315016515 0ustar hawkowlstaff00000000000000#!/usr/bin/env python from __future__ import absolute_import, division, print_function import os, sys from setuptools import setup, find_packages base_dir = os.path.dirname(__file__) src_dir = os.path.join(base_dir, "src") # We need to import outselves sys.path.insert(0, src_dir) import incremental setup( name='incremental', version=incremental.__version__.base(), maintainer='Amber Brown', maintainer_email='hawkowl@twistedmatrix.com', url="https://github.com/hawkowl/incremental", classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", ], packages=find_packages("src", exclude=("exampleproj",)), package_dir={"": "src"}, extras_require={ "scripts": [ "click>=6.0", "twisted>=16.4.0" ] }, license="MIT", zip_safe=False, long_description=open('README.rst').read(), entry_points=""" [distutils.setup_keywords] use_incremental = incremental:_get_version """, ) incremental-16.10.1/src/0000755000076500000240000000000013002050765015545 5ustar hawkowlstaff00000000000000incremental-16.10.1/src/incremental/0000755000076500000240000000000013002050765020046 5ustar hawkowlstaff00000000000000incremental-16.10.1/src/incremental/__init__.py0000644000076500000240000003641513002047661022171 0ustar hawkowlstaff00000000000000# Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. """ Versions for Python packages. See L{Version}. """ from __future__ import division, absolute_import import os import sys import warnings # # Compat functions # if sys.version_info < (3, 0): _PY3 = False else: _PY3 = True unicode = str def _nativeString(s): """ Convert C{bytes} or C{unicode} to the native C{str} type, using ASCII encoding if conversion is necessary. @raise UnicodeError: The input string is not ASCII encodable/decodable. @raise TypeError: The input is neither C{bytes} nor C{unicode}. """ if not isinstance(s, (bytes, unicode)): raise TypeError("%r is neither bytes nor unicode" % s) if _PY3: if isinstance(s, bytes): return s.decode("ascii") else: # Ensure we're limited to ASCII subset: s.encode("ascii") else: if isinstance(s, unicode): return s.encode("ascii") else: # Ensure we're limited to ASCII subset: s.decode("ascii") return s try: _cmp = cmp except NameError: def _cmp(a, b): """ 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 def _comparable(klass): """ Class decorator that ensures support for the special C{__cmp__} method. On Python 2 this does nothing. On Python 3, C{__eq__}, C{__lt__}, etc. methods are added to the class, relying on C{__cmp__} to implement their comparisons. """ # On Python 2, __cmp__ will just work, so no need to add extra methods: if not _PY3: return klass def __eq__(self, other): c = self.__cmp__(other) if c is NotImplemented: return c return c == 0 def __ne__(self, other): c = self.__cmp__(other) if c is NotImplemented: return c return c != 0 def __lt__(self, other): c = self.__cmp__(other) if c is NotImplemented: return c return c < 0 def __le__(self, other): c = self.__cmp__(other) if c is NotImplemented: return c return c <= 0 def __gt__(self, other): c = self.__cmp__(other) if c is NotImplemented: return c return c > 0 def __ge__(self, other): c = self.__cmp__(other) if c is NotImplemented: return c return c >= 0 klass.__lt__ = __lt__ klass.__gt__ = __gt__ klass.__le__ = __le__ klass.__ge__ = __ge__ klass.__eq__ = __eq__ klass.__ne__ = __ne__ return klass # # Versioning # @_comparable class _inf(object): """ An object that is bigger than all other objects. """ def __cmp__(self, other): """ @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 _inf = _inf() class IncomparableVersions(TypeError): """ Two versions could not be compared. """ @_comparable 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, with support for "local versions" which may include a SVN revision or Git SHA1 hash. """ def __init__(self, package, major, minor, micro, release_candidate=None, prerelease=None, dev=None): """ @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 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 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.dev = dev @property def prerelease(self): 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 short(self): """ Return a string in canonical short version format, ..[+rSVNVer/+gitsha1]. """ s = self.base() gitver = self._getGitVersion() if not gitver: svnver = self._getSVNVersion() if svnver: s += '+r' + _nativeString(svnver) else: s += '+' + gitver return s def local(self): """ Return a PEP440-compatible "local" representation of this L{Version}. This includes a SVN revision or Git commit SHA1 hash, if available. Examples: - 14.4.0+r1223 - 1.2.3rc1+rb2e812003b5d5fcf08efd1dffed6afa98d44ac8c - 12.10.1 - 3.4.8rc2 - 11.93.0rc1dev3 """ return self.short() def public(self): """ Return a PEP440-compatible "public" representation of this L{Version}. Examples: - 14.4.0 - 1.2.3rc1 - 14.2.1rc1dev9 - 16.04.0dev0 """ return self.base() def base(self): """ Like L{short}, but without the +rSVNVer or @gitsha1. """ if self.major == "NEXT": return self.major if self.release_candidate is None: rc = "" else: rc = "rc%s" % (self.release_candidate,) if self.dev is None: dev = "" else: dev = "dev%s" % (self.dev,) return '%r.%d.%d%s%s' % (self.major, self.minor, self.micro, rc, dev) def __repr__(self): # Git repr gitver = self._formatGitVersion() if gitver: gitver = ' #' + gitver # SVN repr svnver = self._formatSVNVersion() if svnver: svnver = ' #' + svnver if self.release_candidate is None: release_candidate = "" else: release_candidate = ", release_candidate=%r" % ( self.release_candidate,) 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, dev, gitver or svnver) def __str__(self): return '[%s, version %s]' % ( self.package, self.short()) def __cmp__(self, other): """ Compare two versions, considering major versions, minor versions, micro versions, then release candidates. 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. @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 else: major = self.major if self.release_candidate is None: release_candidate = _inf else: release_candidate = self.release_candidate if self.dev is None: dev = _inf else: dev = self.dev if other.major == "NEXT": othermajor = _inf else: othermajor = other.major if other.release_candidate is None: otherrc = _inf else: otherrc = other.release_candidate if other.dev is None: otherdev = _inf else: otherdev = other.dev x = _cmp((major, self.minor, self.micro, release_candidate, dev), (othermajor, other.minor, other.micro, otherrc, otherdev)) return x def _parseGitDir(self, directory): headFile = os.path.abspath(os.path.join(directory, 'HEAD')) with open(headFile, "r") as f: headContent = f.read().strip() if headContent.startswith("ref: "): with open(os.path.abspath( os.path.join(directory, headContent.split(" ")[1]))) as f: commit = f.read() return commit.strip() return headContent def _getGitVersion(self): """ Given a package directory, walk up and find the git commit sha. """ mod = sys.modules.get(self.package) if mod: basepath = os.path.dirname(mod.__file__) upOne = os.path.abspath(os.path.join(basepath, '..')) if ".git" in os.listdir(upOne): return self._parseGitDir(os.path.join(upOne, '.git')) while True: upOneMore = os.path.abspath(os.path.join(upOne, '..')) if upOneMore == upOne: return None if ".git" in os.listdir(upOneMore): return self._parseGitDir(os.path.join(upOneMore, '.git')) upOne = upOneMore def _parseSVNEntries_4(self, entriesFile): """ Given a readable file object which represents a .svn/entries file in format version 4, return the revision as a string. We do this by reading first XML element in the document that has a 'revision' attribute. """ from xml.dom.minidom import parse doc = parse(entriesFile).documentElement for node in doc.childNodes: if hasattr(node, 'getAttribute'): rev = node.getAttribute('revision') if rev is not None: return rev.encode('ascii') def _parseSVNEntries_8(self, entriesFile): """ Given a readable file object which represents a .svn/entries file in format version 8, return the revision as a string. """ entriesFile.readline() entriesFile.readline() entriesFile.readline() return entriesFile.readline().strip() # Add handlers for version 9 and 10 formats, which are the same as # version 8 as far as revision information is concerned. _parseSVNEntries_9 = _parseSVNEntries_8 _parseSVNEntriesTenPlus = _parseSVNEntries_8 def _getSVNVersion(self): """ Figure out the SVN revision number based on the existence of /.svn/entries, and its contents. This requires discovering the format version from the 'format' file and parsing the entries file accordingly. @return: None or string containing SVN Revision number. """ mod = sys.modules.get(self.package) if mod: svn = os.path.join(os.path.dirname(mod.__file__), '.svn') if not os.path.exists(svn): # It's not an svn working copy return None formatFile = os.path.join(svn, 'format') if os.path.exists(formatFile): # It looks like a less-than-version-10 working copy. with open(formatFile, 'rb') as fObj: format = fObj.read().strip() parser = getattr(self, '_parseSVNEntries_' + format.decode('ascii'), None) else: # It looks like a version-10-or-greater working copy, which # has version information in the entries file. parser = self._parseSVNEntriesTenPlus if parser is None: return b'Unknown' entriesFile = os.path.join(svn, 'entries') entries = open(entriesFile, 'rb') try: try: return parser(entries) finally: entries.close() except: return b'Unknown' def _formatSVNVersion(self): ver = self._getSVNVersion() if ver is None: return '' return ' (SVN r%s)' % (ver,) def _formatGitVersion(self): ver = self._getGitVersion() if ver is None: return '' return ' (Git %s)' % (ver,) def getVersionString(version): """ 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): """ 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(): if item[1] == "_version": version_file = {} 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 __all__ = ["__version__", "Version", "getVersionString"] incremental-16.10.1/src/incremental/_version.py0000644000076500000240000000042113002050536022235 0ustar hawkowlstaff00000000000000""" 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', 16, 10, 1) __all__ = ["__version__"] incremental-16.10.1/src/incremental/tests/0000755000076500000240000000000013002050765021210 5ustar hawkowlstaff00000000000000incremental-16.10.1/src/incremental/tests/__init__.py0000644000076500000240000000000012770307651023321 0ustar hawkowlstaff00000000000000incremental-16.10.1/src/incremental/tests/test_update.py0000644000076500000240000005611612776570252024133 0ustar hawkowlstaff00000000000000# 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, 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, 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, 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, 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, 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, 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, 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, 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, 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.4rc1" """) 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, 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.3rc2" """) 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, 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.0rc1" """) 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, 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.0rc1" """) _run(u'inctestpkg', path=None, newversion=None, patch=False, rc=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, 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_no_mix_newversion(self): """ The `--newversion` flag can't be mixed with --patch, --rc, or --dev. """ out = [] with self.assertRaises(ValueError) as e: _run(u'inctestpkg', path=None, newversion="1", patch=True, rc=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, 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, 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, or --rc. """ out = [] with self.assertRaises(ValueError) as e: _run(u'inctestpkg', path=None, newversion=None, patch=True, rc=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, 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, --dev, or --newversion. """ out = [] with self.assertRaises(ValueError) as e: _run(u'inctestpkg', path=None, newversion=None, patch=True, rc=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, 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, 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, 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.3rc1dev3`, will set that version in the package. """ out = [] _run(u'inctestpkg', path=None, newversion="1.2.3rc1dev3", patch=False, rc=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=1, 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, dev=3).short() next_released_version = "inctestpkg 1.2.3rc1dev3" """)) 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, 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" """) 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.0rc1" """) incremental-16.10.1/src/incremental/tests/test_version.py0000644000076500000240000005077213002047475024325 0ustar hawkowlstaff00000000000000# Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. """ Tests for L{incremental}. """ from __future__ import division, absolute_import import sys import operator from tempfile import mkdtemp from io import BytesIO from incremental import getVersionString, IncomparableVersions from incremental import Version, _inf from twisted.python.filepath import FilePath from twisted.trial.unittest import TestCase VERSION_4_ENTRIES = b"""\ """ VERSION_8_ENTRIES = b"""\ 8 dir 22715 svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk """ VERSION_9_ENTRIES = b"""\ 9 dir 22715 svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk """ VERSION_10_ENTRIES = b"""\ 10 dir 22715 svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk """ 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, 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) 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, dev=0) with self.assertRaises(ValueError): Version("whatever", "NEXT", 0, 1, release_candidate=0, dev=0) with self.assertRaises(ValueError): Version("whatever", "NEXT", 0, 0, release_candidate=1, dev=0) with self.assertRaises(ValueError): Version("whatever", "NEXT", 0, 0, release_candidate=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_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_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. """ self.assertEqual(_inf, _inf) 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_devWithReleaseCandidate(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.0rc1]") 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.0rc1]") 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.0rc1dev2]") 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.0dev1]") def testShort(self): self.assertEqual(Version('dummy', 1, 2, 3).short(), '1.2.3') def test_goodSVNEntries_4(self): """ Version should be able to parse an SVN format 4 entries file. """ version = Version("dummy", 1, 0, 0) self.assertEqual( version._parseSVNEntries_4(BytesIO(VERSION_4_ENTRIES)), b'18211') def test_goodSVNEntries_8(self): """ Version should be able to parse an SVN format 8 entries file. """ version = Version("dummy", 1, 0, 0) self.assertEqual( version._parseSVNEntries_8(BytesIO(VERSION_8_ENTRIES)), b'22715') def test_goodSVNEntries_9(self): """ Version should be able to parse an SVN format 9 entries file. """ version = Version("dummy", 1, 0, 0) self.assertEqual( version._parseSVNEntries_9(BytesIO(VERSION_9_ENTRIES)), b'22715') def test_goodSVNEntriesTenPlus(self): """ Version should be able to parse an SVN format 10 entries file. """ version = Version("dummy", 1, 0, 0) self.assertEqual( version._parseSVNEntriesTenPlus(BytesIO(VERSION_10_ENTRIES)), b'22715') 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.0rc1") 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.0rc1") 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.0dev1") 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.0rc2dev1") 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.0rc8") 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.0dev8") 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.0rc8") 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.0rc2dev8") def test_git(self): gitDir = FilePath(self.mktemp()) gitDir.makedirs() gitDir.child("HEAD").setContent(b"ref: refs/heads/master\n") heads = gitDir.child("refs").child("heads") heads.makedirs() heads.child("master").setContent( b"a96d61d94949c0dc097d6e1c3515792e99a724d5\n") version = Version("foo", 1, 0, 0) self.assertEqual(version._parseGitDir(gitDir.path), "a96d61d94949c0dc097d6e1c3515792e99a724d5") class FormatDiscoveryTests(TestCase): """ Tests which discover the parsing method based on the imported module name. """ def setUp(self): """ Create a temporary directory with a package structure in it. """ self.entry = FilePath(mkdtemp()) self.addCleanup(self.entry.remove) self.preTestModules = sys.modules.copy() sys.path.append(self.entry.path) pkg = self.entry.child("incremental_test_package") pkg.makedirs() pkg.child("__init__.py").setContent( b"from incremental import Version\n" b"version = Version('incremental_test_package', 1, 0, 0)\n") self.svnEntries = pkg.child(".svn") self.svnEntries.makedirs() def tearDown(self): """ Remove the imported modules and sys.path modifications. """ sys.modules.clear() sys.modules.update(self.preTestModules) sys.path.remove(self.entry.path) def checkSVNFormat(self, formatVersion, entriesText, expectedRevision): """ Check for the given revision being detected after setting the SVN entries text and format version of the test directory structure. """ self.svnEntries.child("format").setContent(formatVersion + b"\n") self.svnEntries.child("entries").setContent(entriesText) self.assertEqual(self.getVersion()._getSVNVersion(), expectedRevision) def getVersion(self): """ Import and retrieve the Version object from our dynamically created package. """ import incremental_test_package return incremental_test_package.version def test_detectVersion4(self): """ Verify that version 4 format file will be properly detected and parsed. """ self.checkSVNFormat(b"4", VERSION_4_ENTRIES, b'18211') def test_detectVersion8(self): """ Verify that version 8 format files will be properly detected and parsed. """ self.checkSVNFormat(b"8", VERSION_8_ENTRIES, b'22715') def test_detectVersion9(self): """ Verify that version 9 format files will be properly detected and parsed. """ self.checkSVNFormat(b"9", VERSION_9_ENTRIES, b'22715') def test_unparseableEntries(self): """ Verify that the result is C{b"Unknown"} for an apparently supported version for which parsing of the entries file fails. """ self.checkSVNFormat(b"4", b"some unsupported stuff", b"Unknown") def test_detectVersion10(self): """ Verify that version 10 format files will be properly detected and parsed. Differing from previous formats, the version 10 format lacks a I{format} file and B{only} has the version information on the first line of the I{entries} file. """ self.svnEntries.child("entries").setContent(VERSION_10_ENTRIES) self.assertEqual(self.getVersion()._getSVNVersion(), b'22715') def test_detectUnknownVersion(self): """ Verify that a new version of SVN will result in the revision 'Unknown'. """ self.checkSVNFormat(b"some-random-new-version", b"ooga booga!", b'Unknown') def test_getVersionStringWithRevision(self): """ L{getVersionString} includes the discovered revision number. """ self.svnEntries.child("format").setContent(b"9\n") self.svnEntries.child("entries").setContent(VERSION_10_ENTRIES) version = getVersionString(self.getVersion()) self.assertEqual( "incremental_test_package 1.0.0+r22715", version) self.assertTrue(isinstance(version, type(""))) incremental-16.10.1/src/incremental/update.py0000644000076500000240000001400612776570262021723 0ustar hawkowlstaff00000000000000# Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. from __future__ import absolute_import, division, print_function import click import os import datetime from incremental import Version from twisted.python.filepath import FilePath _VERSIONPY_TEMPLATE = '''""" Provides %s version information. """ # This file is auto-generated! Do not edit! # Use `python -m incremental.update %s` to change this file. from incremental import Version __version__ = %s __all__ = ["__version__"] ''' _YEAR_START = 2000 def _findPath(path, package): 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): version_info = {} with path.child("_version.py").open('r') as f: exec(f.read(), version_info) return version_info["__version__"] def _run(package, path, newversion, patch, rc, dev, create, _date=None, _getcwd=None, _print=print): if not _getcwd: _getcwd = os.getcwd if not _date: _date = datetime.date.today() if type(package) != str: package = package.encode('utf8') if not path: path = _findPath(_getcwd(), package) else: path = FilePath(path) if newversion and patch or newversion and dev or newversion and rc: raise ValueError("Only give --newversion") if dev and patch or dev and rc: raise ValueError("Only give --dev") if create and dev or create and patch or create and rc 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 release = list(st_version.release) if len(release) == 1: release.append(0) if len(release) == 2: release.append(0) v = Version( package, *release, release_candidate=st_version.pre[1] if st_version.pre 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: if rc: rc = 1 else: rc = None existing = _existing_version(path) v = Version(package, existing.major, existing.minor, existing.micro + 1, rc) 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] NEXT_repr_bytes = NEXT_repr.encode('utf8') version_repr = repr(v).split("#")[0] version_repr_bytes = version_repr.encode('utf8') existing_version_repr = repr(existing).split("#")[0] 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 % ( package, package, 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('--dev', is_flag=True) @click.option('--create', is_flag=True) def run(*args, **kwargs): return _run(*args, **kwargs) if __name__ == '__main__': # pragma: no cover run() incremental-16.10.1/src/incremental.egg-info/0000755000076500000240000000000013002050765021540 5ustar hawkowlstaff00000000000000incremental-16.10.1/src/incremental.egg-info/dependency_links.txt0000644000076500000240000000000113002050764025605 0ustar hawkowlstaff00000000000000 incremental-16.10.1/src/incremental.egg-info/entry_points.txt0000644000076500000240000000012313002050764025031 0ustar hawkowlstaff00000000000000 [distutils.setup_keywords] use_incremental = incremental:_get_version incremental-16.10.1/src/incremental.egg-info/not-zip-safe0000644000076500000240000000000113002050764023765 0ustar hawkowlstaff00000000000000 incremental-16.10.1/src/incremental.egg-info/PKG-INFO0000644000076500000240000000453013002050764022636 0ustar hawkowlstaff00000000000000Metadata-Version: 1.1 Name: incremental Version: 16.10.1 Summary: UNKNOWN Home-page: https://github.com/hawkowl/incremental Author: Amber Brown Author-email: hawkowl@twistedmatrix.com License: MIT Description: Incremental =========== |travis| |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: .. code:: setup( use_incremental=True, setup_requires=['incremental'], install_requires=['incremental'], # along with any other install dependencies ... } Then in your project add a ``_version.py`` that contains: .. code:: from incremental import Version __version__ = Version("widgetbox", 1, 2, 3) __all__ = ["__version__"] Then, so users of your project can find your version, in your project's ``__init__.py`` add: .. code:: from ._version import __version__ Subsequent installations of your project will use incremental for versioning. .. |coverage| image:: https://codecov.io/github/hawkowl/incremental/coverage.svg?branch=master .. _coverage: https://codecov.io/github/hawkowl/incremental .. |travis| image:: https://travis-ci.org/hawkowl/incremental.svg?branch=master .. _travis: http://travis-ci.org/hawkowl/incremental .. |pypi| image:: http://img.shields.io/pypi/v/incremental.svg .. _pypi: https://pypi.python.org/pypi/incremental Platform: UNKNOWN Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 incremental-16.10.1/src/incremental.egg-info/requires.txt0000644000076500000240000000004613002050764024137 0ustar hawkowlstaff00000000000000 [scripts] click>=6.0 twisted>=16.4.0 incremental-16.10.1/src/incremental.egg-info/SOURCES.txt0000644000076500000240000000105513002050765023425 0ustar hawkowlstaff00000000000000.coveragerc LICENSE MANIFEST.in NEWS.rst README.rst setup.cfg setup.py towncrier.ini tox.ini src/incremental/__init__.py src/incremental/_version.py 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.pyincremental-16.10.1/src/incremental.egg-info/top_level.txt0000644000076500000240000000001413002050764024264 0ustar hawkowlstaff00000000000000incremental incremental-16.10.1/towncrier.ini0000644000076500000240000000011112770307651017476 0ustar hawkowlstaff00000000000000[towncrier] filename = NEWS.rst package_dir = src/ package = incremental incremental-16.10.1/tox.ini0000644000076500000240000000141612776576175016324 0ustar hawkowlstaff00000000000000[tox] envlist = {py27,py35}-flake8, {py27,pypy,py33,py34,py35}-tests, check-manifest, apidocs [testenv] deps = tests: coverage flake8: flake8 apidocs: pydoctor check-manifest: check-manifest commands = python -V flake8: flake8 src/ apidocs: pydoctor -q --project-name incremental src/incremental check-manifest: check-manifest -v tests: pip install incremental[scripts] 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