diff mbox series

[layerindex-web] Add 'local' files to "Sources"

Message ID 20260625200450.93797-2-tim.orling@konsulko.com
State New
Headers show
Series [layerindex-web] Add 'local' files to "Sources" | expand

Commit Message

Tim Orling June 25, 2026, 8:04 p.m. UTC
Previously, "local" URIs such as 'file://run-ptest' were
explicitly skipped. Add handling of 'file://' URIs for
the Source model (ignoring Patches as those were already
handled elsewhere).

Similar to "Recipe File" field, we display the layer path
to the file and provide a link to it.

Fixes: [Yocto #13757]

Signed-off-by: Tim Orling <tim.orling@konsulko.com>
---
 layerindex/migrations/0052_source_path.py | 16 +++++++++++
 layerindex/models.py                      |  5 ++++
 layerindex/update_layer.py                | 34 ++++++++++++++++++-----
 templates/layerindex/recipedetail.html    |  2 +-
 4 files changed, 49 insertions(+), 8 deletions(-)
 create mode 100644 layerindex/migrations/0052_source_path.py
diff mbox series

Patch

diff --git a/layerindex/migrations/0052_source_path.py b/layerindex/migrations/0052_source_path.py
new file mode 100644
index 0000000..8047947
--- /dev/null
+++ b/layerindex/migrations/0052_source_path.py
@@ -0,0 +1,16 @@ 
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('layerindex', '0051_fix_yoctoproject_cgit_urls'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='source',
+            name='path',
+            field=models.CharField(blank=True, max_length=255),
+        ),
+    ]
diff --git a/layerindex/models.py b/layerindex/models.py
index 864264b..eb7d8bf 100644
--- a/layerindex/models.py
+++ b/layerindex/models.py
@@ -531,12 +531,17 @@  class Source(models.Model):
     recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
     url = models.CharField(max_length=255)
     sha256sum = models.CharField(max_length=64, blank=True)
+    # Layer-relative path for local (file://) sources, used to link to the
+    # file in the layer's repository (empty for remote sources)
+    path = models.CharField(max_length=255, blank=True)
 
     def web_url(self):
         def drop_dotgit(url):
             if url.endswith('.git'):
                 url = url[:-4]
             return url
+        if self.path:
+            return self.recipe.layerbranch.file_url(self.path) or None
         if self.url and self.url.startswith(('http', 'ftp')):
             return self.url
         elif self.url.startswith('git://github.com'):
diff --git a/layerindex/update_layer.py b/layerindex/update_layer.py
index 33c5cfb..432201a 100644
--- a/layerindex/update_layer.py
+++ b/layerindex/update_layer.py
@@ -138,15 +138,35 @@  def update_recipe_file(tinfoil, data, path, recipe, layerdir_start, repodir, sto
         recipe.save()
 
         # Handle sources
+        import bb.fetch2
+        import oe.patch
         old_urls = list(recipe.source_set.values_list('url', flat=True))
-        for url in (envdata.getVar('SRC_URI', True) or '').split():
-            if not url.startswith('file://'):
+        srcfetch = bb.fetch2.Fetch([], envdata)
+        for url in srcfetch.urls:
+            # Patches are recorded separately (shown in the Patches section),
+            # so skip them here - but keep other local file:// entries
+            # (e.g. run-ptest, init scripts, config files) as sources.
+            if oe.patch.patch_path(url, srcfetch, '', expand=False):
+                continue
+            path = ''
+            if url.startswith('file://'):
+                # Show local files without the file:// scheme (e.g. run-ptest)
+                # and, if the file lives in this layer, record its path so we
+                # can link to it in the layer's repository.
+                try:
+                    localpath = srcfetch.localpath(url)
+                except bb.fetch2.FetchError:
+                    localpath = ''
+                if localpath and localpath.startswith(layerdir_start):
+                    path = os.path.relpath(localpath, layerdir_start)
+                url = url[7:].split(';')[0]
+            else:
                 url = url.split(';')[0]
-                if url in old_urls:
-                    old_urls.remove(url)
-                else:
-                    src = Source(recipe=recipe, url=url)
-                    src.save()
+            if url in old_urls:
+                old_urls.remove(url)
+            else:
+                src = Source(recipe=recipe, url=url, path=path)
+                src.save()
         for url in old_urls:
             recipe.source_set.filter(url=url).delete()
 
diff --git a/templates/layerindex/recipedetail.html b/templates/layerindex/recipedetail.html
index 6446386..5322758 100644
--- a/templates/layerindex/recipedetail.html
+++ b/templates/layerindex/recipedetail.html
@@ -163,7 +163,7 @@ 
                     <tbody>
                         {% for source in recipe.source_set.all %}
                         <tr>
-                            <td>{% if source.web_url %}<a href="{{ source.web_url }}">{% endif %}{{ source.url }}{% if source.web_url %}</a>{% endif %}</td>
+                            <td>{% if source.web_url %}<a href="{{ source.web_url }}">{% endif %}{{ source.path|default:source.url }}{% if source.web_url %}</a>{% endif %}</td>
                         </tr>
                         {% endfor %}
                     </tbody>