new file mode 100644
@@ -0,0 +1,96 @@
+# Copyright (C) 2024-2025 Weidmueller Interface GmbH & Co. KG
+# Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
+#
+# SPDX-License-Identifier: MIT
+#
+import base64
+import os
+import re
+import urllib.parse
+import bb
+import oe.vendor
+from bb.fetch2 import URI
+from . import ResolveError
+
+VENDOR_TYPE = "go"
+
+def escape(path):
+ return re.sub(r'([A-Z])', lambda m: '!' + m.group(1).lower(), path)
+
+def determine_subdir(module_path):
+ module_path = escape(module_path)
+ return os.path.join(module_path, "@v")
+
+def determine_uri_path(path, module_path, version, extension):
+ subdir = determine_subdir(module_path)
+ version = escape(version)
+ path = path.rstrip("/")
+ return f"{path}/{subdir}/{version}{extension}"
+
+def determine_downloadfilename(module_path, version, extension):
+ subdir = determine_subdir(module_path)
+ filename = f"{subdir}/{version}{extension}"
+ return oe.vendor.determine_downloadfilename(VENDOR_TYPE, filename)
+
+def extend_uri(uri, module_path, version, subdir, extension, checksum_name=None,
+ checksum_value=None):
+ downloadfilename = determine_downloadfilename(module_path, version,
+ extension)
+ uri.path = determine_uri_path(uri.path, module_path, version, extension)
+ params = uri.params
+ params["subdir"] = subdir
+ params["downloadfilename"] = downloadfilename
+ params['unpack'] = "0"
+ if checksum_name and checksum_value:
+ params[checksum_name] = checksum_value
+
+def determine_src_uri(proxy, module_path, version, subdir):
+ uri = URI(proxy)
+ extend_uri(uri, name, version, subdir, ".zip")
+ return str(uri)
+
+def parse_lock_file(lock_file, function):
+ try:
+ with open(lock_file, "r") as f:
+ for line in f:
+ data = line.strip().split()
+ if len(data) != 3:
+ raise ResolveError(f"Invalid line: {line}", lock_file)
+ function(data)
+ except Exception as e:
+ raise ResolveError(f"Invalid file: {str(e)}", lock_file)
+
+def resolve_src_uris(lock_file, proxy, base_subdir):
+ src_uris = []
+
+ def resolve_src_uri(data):
+ module_path, version, hash = data
+ if version.endswith("/go.mod"):
+ version = version[:-7]
+ extension = ".mod"
+ else:
+ extension = ".zip"
+ if hash.startswith("h1:"):
+ checksum_name = "goh1sum"
+ checksum_value = base64.b64decode(hash[3:]).hex()
+ else:
+ raise ResolveError(f"Invalid hash: {hash}", lock_file)
+
+ uri = URI(proxy)
+ params = uri.params
+ params["name"] = module_path
+ params["version"] = version
+ if extension == ".zip":
+ params["vendor"] = VENDOR_TYPE
+ subdir = os.path.join(base_subdir, "cache/download",
+ determine_subdir(module_path))
+ extend_uri(uri, module_path, version, subdir, extension, checksum_name,
+ checksum_value)
+
+ src_uri = str(uri)
+ src_uri = urllib.parse.unquote(src_uri)
+ src_uris.append(src_uri)
+
+ parse_lock_file(lock_file, resolve_src_uri)
+
+ return src_uris