diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e37a4ab..0000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: python -sudo: false -python: - - '2.7' - - '3.4' - - '3.5' - - '3.6' - - '3.7' - -install: - - pip install -U pip setuptools flake8 - - pip install -e .[testing] - -script: - - flake8 . - - pytest - -deploy: - provider: pypi - user: eventbrite - password: - secure: SjdN3685Yq41etdyCmvq50abe9AbpG2gjmiYfuIQWjlCSmERHuSENiY4VbQ8CwxGeyIgSoaKHP2kzh+HMTnFYtJraSWV9K/R/M88obHiWpq9ouNH3lMqr2H+Da0/Q0v5OnMrD/qWmG2a6S1VLbazhDGSO9BhM+o6YeZp258YqvievrLSD+6Vjt/uGulmK4ZOiD2p3ImkYFTNiQrJ3OH6SmPGv7E2kJDExqcn+Ci27UvwAkOEB8avtwT3G0SMfjjqkyUEUmlgg4am4ESDVKeBgOBcQ4Bv3nNdSs/hC/SudHXFRHCcGGFvLvDWfj50+iCzq2BMy6Etb7+E+A8BtXj8nlO5efstYsSV0NwB3dhBcQhb23qJMVBalH0f8Qb/wu/Fynqofml27od5hL0fGc15xc6//Nc+HHXB6QIJ/66/kiZEA3x1mPwD25K1YHauwYTP9RsRKXfFgyy+qLMHqtL4I2rlZS1stfTo8RJzFUFx/R3SOltEU7pVMwrohK2Zukqag6KdUjvOmMSzO6kqLxvgC27+HSoPGOWHRyHNRXBnObuEU7IRqq+vuLDZEdk/Dz5FDTLRqx2j3woBnQyp/JmTNuqWTr6LVnYkQhVG/DlCc6QOPZ081geGGsI+hWzjOzT7CDcnEATkmgvI1cgQRXbBv7Qugpt2N3WieZkkv575K9o= - distribution: bdist_wheel sdist - on: - tags: true - python: '3.6' diff --git a/README.md b/README.md index 94dba9e..1d7c411 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ This documentation is broken down into five main sections: * [Creating and Using Invoke Release Plugins](#creating-and-using-invoke-release-plugins) - [`PatternReplaceVersionInFilesPlugin`](#patternreplaceversioninfilesplugin) -Invoke Release has been tested on Python 2.7 and 3.5 and on Mac OS X and Ubuntu. It has not been tested on Windows at +Invoke Release has been tested on 3.9 and on Mac OS X and Ubuntu. It has not been tested on Windows at this time, but pull requests are welcome if issues are found with Windows. It would require a shell-like environment, such as [Cygwin](https://www.cygwin.com/), to properly run on Windows operating systems. @@ -62,9 +62,9 @@ properly and that the tools are installed on your machine: ``` $ invoke version -Python 2.7.11 (default, Jun 17 2016, 09:29:41) -Invoke 0.22.0 -Invoke Release 4.6.0 +Python 3.9.23 (main, Jul 11 2025, 22:37:47) +Invoke 2.2.0 +Invoke Release 4.7.0 My Project 2.1.0 Detected Git branch: master Detected version file: /path/to/my/project/module/version.py @@ -79,7 +79,7 @@ directory and follow the on-screen instructions: ``` $ invoke release -Invoke Release 4.6.0 +Invoke Release 4.7.0 Releasing My Project... Current version: 2.1.0 Enter a new version (or "exit"): 2.2.0 @@ -95,7 +95,7 @@ then commit (or cherry-pick, as the case may be) your fix, and from which you ca ``` $ invoke branch -Invoke Release 4.6.0 +Invoke Release 4.7.0 Enter a version tag from which to create a new branch (or "exit"): 2.0.0 ... ``` @@ -148,9 +148,7 @@ not yet installed Invoke Release or if the `invoke` command is not working. As a prerequisite, your project's Python root module _must_ have a module named `version.py` with, at least, a `__version__` variable defined. This variable must also be imported in the `__init__.py` file of the home module. For an example of this, see [`python/invoke_release/version.py`](python/invoke_release/version.py) and -[`python/invoke_release/__init__.py`](python/invoke_release/__init__.py). If your project is a Python 2 or universal -project, we _strongly_ recommend putting `from __future__ import unicode_literals` at the top of your `version.py` -file. For Python 3-only projects, this is not necessary. +[`python/invoke_release/__init__.py`](python/invoke_release/__init__.py). Your project must also contain a file named `CHANGELOG.txt`, `CHANGELOG.md`, or `CHANGELOG.rst`. If more than one of those files are present, Invoke Release will use the first one found, in that order. In order to work properly, the @@ -221,7 +219,7 @@ and verify the output. Address any errors that you see. $ invoke version Python 2.7.11 (default, Jun 17 2016, 09:29:41) Invoke 0.22.0 -Invoke Release 4.6.0 +Invoke Release 4.7.0 PySOA 0.26.1 Detected Git branch: master Detected version file: /path/to/pysoa-project/pysoa/version.py @@ -238,11 +236,9 @@ file with each release; however, there is an alternative approach you may take. `version.txt` file that contains the raw version string and no other contents. Invoke Release will, instead, update the version in that file. This is particularly useful if you have tools that need to read the project version without importing the `version` module. If you take this approach, your `version.py` file should have the following exact -contents (excluding `__future__` for Python 3-only projects): +contents: ```python -from __future__ import unicode_literals - import codecs import os diff --git a/python/invoke_release/__init__.py b/python/invoke_release/__init__.py index 2c68803..53d50a2 100644 --- a/python/invoke_release/__init__.py +++ b/python/invoke_release/__init__.py @@ -1,3 +1 @@ -from __future__ import absolute_import - from invoke_release.version import __version_info__, __version__ # noqa: F401 diff --git a/python/invoke_release/plugins.py b/python/invoke_release/plugins.py index 4da904e..652def7 100644 --- a/python/invoke_release/plugins.py +++ b/python/invoke_release/plugins.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, unicode_literals - import codecs import os diff --git a/python/invoke_release/tasks.py b/python/invoke_release/tasks.py index e96d57e..eb69a9d 100644 --- a/python/invoke_release/tasks.py +++ b/python/invoke_release/tasks.py @@ -1,9 +1,8 @@ -from __future__ import absolute_import, unicode_literals - import codecs from contextlib import closing import datetime from distutils.version import LooseVersion +from importlib import reload import json import os from pkg_resources import parse_version @@ -12,11 +11,9 @@ import subprocess import sys import tempfile +import urllib.request from invoke import task -import six -from six import moves -from six.moves import urllib from wheel import archive RE_CHANGELOG_FILE_HEADER = re.compile(r'^=+$') @@ -144,10 +141,9 @@ def _standard_output(message, *args, **kwargs): def _prompt(message, *args, **kwargs): _print_output(COLOR_WHITE, message + ' ', *args, **kwargs) # noinspection PyCompatibility - response = moves.input() + response = input() if response: - if not isinstance(response, six.text_type): - # Input returns a bytestring in Python 2 and a unicode string in Python 3 + if not isinstance(response, str): return response.decode('utf8').strip() return response.strip() return '' @@ -329,7 +325,7 @@ def _prompt_for_changelog(verbose): if len(built_up_changelog) > 0: _verbose_output(verbose, 'Read {} lines of built-up changelog text:', len(built_up_changelog)) if verbose: - _verbose_output(verbose, six.text_type(built_up_changelog)) + _verbose_output(verbose, str(built_up_changelog)) _standard_output('There are existing changelog details for this release. You can "edit" the changes, ' '"accept" them as-is, delete them and create a "new" changelog message, or "delete" ' 'them and enter no changelog.') @@ -1243,8 +1239,8 @@ def branch(_, verbose=False, no_stash=False): raise ReleaseFailure('Version number {} not in the list of available tags.'.format(branch_version)) _v = LooseVersion(branch_version) - minor_branch = '.'.join(list(map(six.text_type, _v.version[:2])) + ['x']) - major_branch = '.'.join(list(map(six.text_type, _v.version[:1])) + ['x', 'x']) + minor_branch = '.'.join(list(map(str, _v.version[:2])) + ['x']) + major_branch = '.'.join(list(map(str, _v.version[:1])) + ['x', 'x']) proceed_instruction = _prompt( 'Using tag {tag}, would you like to create a minor branch for patch versions (branch {minor}, ' @@ -1419,7 +1415,7 @@ def release(_, verbose=False, no_stash=False): else: version_info = list(map(int, version_info)) release_version = version_separator.join( - filter(None, ['.'.join(map(six.text_type, version_info[:3])), (version_info[3:] or [None])[0]]) + filter(None, ['.'.join(map(str, version_info[:3])), (version_info[3:] or [None])[0]]) ) # This must match the code in VERSION_VARIABLE_TEMPLATE at the top of this file if not (parse_version(release_version) > parse_version(__version__)): @@ -1587,7 +1583,7 @@ def rollback_release(_, verbose=False, no_stash=False): version_module = __import__('{}.version'.format(MODULE_NAME), fromlist=[str('__version__')]) # noinspection PyCompatibility - moves.reload_module(version_module) + reload(version_module) _post_rollback(__version__, version_module.__version__) _standard_output('Release rollback is complete.') @@ -1630,7 +1626,7 @@ def wheel(_): def open_pull_request(branch_name, current_branch_name, display_name, version_to_release, github_token): - remote = six.text_type( + remote = str( subprocess.check_output( ['git', 'remote', 'get-url', 'origin'], stderr=subprocess.STDOUT, diff --git a/python/invoke_release/version.py b/python/invoke_release/version.py index 23074ff..5193d59 100644 --- a/python/invoke_release/version.py +++ b/python/invoke_release/version.py @@ -1,5 +1,2 @@ -from __future__ import unicode_literals - - __version_info__ = (4, 6, 0) __version__ = '-'.join(filter(None, ['.'.join(map(str, __version_info__[:3])), (__version_info__[3:] or [None])[0]])) diff --git a/python/tests/test_tasks.py b/python/tests/test_tasks.py index aceae85..4445c26 100644 --- a/python/tests/test_tasks.py +++ b/python/tests/test_tasks.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, unicode_literals - from unittest import TestCase from invoke_release import tasks diff --git a/setup.py b/setup.py index 1940a5d..27181b6 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, unicode_literals - from setuptools import ( find_packages, setup, @@ -11,15 +9,14 @@ from invoke_release.version import __version__ # noqa: E402 -# No dependencies to keep the library lightweight +# Few dependencies to keep the library lightweight install_requires = [ - 'invoke~=0.22.0', - 'six~=1.11.0', - 'wheel~=0.31.1' + 'invoke', + 'wheel~=0.31.1', ] tests_require = [ - 'pytest' + 'pytest', ] @@ -44,7 +41,7 @@ url='https://github.com/eventbrite/invoke-release', packages=list(map(str, find_packages(where='python', exclude=['*.tests', '*.tests.*', 'tests.*', 'tests']))), package_dir={ - str(''): str('python'), # In Python 2, these can't be unicode; in Python 3, they must be + '': 'python', }, install_requires=install_requires, # Invalid classifier prevents accidental upload to PyPI @@ -59,12 +56,9 @@ 'License :: OSI Approved :: Apache Software License', 'Operating System :: OS Independent', 'Programming Language :: Python', - '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.9', 'Topic :: Software Development', ], + python_requires='>=3.9', ) diff --git a/tasks.py b/tasks.py index 05f7611..47a9502 100644 --- a/tasks.py +++ b/tasks.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, unicode_literals - import os import sys