From 7bba657506130f05e5b5ee485fbabe7c39ff2b80 Mon Sep 17 00:00:00 2001 From: Kiss György Date: Thu, 18 Oct 2018 15:40:47 +0200 Subject: setup.py: Fix gbp problem when installed with pip when installed with "pip install gbp" it will be installed as version "0.0" because the released version doesn't have a debian/changelog file, so it will be installed with a warning: balabit-bbos-tools 1.0.0 has requirement gbp==0.9.8, but you'll have gbp 0.0 which is incompatible. and will cause an Exception when using gbp from a setuptools entrypoint script: File "/home/walkman/stew/projects/platform/source/balabit-os-tools/.venv/lib/python3.6/site-packages/pkg_resources/__init__.py", line 574, in _build_master ws.require(__requires__) File "/home/walkman/stew/projects/platform/source/balabit-os-tools/.venv/lib/python3.6/site-packages/pkg_resources/__init__.py", line 892, in require needed = self.resolve(parse_requirements(requirements)) File "/home/walkman/stew/projects/platform/source/balabit-os-tools/.venv/lib/python3.6/site-packages/pkg_resources/__init__.py", line 783, in resolve raise VersionConflict(dist, req).with_context(dependent_req) pkg_resources.ContextualVersionConflict: (gbp 0.0 (/home/walkman/stew/projects/platform/source/balabit-os-tools/.venv/lib/python3.6/site-packages), Requirement.parse('gbp==0.9.8'), {'requiresgbp'}) This is because pkg_resources checks every dependency version and if it doesn't match with the egg-info, it raises this Exception. Instead, we try to parse the debian/changelog first, then load the version, or if the debian/changelog file doesn't exists (this is the case at pip install) we read the gbp/version.py and parse the version from it. There is a "round trip check", which means the parsed version is written, then it will be read back immediately to see if there is any problem. --- setup.py | 27 +++------------------------ version_parser.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 version_parser.py diff --git a/setup.py b/setup.py index f505b39d..150dfdde 100755 --- a/setup.py +++ b/setup.py @@ -17,30 +17,9 @@ # # END OF COPYRIGHT # -import subprocess -from setuptools import setup, find_packages import os - - -def fetch_version(): - """Get version from debian changelog and write it to gbp/version.py""" - version = "0.0" - - try: - popen = subprocess.Popen('dpkg-parsechangelog', stdout=subprocess.PIPE) - out, ret = popen.communicate() - for line in out.decode('utf-8').split('\n'): - if line.startswith('Version:'): - version = line.split(' ')[1].strip() - break - except OSError: - pass # Failing is fine, we just can't print the version then - - with open('gbp/version.py', 'w') as f: - f.write('"The current gbp version number"\n') - f.write('gbp_version = "%s"\n' % version) - - return version +from setuptools import setup, find_packages +from version_parser import parse_and_fetch_version def readme(): @@ -56,7 +35,7 @@ def setup_requires(): setup(name="gbp", - version=fetch_version(), + version=parse_and_fetch_version(), author=u'Guido Günther', author_email='agx@sigxcpu.org', url='https://honk.sigxcpu.org/piki/projects/git-buildpackage/', diff --git a/version_parser.py b/version_parser.py new file mode 100644 index 00000000..793d77db --- /dev/null +++ b/version_parser.py @@ -0,0 +1,42 @@ +import os +import subprocess + + +VERSION_PY_PATH = 'gbp/version.py' + + +def _parse_changelog(): + """Get version from debian changelog and write it to gbp/version.py""" + popen = subprocess.Popen('dpkg-parsechangelog', stdout=subprocess.PIPE) + out, ret = popen.communicate() + for line in out.decode('utf-8').split('\n'): + if line.startswith('Version:'): + version = line.split(' ')[1].strip() + return version + + raise ValueError('Could not parse version from debian/changelog') + + +def _save_version_py(version): + with open(VERSION_PY_PATH, 'w') as f: + f.write('"The current gbp version number"\n') + f.write('gbp_version = "%s"\n' % version) + + +def _load_version(): + with open(VERSION_PY_PATH, 'r') as f: + version_py = f.read() + version_py_globals = {} + exec(version_py, version_py_globals) + return version_py_globals['gbp_version'] + + +def parse_and_fetch_version(): + if os.path.exists('debian/changelog'): + version = _parse_changelog() + _save_version_py(version) + # we could return with the version here, but instead we check that + # the file has been properly written and it can be loaded back + + version = _load_version() + return version -- cgit v1.2.3