diff mbox series

[layerindex-web] layerindex/utils.py: import bb in is_deps_satisfied()

Message ID 20261018230639.88187-1-tim.orling@konsulko.com
State New
Headers show
Series [layerindex-web] layerindex/utils.py: import bb in is_deps_satisfied() | expand

Commit Message

Tim Orling Oct. 18, 2026, 11:06 p.m. UTC
is_deps_satisfied() calls bb.utils.vercmp_string_op() to check a
versioned dependency such as LAYERDEPENDS_foo = "core (>= 12)", but
utils.py never imports bb at module level: the import in
explode_dep_versions2() only binds bb inside that function. So as soon as
any layer had a versioned dependency on a collection with a
LAYERVERSION, update.py stopped while sorting the layers, before
updating any of them:

  File "layerindex/update.py", line 513, in main
    if utils.is_deps_satisfied(req_col, req_ver, collections):
  File "layerindex/utils.py", line 72, in is_deps_satisfied
    success = bb.utils.vercmp_string_op(existed_ver, dep_version, op)
  NameError: name 'bb' is not defined

Import bb.utils where it is used, as the other functions here do; by
then explode_dep_versions2() has put BitBake's lib directory on
sys.path.

AI-Generated: Claude Opus 5.5
Signed-off-by: Tim Orling <tim.orling@konsulko.com>
---
 layerindex/utils.py |  3 +++
 tests/test_utils.py | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)
 create mode 100644 tests/test_utils.py
diff mbox series

Patch

diff --git a/layerindex/utils.py b/layerindex/utils.py
index 7e7ebe4..e5bad40 100644
--- a/layerindex/utils.py
+++ b/layerindex/utils.py
@@ -68,6 +68,9 @@  def is_deps_satisfied(req_col, req_ver, collections):
                 # If there is no version in the found layer, then don't use this layer.
                 if not existed_ver:
                     continue
+                # bb is not imported at module level; by now
+                # explode_dep_versions2() has put BitBake's lib on sys.path
+                import bb.utils
                 (op, dep_version) = req_ver.split()
                 success = bb.utils.vercmp_string_op(existed_ver, dep_version, op)
                 if success:
diff --git a/tests/test_utils.py b/tests/test_utils.py
new file mode 100644
index 0000000..2b9ebcb
--- /dev/null
+++ b/tests/test_utils.py
@@ -0,0 +1,42 @@ 
+# layerindex-web - tests for layerindex/utils.py
+#
+# Licensed under the MIT license, see COPYING.MIT for details
+#
+# SPDX-License-Identifier: MIT
+
+import operator
+import sys
+import types
+
+import pytest
+
+from layerindex import utils
+
+
+@pytest.fixture
+def fake_bb(monkeypatch):
+    """A stand-in for BitBake's bb.utils, which update.py imports from the
+    BitBake checkout at runtime. Versions here are plain integers."""
+    ops = {'>=': operator.ge, '>': operator.gt, '=': operator.eq, '<=': operator.le, '<': operator.lt}
+    bb = types.ModuleType('bb')
+    bb.utils = types.ModuleType('bb.utils')
+    bb.utils.vercmp_string_op = lambda a, b, op: ops[op](int(a), int(b))
+    monkeypatch.setitem(sys.modules, 'bb', bb)
+    monkeypatch.setitem(sys.modules, 'bb.utils', bb.utils)
+
+
+@pytest.mark.parametrize('req_ver, collections, expected', [
+    # No version constraint: any matching collection will do
+    (None, {('core', '15')}, True),
+    (None, {('core', '')}, True),
+    # Versioned constraint against the collection's LAYERVERSION
+    ('>= 12', {('core', '15')}, True),
+    ('>= 16', {('core', '15')}, False),
+    ('= 15', {('core', '15')}, True),
+    # A collection without a version can't satisfy a versioned constraint
+    ('>= 12', {('core', '')}, False),
+    # Other collections don't count
+    ('>= 12', {('other', '15')}, False),
+])
+def test_is_deps_satisfied(fake_bb, req_ver, collections, expected):
+    assert utils.is_deps_satisfied('core', req_ver, collections) is expected