From e25b618e959da54e6b4c8763d9889be18177866b Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Wed, 26 Jan 2022 17:47:31 -0800 Subject: [PATCH 1/7] Initial pass at script/update-requirements, results of run --- requirements-dev.txt | 30 +++++++++----- requirements.txt | 34 +++++++++++----- script/update-requirements | 63 +++++++++++++++++++++++++++++ setup.py | 10 ++--- tests/test_octodns_manager.py | 2 +- tests/test_octodns_provider_base.py | 2 +- tests/test_octodns_source_axfr.py | 2 +- tests/test_octodns_source_envvar.py | 2 +- 8 files changed, 118 insertions(+), 27 deletions(-) create mode 100755 script/update-requirements diff --git a/requirements-dev.txt b/requirements-dev.txt index 2331aad..1492962 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,10 +1,22 @@ +Pygments==2.11.2 +bleach==4.1.0 build==0.7.0 -coverage -mock -pycodestyle==2.6.0 -pyflakes==2.2.0 -pytest -pytest-network -readme_renderer[md]==26.0 -requests_mock -twine==3.4.2 +cffi==1.15.0 +cmarkgfm==0.6.0 +colorama==0.4.4 +docutils==0.18.1 +importlib-metadata==4.10.1 +keyring==23.5.0 +pep517==0.12.0 +pkginfo==1.8.2 +pycodestyle==2.8.0 +pycparser==2.21 +pyflakes==2.4.0 +pytest-network==0.0.1 +readme-renderer==32.0 +requests-toolbelt==0.9.1 +rfc3986==2.0.0 +tqdm==4.62.3 +twine==3.7.1 +webencodings==0.5.1 +zipp==3.7.0 diff --git a/requirements.txt b/requirements.txt index 653572a..459df1f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,27 @@ -PyYaml==5.4 -dnspython==1.16.0 -docutils==0.16 -fqdn==1.5.0 -jmespath==0.10.0 -natsort==6.2.1 +PyYAML==6.0 +attrs==21.4.0 +certifi==2021.10.8 +charset-normalizer==2.0.10 +coverage==6.3 +dnspython==2.2.0 +fqdn==1.5.1 +idna==3.3 +iniconfig==1.1.1 +natsort==8.0.2 +packaging==21.3 +pluggy==1.0.0 +pprintpp==0.4.0 +py==1.11.0 pycountry-convert==0.7.2 pycountry==22.1.10 -python-dateutil==2.8.1 -requests==2.25.1 -setuptools==60.5.0 +pyparsing==3.0.7 +pytest-cov==3.0.0 +pytest-mock==3.6.1 +pytest==6.2.5 +python-dateutil==2.8.2 +repoze.lru==0.7 +requests==2.27.1 +six==1.16.0 +toml==0.10.2 +tomli==2.0.0 +urllib3==1.26.8 diff --git a/script/update-requirements b/script/update-requirements new file mode 100755 index 0000000..7a2cbf5 --- /dev/null +++ b/script/update-requirements @@ -0,0 +1,63 @@ +#!/usr/bin/env python + +from os.path import join +from subprocess import check_call, check_output +from tempfile import TemporaryDirectory +import re + + +def parse_setup(lines, which): + match = re.search(fr'{which}\w*=\w*[\(\[](?P[^\)\]]*)', lines, + flags=re.DOTALL) + packages = match.groups('list')[0] + packages = re.sub(r"[\"'\s]+", '', packages, flags=re.MULTILINE) + packages = [p for p in packages.split(',') if p] + return packages + + +with open('setup.py') as fh: + lines = fh.read() + +install_requires = parse_setup(lines, 'install_requires') +tests_require = parse_setup(lines, 'tests_require') +dev_requires = [ + 'build>=0.7.0', + 'pycodestyle>=2.6.0', + 'pyflakes>=2.2.0', + 'readme_renderer[md]>=26.0', + 'twine>=3.4.2', +] + + +def print_packages(packages, heading): + print(f'{heading}:') + print(' ', end='') + print('\n '.join(packages)) + + +print_packages(install_requires, 'install_requires') +print_packages(tests_require, 'tests_require') +print_packages(dev_requires, 'dev_requires') + +with TemporaryDirectory() as tmpdir: + check_call(['python3', '-m', 'venv', tmpdir]) + + check_call([join(tmpdir, 'bin', 'pip'), 'install', *install_requires]) + frozen = check_output([join(tmpdir, 'bin', 'pip'), 'freeze']) + frozen = set(frozen.decode('utf-8').split()) + + check_call([join(tmpdir, 'bin', 'pip'), 'install', *tests_require, + *dev_requires]) + dev_frozen = check_output([join(tmpdir, 'bin', 'pip'), 'freeze']) + dev_frozen = set(dev_frozen.decode('utf-8').split()) - frozen + +print_packages(frozen, 'frozen') +print_packages(dev_frozen, 'dev_frozen') + +with open('requirements.txt', 'w') as fh: + fh.write('\n'.join(sorted(frozen))) + fh.write('\n') + +with open('requirements-dev.txt', 'w') as fh: + fh.write('\n'.join(sorted(dev_frozen))) + fh.write('\n') diff --git a/setup.py b/setup.py index 2560c0b..d5c2e70 100644 --- a/setup.py +++ b/setup.py @@ -62,7 +62,7 @@ setup( entry_points={ 'console_scripts': console_scripts, }, - install_requires=[ + install_requires=( 'PyYaml>=4.2b1', 'dnspython>=1.15.0', 'fqdn>=1.5.0', @@ -70,8 +70,8 @@ setup( 'pycountry>=19.8.18', 'pycountry-convert>=0.7.2', 'python-dateutil>=2.8.1', - 'requests>=2.20.0' - ], + 'requests>=2.20.0', + ), license='MIT', long_description=long_description(), long_description_content_type='text/markdown', @@ -81,7 +81,7 @@ setup( url='https://github.com/octodns/octodns', version=octodns.__VERSION__, tests_require=( - 'pytest', - 'pytest-network', + 'pytest>=6.2.5', + 'pytest-network>=0.0.1', ), ) diff --git a/tests/test_octodns_manager.py b/tests/test_octodns_manager.py index ce171bd..06ec7ca 100644 --- a/tests/test_octodns_manager.py +++ b/tests/test_octodns_manager.py @@ -15,8 +15,8 @@ from octodns.record import Create, Delete, Record from octodns.yaml import safe_load from octodns.zone import Zone -from mock import MagicMock, patch from unittest import TestCase +from unittest.mock import MagicMock, patch from helpers import DynamicProvider, GeoProvider, NoSshFpProvider, \ PlannableProvider, SimpleProvider, TemporaryDirectory diff --git a/tests/test_octodns_provider_base.py b/tests/test_octodns_provider_base.py index 7f4be9e..bd6c361 100644 --- a/tests/test_octodns_provider_base.py +++ b/tests/test_octodns_provider_base.py @@ -6,8 +6,8 @@ from __future__ import absolute_import, division, print_function, \ unicode_literals from logging import getLogger -from mock import MagicMock, call from unittest import TestCase +from unittest.mock import MagicMock, call from octodns.processor.base import BaseProcessor from octodns.provider import SupportsException diff --git a/tests/test_octodns_source_axfr.py b/tests/test_octodns_source_axfr.py index 5a01ca5..9e34d06 100644 --- a/tests/test_octodns_source_axfr.py +++ b/tests/test_octodns_source_axfr.py @@ -8,10 +8,10 @@ from __future__ import absolute_import, division, print_function, \ import dns.zone from dns.exception import DNSException -from mock import patch from os.path import exists from shutil import copyfile from unittest import TestCase +from unittest.mock import patch from octodns.source.axfr import AxfrSource, AxfrSourceZoneTransferFailed, \ ZoneFileSource, ZoneFileSourceLoadFailure diff --git a/tests/test_octodns_source_envvar.py b/tests/test_octodns_source_envvar.py index f752821..775b541 100644 --- a/tests/test_octodns_source_envvar.py +++ b/tests/test_octodns_source_envvar.py @@ -1,5 +1,5 @@ -from mock import patch from unittest import TestCase +from unittest.mock import patch from octodns.source.envvar import EnvVarSource from octodns.source.envvar import EnvironmentVariableNotFoundException From b4e006f60fef34f2df9b72b8266ca418743d5e7e Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Wed, 26 Jan 2022 17:57:33 -0800 Subject: [PATCH 2/7] Print sorted frozen and dev_frozen to match files --- script/update-requirements | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/script/update-requirements b/script/update-requirements index 7a2cbf5..b9107ef 100755 --- a/script/update-requirements +++ b/script/update-requirements @@ -51,13 +51,16 @@ with TemporaryDirectory() as tmpdir: dev_frozen = check_output([join(tmpdir, 'bin', 'pip'), 'freeze']) dev_frozen = set(dev_frozen.decode('utf-8').split()) - frozen +frozen = sorted(frozen) +dev_frozen = sorted(dev_frozen) + print_packages(frozen, 'frozen') print_packages(dev_frozen, 'dev_frozen') with open('requirements.txt', 'w') as fh: - fh.write('\n'.join(sorted(frozen))) + fh.write('\n'.join(frozen)) fh.write('\n') with open('requirements-dev.txt', 'w') as fh: - fh.write('\n'.join(sorted(dev_frozen))) + fh.write('\n'.join(dev_frozen)) fh.write('\n') From 65dce06169d5d0ec7ef0375c29cd7f66edb3096a Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Wed, 26 Jan 2022 17:58:10 -0800 Subject: [PATCH 3/7] We don't explicitly need requests anymore --- requirements-dev.txt | 5 +++++ requirements.txt | 5 ----- setup.py | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 1492962..fa61f80 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,10 +1,13 @@ Pygments==2.11.2 bleach==4.1.0 build==0.7.0 +certifi==2021.10.8 cffi==1.15.0 +charset-normalizer==2.0.10 cmarkgfm==0.6.0 colorama==0.4.4 docutils==0.18.1 +idna==3.3 importlib-metadata==4.10.1 keyring==23.5.0 pep517==0.12.0 @@ -15,8 +18,10 @@ pyflakes==2.4.0 pytest-network==0.0.1 readme-renderer==32.0 requests-toolbelt==0.9.1 +requests==2.27.1 rfc3986==2.0.0 tqdm==4.62.3 twine==3.7.1 +urllib3==1.26.8 webencodings==0.5.1 zipp==3.7.0 diff --git a/requirements.txt b/requirements.txt index 459df1f..66484e1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,8 @@ PyYAML==6.0 attrs==21.4.0 -certifi==2021.10.8 -charset-normalizer==2.0.10 coverage==6.3 dnspython==2.2.0 fqdn==1.5.1 -idna==3.3 iniconfig==1.1.1 natsort==8.0.2 packaging==21.3 @@ -20,8 +17,6 @@ pytest-mock==3.6.1 pytest==6.2.5 python-dateutil==2.8.2 repoze.lru==0.7 -requests==2.27.1 six==1.16.0 toml==0.10.2 tomli==2.0.0 -urllib3==1.26.8 diff --git a/setup.py b/setup.py index d5c2e70..ffacd43 100644 --- a/setup.py +++ b/setup.py @@ -70,7 +70,6 @@ setup( 'pycountry>=19.8.18', 'pycountry-convert>=0.7.2', 'python-dateutil>=2.8.1', - 'requests>=2.20.0', ), license='MIT', long_description=long_description(), From 4dff97e8f61e63e9db3a5d3d1b15a81d6b59b86c Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Thu, 27 Jan 2022 10:17:30 -0800 Subject: [PATCH 4/7] Rework update-requirements and setup.py to use pip's setup.py support --- script/update-requirements | 53 +++++++++++++------------------------- setup.py | 19 +++++++++++--- 2 files changed, 33 insertions(+), 39 deletions(-) diff --git a/script/update-requirements b/script/update-requirements index b9107ef..c750a18 100755 --- a/script/update-requirements +++ b/script/update-requirements @@ -3,30 +3,6 @@ from os.path import join from subprocess import check_call, check_output from tempfile import TemporaryDirectory -import re - - -def parse_setup(lines, which): - match = re.search(fr'{which}\w*=\w*[\(\[](?P[^\)\]]*)', lines, - flags=re.DOTALL) - packages = match.groups('list')[0] - packages = re.sub(r"[\"'\s]+", '', packages, flags=re.MULTILINE) - packages = [p for p in packages.split(',') if p] - return packages - - -with open('setup.py') as fh: - lines = fh.read() - -install_requires = parse_setup(lines, 'install_requires') -tests_require = parse_setup(lines, 'tests_require') -dev_requires = [ - 'build>=0.7.0', - 'pycodestyle>=2.6.0', - 'pyflakes>=2.2.0', - 'readme_renderer[md]>=26.0', - 'twine>=3.4.2', -] def print_packages(packages, heading): @@ -35,24 +11,31 @@ def print_packages(packages, heading): print('\n '.join(packages)) -print_packages(install_requires, 'install_requires') -print_packages(tests_require, 'tests_require') -print_packages(dev_requires, 'dev_requires') - with TemporaryDirectory() as tmpdir: check_call(['python3', '-m', 'venv', tmpdir]) - check_call([join(tmpdir, 'bin', 'pip'), 'install', *install_requires]) + # base needs + check_call([join(tmpdir, 'bin', 'pip'), 'install', '.']) frozen = check_output([join(tmpdir, 'bin', 'pip'), 'freeze']) - frozen = set(frozen.decode('utf-8').split()) + frozen = set(frozen.decode('utf-8').strip().split('\n')) - check_call([join(tmpdir, 'bin', 'pip'), 'install', *tests_require, - *dev_requires]) + # dev additions + check_call([join(tmpdir, 'bin', 'pip'), 'install', '.[dev]']) dev_frozen = check_output([join(tmpdir, 'bin', 'pip'), 'freeze']) - dev_frozen = set(dev_frozen.decode('utf-8').split()) - frozen + dev_frozen = set(dev_frozen.decode('utf-8').strip().split('\n')) - frozen -frozen = sorted(frozen) -dev_frozen = sorted(dev_frozen) +# pip installs the module itself along with deps so we need to get that out of +# our list by finding the thing that was file installed during dev +dev_frozen_sorted = sorted(dev_frozen) +dev_frozen = [] +for package in dev_frozen_sorted: + if 'file://' in package: + ours = package.split(' @ ')[0] + else: + dev_frozen.append(package) +# now we can build the list of base requiements w/o ourself +frozen = sorted([p for p in frozen if not p.startswith(ours)]) +# we also sorted things while we were at it above print_packages(frozen, 'frozen') print_packages(dev_frozen, 'dev_frozen') diff --git a/setup.py b/setup.py index ffacd43..407be02 100644 --- a/setup.py +++ b/setup.py @@ -55,6 +55,11 @@ def long_description(): return buf.getvalue() +tests_require = ( + 'pytest>=6.2.5', + 'pytest-network>=0.0.1', +) + setup( author='Ross McFarland', author_email='rwmcfa1@gmail.com', @@ -62,6 +67,15 @@ setup( entry_points={ 'console_scripts': console_scripts, }, + extras_require={ + 'dev': tests_require + ( + 'build>=0.7.0', + 'pycodestyle>=2.6.0', + 'pyflakes>=2.2.0', + 'readme_renderer[md]>=26.0', + 'twine>=3.4.2', + ), + }, install_requires=( 'PyYaml>=4.2b1', 'dnspython>=1.15.0', @@ -77,10 +91,7 @@ setup( name='octodns', packages=find_packages(), python_requires='>=3.6', + tests_require=tests_require, url='https://github.com/octodns/octodns', version=octodns.__VERSION__, - tests_require=( - 'pytest>=6.2.5', - 'pytest-network>=0.0.1', - ), ) From 562a2c9e87f593b9e244c0d68194d162e4cf221b Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Fri, 28 Jan 2022 12:19:34 -0800 Subject: [PATCH 5/7] Rework how we find and exclude ourself in update-requirements --- script/update-requirements | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/script/update-requirements b/script/update-requirements index c750a18..e3d9ab2 100755 --- a/script/update-requirements +++ b/script/update-requirements @@ -3,6 +3,7 @@ from os.path import join from subprocess import check_call, check_output from tempfile import TemporaryDirectory +import re def print_packages(packages, heading): @@ -11,6 +12,15 @@ def print_packages(packages, heading): print('\n '.join(packages)) +# would be nice if there was a cleaner way to get this, but I've not found a +# more reliable one. +with open('setup.py') as fh: + match = re.search(r"name='(?P[\w-]+)',", fh.read()) + if not match: + raise Exception('failed to determine our package name') + our_package_name = match.group('pkg') + print(f'our_package_name: {our_package_name}') + with TemporaryDirectory() as tmpdir: check_call(['python3', '-m', 'venv', tmpdir]) @@ -26,16 +36,9 @@ with TemporaryDirectory() as tmpdir: # pip installs the module itself along with deps so we need to get that out of # our list by finding the thing that was file installed during dev -dev_frozen_sorted = sorted(dev_frozen) -dev_frozen = [] -for package in dev_frozen_sorted: - if 'file://' in package: - ours = package.split(' @ ')[0] - else: - dev_frozen.append(package) -# now we can build the list of base requiements w/o ourself -frozen = sorted([p for p in frozen if not p.startswith(ours)]) -# we also sorted things while we were at it above +frozen = sorted([p for p in frozen if not p.startswith(our_package_name)]) +dev_frozen = sorted([p for p in dev_frozen + if not p.startswith(our_package_name)]) print_packages(frozen, 'frozen') print_packages(dev_frozen, 'dev_frozen') From a36222716ca55d334138a46cc2c4ac0f36a1a616 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Fri, 28 Jan 2022 12:20:05 -0800 Subject: [PATCH 6/7] pytest-mock version bump --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 66484e1..a403ad3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ pycountry-convert==0.7.2 pycountry==22.1.10 pyparsing==3.0.7 pytest-cov==3.0.0 -pytest-mock==3.6.1 +pytest-mock==3.7.0 pytest==6.2.5 python-dateutil==2.8.2 repoze.lru==0.7 From 49535fa1045ae18f141d52109998706b690a4a0f Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Fri, 28 Jan 2022 12:24:04 -0800 Subject: [PATCH 7/7] Move pycountry-convert to dev requirements --- requirements-dev.txt | 15 +++++++++++++++ requirements.txt | 15 --------------- setup.py | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index fa61f80..49b8f4c 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,5 @@ Pygments==2.11.2 +attrs==21.4.0 bleach==4.1.0 build==0.7.0 certifi==2021.10.8 @@ -6,20 +7,34 @@ cffi==1.15.0 charset-normalizer==2.0.10 cmarkgfm==0.6.0 colorama==0.4.4 +coverage==6.3 docutils==0.18.1 idna==3.3 importlib-metadata==4.10.1 +iniconfig==1.1.1 keyring==23.5.0 +packaging==21.3 pep517==0.12.0 pkginfo==1.8.2 +pluggy==1.0.0 +pprintpp==0.4.0 +py==1.11.0 pycodestyle==2.8.0 +pycountry-convert==0.7.2 pycparser==2.21 pyflakes==2.4.0 +pyparsing==3.0.7 +pytest-cov==3.0.0 +pytest-mock==3.7.0 pytest-network==0.0.1 +pytest==6.2.5 readme-renderer==32.0 +repoze.lru==0.7 requests-toolbelt==0.9.1 requests==2.27.1 rfc3986==2.0.0 +toml==0.10.2 +tomli==2.0.0 tqdm==4.62.3 twine==3.7.1 urllib3==1.26.8 diff --git a/requirements.txt b/requirements.txt index a403ad3..0d9b90a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,22 +1,7 @@ PyYAML==6.0 -attrs==21.4.0 -coverage==6.3 dnspython==2.2.0 fqdn==1.5.1 -iniconfig==1.1.1 natsort==8.0.2 -packaging==21.3 -pluggy==1.0.0 -pprintpp==0.4.0 -py==1.11.0 -pycountry-convert==0.7.2 pycountry==22.1.10 -pyparsing==3.0.7 -pytest-cov==3.0.0 -pytest-mock==3.7.0 -pytest==6.2.5 python-dateutil==2.8.2 -repoze.lru==0.7 six==1.16.0 -toml==0.10.2 -tomli==2.0.0 diff --git a/setup.py b/setup.py index 407be02..eb97c92 100644 --- a/setup.py +++ b/setup.py @@ -71,6 +71,7 @@ setup( 'dev': tests_require + ( 'build>=0.7.0', 'pycodestyle>=2.6.0', + 'pycountry-convert>=0.7.2', 'pyflakes>=2.2.0', 'readme_renderer[md]>=26.0', 'twine>=3.4.2', @@ -82,7 +83,6 @@ setup( 'fqdn>=1.5.0', 'natsort>=5.5.0', 'pycountry>=19.8.18', - 'pycountry-convert>=0.7.2', 'python-dateutil>=2.8.1', ), license='MIT',