diff mbox series

[RFC,09/15] fetch2: make DOWNLOADFILENAME and PATH explicit in mirrors

Message ID 20250205080953.RFC.9.9dcddffa-7bd7-491b-8d33-ed0d255fa02e@changeid
State New
Headers show
Series Make mirror replacement syntax explicit | expand

Commit Message

Stefan Herbrechtsmeier Feb. 5, 2025, 7:15 a.m. UTC
From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

Make the DOWNLOADFILENAME and PATH replacement explicit in the mirrors
to support upstream and download mirrors. An upstream mirror expects the
original PATH whereas a download mirror requires the DOWNLOADFILENAME.

Don’t replace the last part of the PATH with the basename of the
downloaded filename. The downloadfilename parameter may contain
subfolders and a mirror may require the original PATH.

Add a preprocessing of the mirror replacement to support common
inexplicit use cases.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
---

 lib/bb/fetch2/__init__.py | 41 +++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 21 deletions(-)
diff mbox series

Patch

diff --git a/lib/bb/fetch2/__init__.py b/lib/bb/fetch2/__init__.py
index 2328a8fe3..7ec1b4b20 100644
--- a/lib/bb/fetch2/__init__.py
+++ b/lib/bb/fetch2/__init__.py
@@ -429,6 +429,21 @@  def uri_replace(ud, uri_find, uri_replace, replacements, d, mirrortarball=None):
     uri_decoded = list(decodeurl(ud.url))
     uri_find_decoded = list(decodeurl(uri_find))
     uri_replace_decoded = list(decodeurl(uri_replace))
+
+    # Fix mirror lines without PATH, BASENAME or DOWNLOADFILENAME
+    if (uri_find_decoded[0] == "file" and ".*" in uri_find_decoded[2]
+            and all({k not in uri_replace_decoded[2]
+                     for k in {"PATH", "BASENAME"}})):
+        uri_replace_decoded[2] = os.path.join(uri_replace_decoded[2], "PATH")
+    elif ((uri_replace_decoded[0].startswith("http")
+                or uri_replace_decoded[0] == "file")
+            and ((uri_decoded[0] != uri_replace_decoded[0] and mirrortarball)
+                    or ".*" in uri_find_decoded[2])
+            and all({k not in uri_replace_decoded[2]
+                     for k in {"PATH", "BASENAME", "DOWNLOADFILENAME"}})):
+        uri_replace_decoded[2] = os.path.join(uri_replace_decoded[2],
+                                              "DOWNLOADFILENAME")
+
     logger.debug2("For url %s comparing %s to %s" % (uri_decoded, uri_find_decoded, uri_replace_decoded))
     result_decoded = ['', '', '', '', '', {}]
     # 0 - type, 1 - host, 2 - path, 3 - user,  4- pswd, 5 - params
@@ -441,7 +456,10 @@  def uri_replace(ud, uri_find, uri_replace, replacements, d, mirrortarball=None):
             regexp += "$"
         if loc == 5:
             # Handle URL parameters
-            if i:
+            if uri_decoded[0] != uri_replace_decoded[0] and mirrortarball:
+                # Kill parameters, they make no sense for mirror tarballs
+                result_decoded[5] = {}
+            elif i:
                 # Any specified URL parameters must match
                 for k in uri_find_decoded[loc]:
                     if uri_decoded[loc][k] != uri_find_decoded[loc][k]:
@@ -462,26 +480,6 @@  def uri_replace(ud, uri_find, uri_replace, replacements, d, mirrortarball=None):
                     uri_replace_decoded[loc] = uri_replace_decoded[loc].replace(k, replacements[k])
                 #bb.note("%s %s %s" % (regexp, uri_replace_decoded[loc], uri_decoded[loc]))
                 result_decoded[loc] = re.sub(regexp, uri_replace_decoded[loc], uri_decoded[loc], count=1)
-            if loc == 2:
-                # Handle path manipulations
-                basename = None
-                if uri_decoded[0] != uri_replace_decoded[0] and mirrortarball:
-                    # If the source and destination url types differ, must be a mirrortarball mapping
-                    basename = os.path.basename(mirrortarball)
-                    # Kill parameters, they make no sense for mirror tarballs
-                    uri_decoded[5] = {}
-                    uri_find_decoded[5] = {}
-                elif ud.localpath and ud.method.supports_checksum(ud):
-                    basename = os.path.basename(ud.localpath)
-                if basename:
-                    uri_basename = os.path.basename(uri_decoded[loc])
-                    # Prefix with a slash as a sentinel in case
-                    # result_decoded[loc] does not contain one.
-                    path = "/" + result_decoded[loc]
-                    if uri_basename and basename != uri_basename and path.endswith("/" + uri_basename):
-                        result_decoded[loc] = path[1:-len(uri_basename)] + basename
-                    elif not path.endswith("/" + basename):
-                        result_decoded[loc] = os.path.join(path[1:], basename)
         else:
             return None
     result = encodeurl(result_decoded)
@@ -1000,6 +998,7 @@  def build_mirroruris(origud, mirrors, ld):
                 continue
 
             for tarball in tarballs:
+                replacements["DOWNLOADFILENAME"] = tarball or origud.localfile
                 newuri = uri_replace(ud, find, replace, replacements, ld, tarball)
                 if not newuri or newuri in uris or newuri == origud.url:
                     continue