From 42d607ba5dca13ff425e20de05074d9564908fee Mon Sep 17 00:00:00 2001 From: Ryan Fox Date: Sun, 22 Aug 2021 00:21:00 +0000 Subject: [PATCH] Check PyPI packages --- pkgcrap/outdated_check.py | 94 ++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 35 deletions(-) diff --git a/pkgcrap/outdated_check.py b/pkgcrap/outdated_check.py index 5c22431..b1f4406 100644 --- a/pkgcrap/outdated_check.py +++ b/pkgcrap/outdated_check.py @@ -3,6 +3,7 @@ import urllib.request import pkgcrap.parse as parse +import json from pkgcrap.util import maintained_packages_get from functools import cmp_to_key from libversion import version_compare @@ -10,28 +11,33 @@ from libversion import version_compare def guess_repo(uri): forges = [ ('git', 'https://github.com', True), - ('https://gitlab.com', True), - ('https://git.sr.ht', False), + ('git', 'https://gitlab.com', True), + ('git', 'https://git.sr.ht', False), + ('pypi', 'mirror://pypi', False), ] for forge in forges: - if uri.startswith(forge[0]): - suffix = '.git' if forge[1] == True else '' - return '/'.join(uri.split('/')[:5])+suffix + if uri.startswith(forge[1]): + if forge[0] == 'git': + suffix = '.git' if forge[2] == True else '' + return (forge[0], '/'.join(uri.split('/')[:5])+suffix) + if forge[0] == 'pypi': + return (forge[0], uri.split('/')[4]) return None -def repo_from_metadata(pkg): - if len(pkg.metadata.remotes) == 0: - return None - remote = pkg.metadata.remotes[0] - if remote[0] == 'github': - return "https://github.com/"+remote[1]+".git" - if remote[0] == 'gitlab': - return "https://gitlab.com/"+remote[1]+".git" - return None +def repos_from_metadata(pkg): + remotes = [] + for remote in pkg.metadata.remotes: + if remote[0] == 'github': + remotes.append(('git', 'https://github.com/'+remote[1]+'.git')) + if remote[0] == 'gitlab': + remotes.append(('git', 'https://gitlab.com/'+remote[1]+'.git')) + if remote[0] == 'pypi': + remotes.append(('pypi', remote[1])) + return remotes def repo_from_egit_uri(pkg): if 'EGIT_REPO_URI' in pkg.ebuilds[0].vars: - return pkg.ebuilds[0].vars['EGIT_REPO_URI'].replace('${PN}', pkg.name) + return ('git', pkg.ebuilds[0].vars['EGIT_REPO_URI'].replace('${PN}', pkg.name)) def repo_from_src_uri(pkg): for eb in pkg.ebuilds: @@ -43,21 +49,20 @@ def repo_from_homepage(pkg): if 'HOMEPAGE' in eb.vars: return guess_repo(eb.vars['HOMEPAGE']) -def repo_from_pkg(pkg): - repo = repo_from_metadata(pkg) - if repo is None: - repo = repo_from_egit_uri(pkg) - if repo is None: - repo = repo_from_src_uri(pkg) - if repo is None: - repo = repo_from_homepage(pkg) - return repo +def repos_from_pkg(pkg): + repos = [] + repos += repos_from_metadata(pkg) + repos.append(repo_from_egit_uri(pkg)) + repos.append(repo_from_src_uri(pkg)) + repos.append(repo_from_homepage(pkg)) + return [repo for repo in repos if repo != None] -def repo_get_latest(repo, pkg): +def repo_get_latest_git(uri, pkg, verbose): try: - r = urllib.request.urlopen(repo+'/info/refs?service=git-upload-pack') + r = urllib.request.urlopen(uri+'/info/refs?service=git-upload-pack') except urllib.error.HTTPError: - print(pkg.full_name+':', 'Invalid repo!', repo) + if verbose: + print(pkg.full_name+':', 'Invalid repo!', uri) return None tags = [] for line in reversed(r.read().decode('utf-8').split("\n")): @@ -78,26 +83,45 @@ def repo_get_latest(repo, pkg): return None return latest +def repo_get_latest_pypi(uri, pkg, verbose): + try: + r = urllib.request.urlopen('https://pypi.org/pypi/'+uri+'/json') + except urllib.error.HTTPError: + if verbose: + print(pkg.full_name+':', 'Invalid PyPI package!', uri) + return None + return list(json.load(r)['releases'].keys())[-1] + +def repo_get_latest(repo, pkg, verbose): + if repo[0] == 'git': + return repo_get_latest_git(repo[1], pkg, verbose) + if repo[0] == 'pypi': + return repo_get_latest_pypi(repo[1], pkg, verbose) + return None + def outdated_check(pkg, verbose=False): if len(pkg.ebuilds) == 1 and pkg.ebuilds[0].live: if verbose: print(pkg.full_name+':', 'Only has live ebuild') return - repo = repo_from_pkg(pkg) - if repo == None: + repos = repos_from_pkg(pkg) + if len(repos) == 0: if verbose: print(pkg.full_name+':', 'Repo not found') return current = pkg.version_latest() - latest = repo_get_latest(repo, pkg) + for repo in repos: + latest = repo_get_latest(repo, pkg, verbose) + if latest != None: + break if latest == None: if verbose: print(pkg.full_name+':', 'Unable to find latest version!') - return - if version_compare(current, latest) == -1: - print(pkg.full_name+':', 'Outdated package!', current, '->', latest) - elif verbose: - print(pkg.full_name+':', 'Up to date!', current, '->', latest) + else: + if version_compare(current, latest) == -1: + print(pkg.full_name+':', 'Outdated package!', current, '->', latest) + elif verbose: + print(pkg.full_name+':', 'Up to date!', current, '->', latest) def main(args): if 'all' in args: