@@ -2117,6 +2117,7 @@ from . import crate
from . import gcp
from . import gomod
from . import gosum
+from . import cargolock
methods.append(local.Local())
methods.append(wget.Wget())
@@ -2142,3 +2143,4 @@ methods.append(gomod.GoMod())
methods.append(gomod.GoModGit())
methods.extend(npmsw.methods)
methods.extend(gosum.methods)
+methods.extend(cargolock.methods)
new file mode 100644
@@ -0,0 +1,73 @@
+# Copyright (C) 2024-2025 Weidmueller Interface GmbH & Co. KG
+# Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
+#
+# SPDX-License-Identifier: MIT
+#
+"""
+BitBake 'Fetch' implementation for cargo.lock
+
+The cargolock, cargolock+https and cargolock+git fetchers are used to download
+Cargo dependencies via a cargo.lock file.
+"""
+
+import os
+import tomllib
+import bb
+from bb.fetch2 import ParameterError
+from bb.fetch2 import URI
+from bb.fetch2.dependency import create_methods
+
+class CargoLockMixin:
+ def resolve_dependencies(self, ud, localpath, d):
+ if os.path.isdir(localpath):
+ localpath = os.path.join(localpath, "Cargo.lock")
+ try:
+ with open(localpath, "rb") as f:
+ crates = tomllib.load(f)
+ except Exception as e:
+ raise ParameterError("Invalid Cargo lock file: %s" % str(e), ud.url)
+
+ urls = []
+ for crate in crates.get("package", []):
+ name = crate.get('name')
+ version = crate.get('version')
+ source = crate.get("source")
+
+ if not source:
+ continue
+
+ if source.startswith("registry"):
+ uri = URI(source[9:])
+ if (uri.scheme == "https" and uri.hostname == "github.com"
+ and uri.path == "/rust-lang/crates.io-index"):
+ uri.scheme = "crate"
+ uri.hostname = "crates.io"
+ uri.path = f"/{name}/{version}"
+ uri.params["dn"] = name
+ uri.params["dv"] = version
+ else:
+ bb.warn(f"Please add support for the url to crate fetcher: {source}")
+ uri.params["subdir"] = os.path.join("cargo_home", "bitbake")
+ uri.params["sha256sum"] = crate.get('checksum')
+ url = str(uri)
+
+ elif source.startswith("git"):
+ url, _, rev = source.partition("#")
+ uri = URI(url)
+ scheme, _, protocol = uri.scheme.partition("+")
+ if protocol:
+ uri.params["protocol"] = protocol
+ uri.scheme = scheme
+ uri.params["rev"] = rev
+ uri.params["nobranch"] = "1"
+ uri.params["destsuffix"] = f"{name}-{version}"
+ uri.params["subdir"] = os.path.join("cargo_home", "bitbake")
+ url = str(uri)
+ else:
+ raise ParameterError(f"Unsupported dependency: {name}", ud.url)
+
+ urls.append(url)
+
+ return urls
+
+methods = create_methods("cargolock", CargoLockMixin)