From 9b547730d2972cf82ca2ad5c10f85dc3f6237291 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Wed, 5 Feb 2025 10:51:09 +0100 Subject: [PATCH 1/2] Support checksum dicts for cargo crates We usually use `{'source': checksum}` for checksums so `src['checksum']` might return such a dict instead of a checksum. This can be observed in `uv-0.2.30-GCCcore-13.3.0.eb`: ``` {'reqwest-middleware-0.3.2-21ceec9a5fd2e8d6f71c3ea2999078fecbd13cbe.tar.gz': None} {'reqwest-retry-0.7.0-21ceec9a5fd2e8d6f71c3ea2999078fecbd13cbe.tar.gz': None} ``` Unpack such dicts via a helper method. --- easybuild/easyblocks/generic/cargo.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index ddcee2565f0..770d5c23553 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -125,6 +125,18 @@ def get_workspace_members(crate_dir): return [os.path.join(crate_dir, m) for m in members] +def get_checksum(src, log): + """Get the checksum from an extracted source""" + checksum = src['checksum'] + if isinstance(checksum, dict): + try: + checksum = checksum[src['name']] + except KeyError: + log.warning('No checksum for %s in %s', checksum, src['name']) + checksum = None + return checksum + + class Cargo(ExtensionEasyBlock): """Support for installing Cargo packages (Rust)""" @@ -257,12 +269,13 @@ def extract_step(self): except KeyError: git_sources[git_key] = src else: - previous_checksum = previous_source['checksum'] - current_checksum = src['checksum'] + previous_checksum = get_checksum(previous_source, self.log) + current_checksum = get_checksum(src, self.log) if previous_checksum and current_checksum and previous_checksum != current_checksum: - raise EasyBuildError("Sources for the same git repository need to be identical." - "Mismatch found for %s rev %s in %s vs %s", - git_repo, rev, previous_source['name'], src['name']) + raise EasyBuildError("Sources for the same git repository need to be identical. " + "Mismatch found for %s rev %s in %s (checksum: %s) vs %s (checksum: %s)", + git_repo, rev, previous_source['name'], previous_checksum, + src['name'], current_checksum) self.log.info("Source %s already extracted to %s by %s. Skipping extraction.", src['name'], previous_source['finalpath'], previous_source['name']) src['finalpath'] = previous_source['finalpath'] From a29e4476159ea9037149db8ed37f7936d72b864f Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Wed, 5 Feb 2025 10:57:45 +0100 Subject: [PATCH 2/2] Set Cargo variables also for extensions --- easybuild/easyblocks/generic/cargo.py | 28 ++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 770d5c23553..313f9bd344c 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -198,13 +198,7 @@ def __init__(self, *args, **kwargs): """Constructor for Cargo easyblock.""" super(Cargo, self).__init__(*args, **kwargs) self.cargo_home = os.path.join(self.builddir, '.cargo') - env.setvar('CARGO_HOME', self.cargo_home) - env.setvar('RUSTC', 'rustc') - env.setvar('RUSTDOC', 'rustdoc') - env.setvar('RUSTFMT', 'rustfmt') - env.setvar('RUSTFLAGS', self.rustc_optarch()) - env.setvar('RUST_LOG', 'DEBUG') - env.setvar('RUST_BACKTRACE', '1') + self.set_cargo_vars() # Populate sources from "crates" list of tuples sources = [] @@ -231,11 +225,31 @@ def __init__(self, *args, **kwargs): self.cfg.update('sources', sources) + def set_cargo_vars(self): + """Set environment variables for Rust compilation and Cargo""" + env.setvar('CARGO_HOME', self.cargo_home) + env.setvar('RUSTC', 'rustc') + env.setvar('RUSTDOC', 'rustdoc') + env.setvar('RUSTFMT', 'rustfmt') + env.setvar('RUSTFLAGS', self.rustc_optarch()) + env.setvar('RUST_LOG', 'DEBUG') + env.setvar('RUST_BACKTRACE', '1') + @property def crates(self): """Return the crates as defined in the EasyConfig""" return self.cfg['crates'] + def load_module(self, *args, **kwargs): + """(Re)set environment variables after loading module file. + + Required here to ensure the variables are defined for stand-alone installations and extensions, + because the environment is reset to the initial environment right before loading the module. + """ + + super(Cargo, self).load_module(*args, **kwargs) + self.set_cargo_vars() + def extract_step(self): """ Unpack the source files and populate them with required .cargo-checksum.json if offline