From f8d0e587e490a96020fcc819d3d147caffb0c6e3 Mon Sep 17 00:00:00 2001 From: Brandon Siegel Date: Thu, 27 Jun 2019 16:17:08 -0700 Subject: [PATCH] Use pkg_resources to parse requirements --- scripts/analyze_deps.py | 46 +++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/scripts/analyze_deps.py b/scripts/analyze_deps.py index e06515ed4000..2d1adbd65d5e 100755 --- a/scripts/analyze_deps.py +++ b/scripts/analyze_deps.py @@ -6,6 +6,7 @@ import glob import io import os +from pkg_resources import Requirement import re import sys import textwrap @@ -27,6 +28,24 @@ def locate_wheels(base_dir): wheels = glob.glob(os.path.join(base_dir, '*.whl')) return sorted(wheels) +def parse_req(req): + try: + req_object = Requirement.parse(req) + req_name = req_object.key + spec = str(req_object).replace(req_name, '') + return (req_name, spec) + except: + print('Failed to parse requirement %s' % (req)) + +def record_dep(dependencies, req, lib_name): + req_name, spec = parse_req(req) + if not req_name in dependencies: + dependencies[req_name] = {} + if not spec in dependencies[req_name]: + dependencies[req_name][spec] = [] + dependencies[req_name][spec].append(lib_name) + + def get_lib_deps(base_dir): packages = {} dependencies = {} @@ -44,15 +63,7 @@ def get_lib_deps(base_dir): } for req in requires: - req_parts = re.split('([<>~=]+)', req, 1) - req_name = req_parts[0] - spec = ''.join(req_parts[1:]) - spec = ','.join(sorted(spec.split(','))) - if not req_name in dependencies: - dependencies[req_name] = {} - if not spec in dependencies[req_name]: - dependencies[req_name][spec] = [] - dependencies[req_name][spec].append(lib_name) + record_dep(dependencies, req, lib_name) except: print('Failed to parse %s' % (setup_path)) return packages, dependencies @@ -61,7 +72,6 @@ def get_wheel_deps(wheel_dir): from wheel.pkginfo import read_pkg_info_bytes from wheel.wheelfile import WheelFile - requires_dist_re = re.compile(r"""^(?P\S+)(\s\((?P.+)\))?$""") packages = {} dependencies = {} for whl_path in locate_wheels(wheel_dir): @@ -79,14 +89,8 @@ def get_wheel_deps(wheel_dir): requires = pkg_info.get_all('Requires-Dist') for req in requires: - parsed = requires_dist_re.match(req.split(';')[0].strip()) - req_name, spec = parsed.group('name', 'spec') - spec = ','.join(sorted(spec.split(','))) if spec else '' - if not req_name in dependencies: - dependencies[req_name] = {} - if not spec in dependencies[req_name]: - dependencies[req_name][spec] = [] - dependencies[req_name][spec].append(lib_name) + req = re.sub(r'[\s\(\)]', '', req) + record_dep(dependencies, req, lib_name) except: print('Failed to parse METADATA from %s' % (whl_path)) return packages, dependencies @@ -241,9 +245,7 @@ def render_report(output_path, report_context): try: with open(frozen_filename, 'r') as frozen_file: for line in frozen_file: - req_parts = re.split('([<>~=]+)', line.strip(), 1) - req_name = req_parts[0] - spec = ''.join(req_parts[1:]) + req_name, spec = parse_req(line) frozen[req_name] = [spec] except: print('Unable to open shared_requirements.txt, shared requirements have not been validated') @@ -307,4 +309,4 @@ def display_order(k): elif not args.verbose: print('Library dependencies do not match frozen requirements, run this script with --verbose for details') - sys.exit(exitcode) \ No newline at end of file + sys.exit(exitcode)