diff mbox series

[layerindex-web] layerindex: expand recursive dependencies from the right layer branch

Message ID 20261025020912.90595-1-tim.orling@konsulko.com
State New
Headers show
Series [layerindex-web] layerindex: expand recursive dependencies from the right layer branch | expand

Commit Message

Tim Orling Oct. 25, 2026, 2:09 a.m. UTC
The Expand button on the layer page fetches each dependency's own
dependencies by LayerBranch id, but the list items held the
dependency's LayerItem id, so the first level of the tree came from
an unrelated layer branch, or was empty. Use the dependency's layer
branch on the current branch instead, and start cycle detection with
the layer itself.

[YOCTO #12599]

AI-Generated: Claude Opus 5.5
Signed-off-by: Tim Orling <tim.orling@konsulko.com>
---
 layerindex/models.py             |  4 ++++
 templates/layerindex/detail.html |  4 ++--
 tests/test_layer_dependencies.py | 41 ++++++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 2 deletions(-)
 create mode 100644 tests/test_layer_dependencies.py
diff mbox series

Patch

diff --git a/layerindex/models.py b/layerindex/models.py
index 425af53..1d72c55 100644
--- a/layerindex/models.py
+++ b/layerindex/models.py
@@ -409,6 +409,10 @@  class LayerDependency(models.Model):
     def __str__(self):
         return "%s depends on %s" % (self.layerbranch.layer.name, self.dependency.name)
 
+    def dependency_layerbranch(self):
+        """Return the dependency's LayerBranch on the same branch, if any"""
+        return LayerBranch.objects.filter(layer=self.dependency, branch_id=self.layerbranch.branch_id).first()
+
 
 class LayerNote(models.Model):
     layer = models.ForeignKey(LayerItem, on_delete=models.CASCADE)
diff --git a/templates/layerindex/detail.html b/templates/layerindex/detail.html
index 9ab6bf6..6c20f47 100644
--- a/templates/layerindex/detail.html
+++ b/templates/layerindex/detail.html
@@ -166,7 +166,7 @@ 
                                 <p>The {{ layeritem.name }} layer depends upon:</p>
                                 <ul id="dependencies_list">
                                     {% for dep in layerbranch.get_required %}
-                                        <li data-layerbranch="{{ dep.dependency.id }}">
+                                        <li data-layerbranch="{{ dep.dependency_layerbranch.id }}">
                                             <a href="{% url 'layer_item' url_branch dep.dependency.name %}">{{ dep.dependency.name }}</a>
                                         </li>
                                     {% endfor %}
@@ -540,7 +540,7 @@ 
 
                     var layerBranchId = $(this).data('layerbranch');
 
-                    $(this).append(expandLayerDependencies(layerBranchId, []));
+                    $(this).append(expandLayerDependencies(layerBranchId, [{{ layerbranch.id }}]));
                 });
             });
 
diff --git a/tests/test_layer_dependencies.py b/tests/test_layer_dependencies.py
new file mode 100644
index 0000000..1dd8250
--- /dev/null
+++ b/tests/test_layer_dependencies.py
@@ -0,0 +1,41 @@ 
+# layerindex-web - tests for showing layer dependencies
+#
+# Licensed under the MIT license, see COPYING.MIT for details
+#
+# SPDX-License-Identifier: MIT
+
+import pytest
+from django.test import TestCase
+from django.urls import reverse
+
+from layerindex.models import Branch, LayerBranch, LayerDependency, LayerItem
+
+
+@pytest.mark.django_db
+class TestLayerDependencies(TestCase):
+
+    def make_layer(self, name):
+        return LayerItem.objects.create(name=name, status='P', layer_type='A',
+                                        summary='test', description='test',
+                                        vcs_url='git://example.com/%s.git' % name)
+
+    def setUp(self):
+        master, _ = Branch.objects.get_or_create(name='master', defaults={'bitbake_branch': 'master'})
+        other = Branch.objects.create(name='other', bitbake_branch='master')
+        top = self.make_layer('meta-top')
+        dep = self.make_layer('meta-dep')
+        # Create layer branches on another branch first, so that meta-dep's
+        # LayerItem and LayerBranch ids differ
+        LayerBranch.objects.create(layer=top, branch=other)
+        LayerBranch.objects.create(layer=dep, branch=other)
+        self.dep_layerbranch = LayerBranch.objects.create(layer=dep, branch=master)
+        top_layerbranch = LayerBranch.objects.create(layer=top, branch=master)
+        self.dependency = LayerDependency.objects.create(layerbranch=top_layerbranch, dependency=dep)
+        self.assertNotEqual(dep.id, self.dep_layerbranch.id)
+
+    def test_dependency_layerbranch(self):
+        self.assertEqual(self.dependency.dependency_layerbranch(), self.dep_layerbranch)
+
+    def test_detail_page_lists_dependency_layerbranch(self):
+        response = self.client.get(reverse('layer_item', args=('master', 'meta-top')))
+        self.assertContains(response, '<li data-layerbranch="%d">' % self.dep_layerbranch.id)