From: Stefan Herbrechtsmeier <stefan.herbrechtsme...@weidmueller.com>
Add a vendor module for cargo to resolve dependencies and populate vendor directories from a Cargo.lock file. Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsme...@weidmueller.com> --- meta/lib/oe/vendor/cargo.py | 121 ++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 meta/lib/oe/vendor/cargo.py diff --git a/meta/lib/oe/vendor/cargo.py b/meta/lib/oe/vendor/cargo.py new file mode 100644 index 0000000000..4d0a0034f3 --- /dev/null +++ b/meta/lib/oe/vendor/cargo.py @@ -0,0 +1,121 @@ +# Copyright (C) 2024-2025 Weidmueller Interface GmbH & Co. KG +# Stefan Herbrechtsmeier <stefan.herbrechtsme...@weidmueller.com> +# +# SPDX-License-Identifier: MIT +# +import json +import os +import tomllib +import bb +import oe.vendor +from bb.fetch2 import URI +from . import ResolveError + +VENDOR_TYPE = "cargo" + +VENDOR_DIR = "vendor/cargo" + +def escape(path): + return re.sub(r'([A-Z])', lambda m: '!' + m.group(1).lower(), path) + +def determine_subdir(name, version): + return f"{name}-{version}" + +def determine_uri_path(path, name, version): + path = path.rstrip("/") + return f"{path}/api/v1/crates/{name}/{version}/download" + +def determine_downloadfilename(name, version): + filename = f"{name}-{version}.crate" + return oe.vendor.determine_downloadfilename(VENDOR_TYPE, filename) + +def extend_uri(uri, name, version, subdir, checksum_name=None, + checksum_value=None): + uri.path = determine_uri_path(uri.path, name, version) + params = uri.params + params["subdir"] = subdir + params["downloadfilename"] = determine_downloadfilename(name, version) + if checksum_name and checksum_value: + params[checksum_name] = checksum_value + +def determine_src_uri(registry, name, version, subdir): + uri = URI(registry) + extend_uri(uri, name, version, subdir) + return str(uri) + +def parse_lock_file(lock_file, function): + try: + with open(lock_file, "rb") as f: + crates = tomllib.load(f) + except Exception as e: + raise ResolveError(f"Invalid file: {str(e)}", lock_file) + + for data in crates.get("package", []): + if "source" not in data: + continue + + function(data) + +def resolve_src_uris(lock_file, registry, base_subdir, vendor_subdir): + src_uris = [] + + def resolve_src_uri(data): + name = data.get('name') + version = data.get('version') + source = data.get("source") + + if source.startswith("registry"): + checksum_name = "sha256sum" + checksum_value = data.get('checksum') + uri = URI(source[9:]) + if (source[9:] == "https://github.com/rust-lang/crates.io-index"): + uri = URI(registry) + params = uri.params + params["name"] = name + params["version"] = version + params["type"] = VENDOR_TYPE + subdir = os.path.join(base_subdir, vendor_subdir) + extend_uri(uri, name, version, subdir, checksum_name, + checksum_value) + else: + raise ResolveError(f"Unsupported cargo registry: {source}", + lock_file) + + elif source.startswith("git"): + repository, _, revision = source.partition("#") + uri = URI(repository) + params = uri.params + scheme, _, protocol = uri.scheme.partition("+") + if protocol: + params["protocol"] = protocol + uri.scheme = scheme + params["nobranch"] = "1" + subdir = determine_subdir(name, version) + params["subdir"] = os.path.join(base_subdir, vendor_subdir, subdir) + params["rev"] = revision + else: + raise ResolveError(f"Unsupported dependency: {name}", lock_file) + + src_uris.append(str(uri)) + + parse_lock_file(lock_file, resolve_src_uri) + + return src_uris + +def populate_vendor(lock_file, rootdir): + def populate_checksum(data): + name = data.get('name') + version = data.get('version') + source = data.get("source") + chechsum = data.get('checksum') + + if source.startswith("registry"): + subdir = determine_subdir(name, version) + filepath = os.path.join(rootdir, subdir, ".cargo-checksum.json") + with open(filepath, "w") as f: + json.dump({ + "files": {}, + "package": chechsum + }, f) + + parse_lock_file(lock_file, populate_checksum) -- 2.39.5
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#211132): https://lists.openembedded.org/g/openembedded-core/message/211132 Mute This Topic: https://lists.openembedded.org/mt/111123523/21656 Group Owner: openembedded-core+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-