diff --git a/platformio/managers/lib.py b/platformio/managers/lib.py index 48cba9b5..ef00787b 100644 --- a/platformio/managers/lib.py +++ b/platformio/managers/lib.py @@ -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: diff --git a/platformio/managers/package.py b/platformio/managers/package.py index e8e6dfdd..934a2e13 100644 --- a/platformio/managers/package.py +++ b/platformio/managers/package.py @@ -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'] diff --git a/tests/test_managers.py b/tests/test_managers.py index 74bd652f..559c9d29 100644 --- a/tests/test_managers.py +++ b/tests/test_managers.py @@ -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",