From 56807bf793a88db21ac9b6510d89489f446f1668 Mon Sep 17 00:00:00 2001 From: Harald Nezbeda Date: Wed, 6 Sep 2017 07:55:16 +0200 Subject: [PATCH] Adds license information --- test/fixtures/pypi-package3-1.0.0.json | 81 ++++++++++++++++++++++++++ test/fixtures/pypi-package3-2.0.0.json | 81 ++++++++++++++++++++++++++ test/fixtures/pypi-package3-3.0.0.json | 81 ++++++++++++++++++++++++++ test/test_update.py | 6 +- test/test_update_license.py | 58 ++++++++++++++++++ updatable/__init__.py | 38 +++++++++--- updatable/__version__.py | 2 +- 7 files changed, 337 insertions(+), 10 deletions(-) create mode 100644 test/fixtures/pypi-package3-1.0.0.json create mode 100644 test/fixtures/pypi-package3-2.0.0.json create mode 100644 test/fixtures/pypi-package3-3.0.0.json create mode 100644 test/test_update_license.py diff --git a/test/fixtures/pypi-package3-1.0.0.json b/test/fixtures/pypi-package3-1.0.0.json new file mode 100644 index 0000000..a645c85 --- /dev/null +++ b/test/fixtures/pypi-package3-1.0.0.json @@ -0,0 +1,81 @@ +{ + "info": { + "maintainer": "", + "docs_url": null, + "requires_python": "", + "maintainer_email": "", + "cheesecake_code_kwalitee_id": null, + "keywords": "", + "package_url": "http://pypi.python.org/pypi/package3", + "author": "Package 3 author", + "author_email": "package3@package.test", + "download_url": "", + "platform": "", + "version": "1.0.0", + "cheesecake_documentation_id": null, + "_pypi_hidden": false, + "description": "UNKNOWN\n\n\n", + "release_url": "http://pypi.python.org/pypi/package3/1.0.1", + "downloads": { + "last_month": 0, + "last_week": 0, + "last_day": 0 + }, + "_pypi_ordering": 141, + "requires_dist": [], + "classifiers": [], + "name": "Package3", + "bugtrack_url": "", + "license": "GPL-2.0", + "summary": "Python package", + "home_page": "https://www.url.tld/", + "cheesecake_installability_id": null + }, + "releases": { + "1.0.0": [ + { + "has_sig": false, + "upload_time": "2011-09-29T23:34:21", + "comment_text": "", + "python_version": "source", + "url": "", + "md5_digest": "", + "downloads": 0, + "filename": "package.tar.gz", + "packagetype": "sdist", + "path": "f0/package.tar.gz", + "size": 1234 + } + ], + "2.0.0": [ + { + "has_sig": false, + "upload_time": "2013-11-29T23:34:21", + "comment_text": "", + "python_version": "source", + "url": "", + "md5_digest": "", + "downloads": 0, + "filename": "package.tar.gz", + "packagetype": "sdist", + "path": "f0/package.tar.gz", + "size": 1234 + } + ], + "3.0.0": [ + { + "has_sig": false, + "upload_time": "2015-09-29T23:34:21", + "comment_text": "", + "python_version": "source", + "url": "", + "md5_digest": "", + "downloads": 0, + "filename": "package.tar.gz", + "packagetype": "sdist", + "path": "f0/package.tar.gz", + "size": 1234 + } + ] + } +} \ No newline at end of file diff --git a/test/fixtures/pypi-package3-2.0.0.json b/test/fixtures/pypi-package3-2.0.0.json new file mode 100644 index 0000000..722b419 --- /dev/null +++ b/test/fixtures/pypi-package3-2.0.0.json @@ -0,0 +1,81 @@ +{ + "info": { + "maintainer": "", + "docs_url": null, + "requires_python": "", + "maintainer_email": "", + "cheesecake_code_kwalitee_id": null, + "keywords": "", + "package_url": "http://pypi.python.org/pypi/package3", + "author": "Package 3 author", + "author_email": "package3@package.test", + "download_url": "", + "platform": "", + "version": "2.0.0", + "cheesecake_documentation_id": null, + "_pypi_hidden": false, + "description": "UNKNOWN\n\n\n", + "release_url": "http://pypi.python.org/pypi/package3/1.0.1", + "downloads": { + "last_month": 0, + "last_week": 0, + "last_day": 0 + }, + "_pypi_ordering": 141, + "requires_dist": [], + "classifiers": [], + "name": "Package3", + "bugtrack_url": "", + "license": "GPL-3.0", + "summary": "Python package", + "home_page": "https://www.url.tld/", + "cheesecake_installability_id": null + }, + "releases": { + "1.0.0": [ + { + "has_sig": false, + "upload_time": "2011-09-29T23:34:21", + "comment_text": "", + "python_version": "source", + "url": "", + "md5_digest": "", + "downloads": 0, + "filename": "package.tar.gz", + "packagetype": "sdist", + "path": "f0/package.tar.gz", + "size": 1234 + } + ], + "2.0.0": [ + { + "has_sig": false, + "upload_time": "2013-11-29T23:34:21", + "comment_text": "", + "python_version": "source", + "url": "", + "md5_digest": "", + "downloads": 0, + "filename": "package.tar.gz", + "packagetype": "sdist", + "path": "f0/package.tar.gz", + "size": 1234 + } + ], + "3.0.0": [ + { + "has_sig": false, + "upload_time": "2015-09-29T23:34:21", + "comment_text": "", + "python_version": "source", + "url": "", + "md5_digest": "", + "downloads": 0, + "filename": "package.tar.gz", + "packagetype": "sdist", + "path": "f0/package.tar.gz", + "size": 1234 + } + ] + } +} \ No newline at end of file diff --git a/test/fixtures/pypi-package3-3.0.0.json b/test/fixtures/pypi-package3-3.0.0.json new file mode 100644 index 0000000..900ef44 --- /dev/null +++ b/test/fixtures/pypi-package3-3.0.0.json @@ -0,0 +1,81 @@ +{ + "info": { + "maintainer": "", + "docs_url": null, + "requires_python": "", + "maintainer_email": "", + "cheesecake_code_kwalitee_id": null, + "keywords": "", + "package_url": "http://pypi.python.org/pypi/package3", + "author": "Package 3 author", + "author_email": "package3@package.test", + "download_url": "", + "platform": "", + "version": "3.0.0", + "cheesecake_documentation_id": null, + "_pypi_hidden": false, + "description": "UNKNOWN\n\n\n", + "release_url": "http://pypi.python.org/pypi/package3/1.0.1", + "downloads": { + "last_month": 0, + "last_week": 0, + "last_day": 0 + }, + "_pypi_ordering": 141, + "requires_dist": [], + "classifiers": [], + "name": "Package3", + "bugtrack_url": "", + "license": "MIT", + "summary": "Python package", + "home_page": "https://www.url.tld/", + "cheesecake_installability_id": null + }, + "releases": { + "1.0.0": [ + { + "has_sig": false, + "upload_time": "2011-09-29T23:34:21", + "comment_text": "", + "python_version": "source", + "url": "", + "md5_digest": "", + "downloads": 0, + "filename": "package.tar.gz", + "packagetype": "sdist", + "path": "f0/package.tar.gz", + "size": 1234 + } + ], + "2.0.0": [ + { + "has_sig": false, + "upload_time": "2013-11-29T23:34:21", + "comment_text": "", + "python_version": "source", + "url": "", + "md5_digest": "", + "downloads": 0, + "filename": "package.tar.gz", + "packagetype": "sdist", + "path": "f0/package.tar.gz", + "size": 1234 + } + ], + "3.0.0": [ + { + "has_sig": false, + "upload_time": "2015-09-29T23:34:21", + "comment_text": "", + "python_version": "source", + "url": "", + "md5_digest": "", + "downloads": 0, + "filename": "package.tar.gz", + "packagetype": "sdist", + "path": "f0/package.tar.gz", + "size": 1234 + } + ] + } +} \ No newline at end of file diff --git a/test/test_update.py b/test/test_update.py index e895ae1..8a81be7 100644 --- a/test/test_update.py +++ b/test/test_update.py @@ -10,8 +10,10 @@ PATH = os.path.dirname(os.path.realpath(__file__)) -def get_pypi_package_data_monkey(package_name): - with open(os.path.join(PATH, 'fixtures', 'pypi-%s.json' % package_name)) as data_file: +def get_pypi_package_data_monkey(package_name, version=None): + json_file = 'pypi-%s.json' % package_name + + with open(os.path.join(PATH, 'fixtures', json_file)) as data_file: return json.load(data_file) diff --git a/test/test_update_license.py b/test/test_update_license.py new file mode 100644 index 0000000..16ffcb5 --- /dev/null +++ b/test/test_update_license.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +import unittest +import os +import json + +import updatable + + +PATH = os.path.dirname(os.path.realpath(__file__)) + + +def get_pypi_package_data_monkey(package_name, version=None): + if version: + json_file = 'pypi-%s-%s.json' % (package_name, version) + else: + json_file = 'pypi-%s.json' % package_name + + with open(os.path.join(PATH, 'fixtures', json_file)) as data_file: + return json.load(data_file) + + +class TestUpdateLicense(unittest.TestCase): + """ + Tests package updatability + """ + + def setUp(self): + self.get_pypi_package_data_orig = updatable.get_pypi_package_data + updatable.get_pypi_package_data = get_pypi_package_data_monkey + + def tearDown(self): + updatable.get_pypi_package_data = self.get_pypi_package_data_orig + + def test_update_license(self): + """ + Test update count for a package that has only major releases + """ + updates = updatable.get_package_update_list('package3', '1.0.0') + self.assertEqual(updates['current_release'], '1.0.0') + self.assertEqual(updates['latest_release'], '3.0.0') + self.assertEqual(updates['current_release_license'], 'GPL-2.0') + self.assertEqual(updates['latest_release_license'], 'MIT') + + updates = updatable.get_package_update_list('package3', '2.0.0') + self.assertEqual(updates['current_release'], '2.0.0') + self.assertEqual(updates['latest_release'], '3.0.0') + self.assertEqual(updates['current_release_license'], 'GPL-3.0') + self.assertEqual(updates['latest_release_license'], 'MIT') + + updates = updatable.get_package_update_list('package3', '3.0.0') + self.assertEqual(updates['current_release'], '3.0.0') + self.assertEqual(updates['latest_release'], '3.0.0') + self.assertEqual(updates['current_release_license'], 'MIT') + self.assertEqual(updates['latest_release_license'], 'MIT') + + +if __name__ == '__main__': + unittest.main() diff --git a/updatable/__init__.py b/updatable/__init__.py index 48f02b2..45445f4 100644 --- a/updatable/__init__.py +++ b/updatable/__init__.py @@ -60,17 +60,25 @@ def parse_requirements_list(requirements_list): return req_list -def get_pypi_package_data(package_name): +def get_pypi_package_data(package_name, version=None): """ Get package data from pypi by the package name https://wiki.python.org/moin/PyPIJSON :param package_name: string + :param version: string :return: dict """ + pypi_url = 'https://pypi.python.org/pypi' + + if version: + package_url = '%s/%s/%s/json' % (pypi_url, package_name, version, ) + else: + package_url = '%s/%s/json' % (pypi_url, package_name, ) + try: - response = requests.get('https://pypi.python.org/pypi/%s/json' % package_name) + response = requests.get(package_url) except requests.ConnectionError: raise RuntimeError('Connection error!') @@ -90,20 +98,30 @@ def get_package_update_list(package_name, version): :return: dict """ package_version = semantic_version.Version.coerce(version) - data = get_pypi_package_data(package_name) + # Get package and version data from pypi + package_data = get_pypi_package_data(package_name) + version_data = get_pypi_package_data(package_name, version) + + # Current release specific information + current_release = '' + current_release_license = '' + + # Latest release specific information latest_release = '' latest_release_license = '' + + # Information about packages major_updates = [] minor_updates = [] patch_updates = [] non_semantic_versions = [] - if data: - latest_release = data['info']['version'] - latest_release_license = data['info']['license'] if data['info']['license'] else '' + if package_data: + latest_release = package_data['info']['version'] + latest_release_license = package_data['info']['license'] if package_data['info']['license'] else '' - for release, info in data['releases'].items(): + for release, info in package_data['releases'].items(): upload_time = None if info: upload_time = datetime.strptime(info[0]['upload_time'], "%Y-%m-%dT%H:%M:%S") @@ -132,10 +150,16 @@ def get_package_update_list(package_name, version): # Keep track of versions that could not be recognized as semantic non_semantic_versions.append({'version': release, 'upload_time': upload_time}) + if version_data: + current_release = version_data['info']['version'] + current_release_license = version_data['info']['license'] if version_data['info']['license'] else '' + # Get number of newer releases available for the given package newer_releases = len(major_updates + minor_updates + patch_updates) return { + 'current_release': current_release, + 'current_release_license': current_release_license, 'latest_release': latest_release, 'latest_release_license': latest_release_license, 'newer_releases': newer_releases, diff --git a/updatable/__version__.py b/updatable/__version__.py index 055551e..3e129c8 100644 --- a/updatable/__version__.py +++ b/updatable/__version__.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- -__version__ = "0.1.5" +__version__ = "0.2.0"