mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-29 17:47:14 +02:00
Improve support for partial package versions
This commit is contained in:
@ -21,7 +21,6 @@ from os.path import isdir, join
|
||||
|
||||
import arrow
|
||||
import click
|
||||
import semantic_version
|
||||
|
||||
from platformio import app, commands, exception, util
|
||||
from platformio.managers.package import BasePkgManager
|
||||
@ -153,8 +152,7 @@ class LibraryManager(BasePkgManager):
|
||||
]
|
||||
return items
|
||||
|
||||
@staticmethod
|
||||
def max_satisfying_repo_version(versions, requirements=None):
|
||||
def max_satisfying_repo_version(self, versions, requirements=None):
|
||||
|
||||
def _cmp_dates(datestr1, datestr2):
|
||||
date1 = arrow.get(datestr1)
|
||||
@ -163,29 +161,22 @@ class LibraryManager(BasePkgManager):
|
||||
return 0
|
||||
return -1 if date1 < date2 else 1
|
||||
|
||||
semver_spec = self.parse_semver_spec(
|
||||
requirements) if requirements else None
|
||||
item = None
|
||||
reqspec = None
|
||||
if requirements:
|
||||
try:
|
||||
reqspec = semantic_version.Spec(requirements)
|
||||
except ValueError:
|
||||
pass
|
||||
for v in versions:
|
||||
specver = None
|
||||
try:
|
||||
specver = semantic_version.Version(v['name'], partial=True)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if reqspec:
|
||||
if not specver or specver not in reqspec:
|
||||
for v in versions:
|
||||
semver_new = self.parse_semver_version(v['name'])
|
||||
if semver_spec:
|
||||
if not semver_new or semver_new not in semver_spec:
|
||||
continue
|
||||
if not item or semantic_version.Version(
|
||||
item['name'], partial=True) < specver:
|
||||
if not item or self.parse_semver_version(
|
||||
item['name']) < semver_new:
|
||||
item = v
|
||||
elif requirements:
|
||||
if requirements == v['name']:
|
||||
return v
|
||||
|
||||
else:
|
||||
if not item or _cmp_dates(item['released'],
|
||||
v['released']) == -1:
|
||||
|
@ -191,6 +191,27 @@ class PkgInstallerMixin(object):
|
||||
with FileUnpacker(source_path) as fu:
|
||||
return fu.unpack(dest_dir)
|
||||
|
||||
@staticmethod
|
||||
def parse_semver_spec(value, raise_exception=False):
|
||||
try:
|
||||
return semantic_version.Spec(value)
|
||||
except ValueError as e:
|
||||
if raise_exception:
|
||||
raise e
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def parse_semver_version(value, raise_exception=False):
|
||||
try:
|
||||
try:
|
||||
return semantic_version.Version(value)
|
||||
except ValueError:
|
||||
return semantic_version.Version.coerce(value)
|
||||
except ValueError as e:
|
||||
if raise_exception:
|
||||
raise e
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_install_dirname(manifest):
|
||||
name = re.sub(r"[^\da-z\_\-\. ]", "_", manifest['name'], flags=re.I)
|
||||
@ -290,15 +311,15 @@ class PkgInstallerMixin(object):
|
||||
return manifest
|
||||
|
||||
try:
|
||||
if requirements and not semantic_version.Spec(
|
||||
requirements).match(
|
||||
semantic_version.Version(
|
||||
manifest['version'], partial=True)):
|
||||
if requirements and not self.parse_semver_spec(
|
||||
requirements, raise_exception=True).match(
|
||||
self.parse_semver_version(
|
||||
manifest['version'], raise_exception=True)):
|
||||
continue
|
||||
elif not best or (semantic_version.Version(
|
||||
manifest['version'], partial=True) >
|
||||
semantic_version.Version(
|
||||
best['version'], partial=True)):
|
||||
elif not best or (self.parse_semver_version(
|
||||
manifest['version'], raise_exception=True) >
|
||||
self.parse_semver_version(
|
||||
best['version'], raise_exception=True)):
|
||||
best = manifest
|
||||
except ValueError:
|
||||
pass
|
||||
@ -406,16 +427,10 @@ class PkgInstallerMixin(object):
|
||||
pkg_dir = join(self.package_dir, pkg_dirname)
|
||||
cur_manifest = self.load_manifest(pkg_dir)
|
||||
|
||||
tmp_semver = None
|
||||
tmp_semver = self.parse_semver_version(tmp_manifest['version'])
|
||||
cur_semver = None
|
||||
try:
|
||||
tmp_semver = semantic_version.Version(
|
||||
tmp_manifest['version'], partial=True)
|
||||
if cur_manifest:
|
||||
cur_semver = semantic_version.Version(
|
||||
cur_manifest['version'], partial=True)
|
||||
except ValueError:
|
||||
pass
|
||||
if cur_manifest:
|
||||
cur_semver = self.parse_semver_version(cur_manifest['version'])
|
||||
|
||||
# package should satisfy requirements
|
||||
if requirements:
|
||||
@ -591,8 +606,10 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
|
||||
up_to_date = False
|
||||
try:
|
||||
assert "__src_url" not in manifest
|
||||
up_to_date = (semantic_version.Version.coerce(manifest['version'])
|
||||
>= semantic_version.Version.coerce(latest))
|
||||
up_to_date = (self.parse_semver_version(
|
||||
manifest['version'], raise_exception=True) >=
|
||||
self.parse_semver_version(
|
||||
latest, raise_exception=True))
|
||||
except (AssertionError, ValueError):
|
||||
up_to_date = latest == manifest['version']
|
||||
|
||||
|
@ -156,7 +156,7 @@ def test_install_packages(isolated_pio_home, tmpdir):
|
||||
dict(id=1, name="name_1", version="shasum"),
|
||||
dict(id=1, name="name_1", version="2.0.0"),
|
||||
dict(id=1, name="name_1", version="2.1.0"),
|
||||
dict(id=1, name="name_1", version="1.2.0"),
|
||||
dict(id=1, name="name_1", version="1.2"),
|
||||
dict(id=1, name="name_1", version="1.0.0"),
|
||||
dict(name="name_2", version="1.0.0"),
|
||||
dict(name="name_2", version="2.0.0",
|
||||
@ -177,7 +177,7 @@ def test_install_packages(isolated_pio_home, tmpdir):
|
||||
assert len(pm.get_installed()) == len(packages) - 1
|
||||
|
||||
pkg_dirnames = [
|
||||
'name_1_ID1', 'name_1_ID1@1.0.0', 'name_1_ID1@1.2.0',
|
||||
'name_1_ID1', 'name_1_ID1@1.0.0', 'name_1_ID1@1.2',
|
||||
'name_1_ID1@2.0.0', 'name_1_ID1@shasum', 'name_2',
|
||||
'name_2@src-177cbce1f0705580d17790fda1cc2ef5',
|
||||
'name_2@src-f863b537ab00f4c7b5011fc44b120e1f'
|
||||
@ -192,12 +192,11 @@ def test_get_package(isolated_pio_home):
|
||||
[("1", ), None],
|
||||
[("id=1", "shasum"), dict(id=1, name="name_1", version="shasum")],
|
||||
[("id=1", "*"), dict(id=1, name="name_1", version="2.1.0")],
|
||||
[("id=1", "^1"), dict(id=1, name="name_1", version="1.2.0")],
|
||||
[("id=1", "^1"), dict(id=1, name="name_1", version="1.2.0")],
|
||||
[("name_1", "<2"), dict(id=1, name="name_1", version="1.2.0")],
|
||||
[("id=1", "^1"), dict(id=1, name="name_1", version="1.2")],
|
||||
[("id=1", "^1"), dict(id=1, name="name_1", version="1.2")],
|
||||
[("name_1", "<2"), dict(id=1, name="name_1", version="1.2")],
|
||||
[("name_1", ">2"), None],
|
||||
[("name_1", "2-0-0"), dict(id=1, name="name_1", version="2.1.0")],
|
||||
[("name_1", "2-0-0"), dict(id=1, name="name_1", version="2.1.0")],
|
||||
[("name_1", "2-0-0"), None],
|
||||
[("name_2", ), dict(name="name_2", version="4.0.0")],
|
||||
[("url_has_higher_priority", None, "git+https://github.com"),
|
||||
dict(name="name_2", version="2.0.0",
|
||||
|
Reference in New Issue
Block a user