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