|
2 | 2 | import inspect
|
3 | 3 | import operator
|
4 | 4 | import os
|
5 |
| -import re |
6 |
| -import pkg_resources |
7 |
| -import platform |
8 | 5 | import shutil
|
9 | 6 | import stat
|
| 7 | +import sys |
10 | 8 | from pathlib import Path
|
11 | 9 |
|
| 10 | +import tomli |
12 | 11 | from invoke import task
|
13 |
| - |
| 12 | +from packaging.requirements import Requirement |
| 13 | +from packaging.version import Version |
14 | 14 |
|
15 | 15 | COMPARISONS = {
|
16 | 16 | '>=': operator.ge,
|
@@ -39,49 +39,45 @@ def unit(c):
|
39 | 39 | c.run('python -m pytest ./tests/unit --reruns 3')
|
40 | 40 |
|
41 | 41 |
|
42 |
| -def _validate_python_version(line): |
43 |
| - is_valid = True |
44 |
| - for python_version_match in re.finditer(r"python_version(<=?|>=?|==)\'(\d\.?)+\'", line): |
45 |
| - python_version = python_version_match.group(0) |
46 |
| - comparison = re.search(r'(>=?|<=?|==)', python_version).group(0) |
47 |
| - version_number = python_version.split(comparison)[-1].replace("'", "") |
48 |
| - comparison_function = COMPARISONS[comparison] |
49 |
| - is_valid = is_valid and comparison_function( |
50 |
| - pkg_resources.parse_version(platform.python_version()), |
51 |
| - pkg_resources.parse_version(version_number), |
52 |
| - ) |
| 42 | +def _get_minimum_versions(dependencies, python_version): |
| 43 | + min_versions = {} |
| 44 | + for dependency in dependencies: |
| 45 | + if '@' in dependency: |
| 46 | + name, url = dependency.split(' @ ') |
| 47 | + min_versions[name] = f'{name} @ {url}' |
| 48 | + continue |
| 49 | + |
| 50 | + req = Requirement(dependency) |
| 51 | + if ';' in dependency: |
| 52 | + marker = req.marker |
| 53 | + if marker and not marker.evaluate({'python_version': python_version}): |
| 54 | + continue # Skip this dependency if the marker does not apply to the current Python version |
| 55 | + |
| 56 | + if req.name not in min_versions: |
| 57 | + min_version = next((spec.version for spec in req.specifier if spec.operator in ('>=', '==')), None) |
| 58 | + if min_version: |
| 59 | + min_versions[req.name] = f'{req.name}=={min_version}' |
53 | 60 |
|
54 |
| - return is_valid |
| 61 | + elif '@' not in min_versions[req.name]: |
| 62 | + existing_version = Version(min_versions[req.name].split('==')[1]) |
| 63 | + new_version = next((spec.version for spec in req.specifier if spec.operator in ('>=', '==')), existing_version) |
| 64 | + if new_version > existing_version: |
| 65 | + min_versions[req.name] = f'{req.name}=={new_version}' # Change when a valid newer version is found |
| 66 | + |
| 67 | + return list(min_versions.values()) |
55 | 68 |
|
56 | 69 |
|
57 | 70 | @task
|
58 | 71 | def install_minimum(c):
|
59 |
| - with open('pyproject.toml', 'r') as pyproject: |
60 |
| - lines = pyproject.read().splitlines() |
61 |
| - |
62 |
| - versions = [] |
63 |
| - started = False |
64 |
| - for line in lines: |
65 |
| - if started: |
66 |
| - if line == ']': |
67 |
| - started = False |
68 |
| - continue |
69 |
| - |
70 |
| - line = line.strip() |
71 |
| - if _validate_python_version(line): |
72 |
| - requirement = re.match(r'[^>]*', line).group(0) |
73 |
| - requirement = re.sub(r"""['",]""", '', requirement) |
74 |
| - version = re.search(r'>=?(\d\.?)+\w*', line).group(0) |
75 |
| - if version: |
76 |
| - version = re.sub(r'>=?', '==', version) |
77 |
| - version = re.sub(r"""['",]""", '', version) |
78 |
| - requirement += version |
79 |
| - versions.append(requirement) |
80 |
| - |
81 |
| - elif (line.startswith('dependencies = [')): |
82 |
| - started = True |
83 |
| - |
84 |
| - c.run(f'python -m pip install {" ".join(versions)}') |
| 72 | + with open('pyproject.toml', 'rb') as pyproject_file: |
| 73 | + pyproject_data = tomli.load(pyproject_file) |
| 74 | + |
| 75 | + dependencies = pyproject_data.get('project', {}).get('dependencies', []) |
| 76 | + python_version = '.'.join(map(str, sys.version_info[:2])) |
| 77 | + minimum_versions = _get_minimum_versions(dependencies, python_version) |
| 78 | + |
| 79 | + if minimum_versions: |
| 80 | + c.run(f'python -m pip install {" ".join(minimum_versions)}') |
85 | 81 |
|
86 | 82 |
|
87 | 83 | @task
|
|
0 commit comments