Skip to content

Commit

Permalink
Resolved an issue where the LDF selected an incorrect library version…
Browse files Browse the repository at this point in the history
… // Resolve #4860
  • Loading branch information
ivankravets committed Feb 13, 2024
1 parent 2239616 commit e1ff9a4
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 11 deletions.
3 changes: 2 additions & 1 deletion HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ test-driven methodologies, and modern toolchains for unrivaled success.
~~~~~~~~~~~~~~~~~~~

* Broadened version support for the ``pyelftools`` dependency, enabling compatibility with lower versions and facilitating integration with a wider range of third-party tools (`issue #4834 <https://github.com/platformio/platformio-core/issues/4834>`_)
* Resolved an issue related to the relative package path in the `pio pkg publish <https://docs.platformio.org/en/latest/core/userguide/pkg/cmd_publish.html>`__ command
* Addressed an issue where passing a relative path (``--project-dir``) to the `pio project init <https://docs.platformio.org/en/latest/core/userguide/project/cmd_init.html>`__ command resulted in an error (`issue #4847 <https://github.com/platformio/platformio-core/issues/4847>`_)
* Resolved an issue related to the relative package path in the `pio pkg publish <https://docs.platformio.org/en/latest/core/userguide/pkg/cmd_publish.html>`__ command
* Resolved an issue where the |LDF| selected an incorrect library version (`issue #4860 <https://github.com/platformio/platformio-core/issues/4860>`_)

6.1.13 (2024-01-12)
~~~~~~~~~~~~~~~~~~~
Expand Down
17 changes: 14 additions & 3 deletions platformio/builder/tools/piolib.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,10 @@ def process_dependencies(self):
if not self.dependencies or self._deps_are_processed:
return
self._deps_are_processed = True
for item in self.dependencies:
for dependency in self.dependencies:
found = False
for lb in self.env.GetLibBuilders():
if item["name"] != lb.name:
if not lb.is_dependency_compatible(dependency):
continue
found = True
if lb not in self.depbuilders:
Expand All @@ -322,9 +322,20 @@ def process_dependencies(self):
if not found and self.verbose:
sys.stderr.write(
"Warning: Ignored `%s` dependency for `%s` "
"library\n" % (item["name"], self.name)
"library\n" % (dependency["name"], self.name)
)

def is_dependency_compatible(self, dependency):
pkg = PackageItem(self.path)
qualifiers = {"name": self.name, "version": self.version}
if pkg.metadata:
qualifiers = {"name": pkg.metadata.name, "version": pkg.metadata.version}
if pkg.metadata.spec and pkg.metadata.spec.owner:
qualifiers["owner"] = pkg.metadata.spec.owner
return PackageCompatibility.from_dependency(dependency).is_compatible(
PackageCompatibility(**qualifiers)
)

def get_search_files(self):
return [
os.path.join(self.src_dir, item)
Expand Down
6 changes: 5 additions & 1 deletion platformio/package/manager/_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ def _install(
pkg = self.install_from_registry(
spec,
search_qualifiers=(
compatibility.to_search_qualifiers() if compatibility else None
compatibility.to_search_qualifiers(
["platforms", "frameworks", "authors"]
)
if compatibility
else None
),
)

Expand Down
45 changes: 39 additions & 6 deletions platformio/package/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ def from_archive(cls, path):


class PackageCompatibility:
KNOWN_QUALIFIERS = ("platforms", "frameworks", "authors")
KNOWN_QUALIFIERS = (
"owner",
"name",
"version",
"platforms",
"frameworks",
"authors",
)

@classmethod
def from_dependency(cls, dependency):
Expand All @@ -89,19 +96,45 @@ def __init__(self, **kwargs):
def __repr__(self):
return "PackageCompatibility <%s>" % self.qualifiers

def to_search_qualifiers(self):
return self.qualifiers
def to_search_qualifiers(self, fields=None):
result = {}
for name, value in self.qualifiers.items():
if not fields or name in fields:
result[name] = value
return result

def is_compatible(self, other):
assert isinstance(other, PackageCompatibility)
for key, value in self.qualifiers.items():
for key, current_value in self.qualifiers.items():
other_value = other.qualifiers.get(key)
if not value or not other_value:
if not current_value or not other_value:
continue
if any(isinstance(v, list) for v in (current_value, other_value)):
if not items_in_list(current_value, other_value):
return False
continue
if key == "version":
if not self._compare_versions(current_value, other_value):
return False
continue
if not items_in_list(value, other_value):
if current_value != other_value:
return False
return True

def _compare_versions(self, current, other):
if current == other:
return True
try:
version = (
other
if isinstance(other, semantic_version.Version)
else cast_version_to_semver(other)
)
return version in semantic_version.SimpleSpec(current)
except ValueError:
pass
return False


class PackageOutdatedResult:
UPDATE_INCREMENT_MAJOR = "major"
Expand Down

0 comments on commit e1ff9a4

Please sign in to comment.