From 4604431c85d5b99778a42070c71d21729431176d Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Tue, 6 Aug 2024 16:04:52 +0200 Subject: [PATCH 1/2] fix crash in Cargo easyblock when no crates are specified The extract step accesses `self.crates` but that is not set when the 'crates' key in the EasyConfig is not set yielding > AttributeError: 'CargoPythonPackage' object has no attribute 'crates' While this usecase is rare and might not make much sense we shouldn't crash so initialize this property to an empty list. --- easybuild/easyblocks/generic/cargo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 0642529cb4..370720ebe0 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -123,6 +123,7 @@ def __init__(self, *args, **kwargs): super(Cargo, self).__init__(*args, **kwargs) self.cargo_home = os.path.join(self.builddir, '.cargo') self.vendor_dir = os.path.join(self.builddir, 'easybuild_vendor') + self.crates = [] # Define property in case EasyConfig has no 'crates' key env.setvar('CARGO_HOME', self.cargo_home) env.setvar('RUSTC', 'rustc') env.setvar('RUSTDOC', 'rustdoc') From a9cadc471982a60ea905cab903509dd7fec8a8e3 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 15 Aug 2024 14:16:44 +0200 Subject: [PATCH 2/2] Use property for crates The double-init issue is fixed --- easybuild/easyblocks/generic/cargo.py | 55 +++++++++++++-------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 370720ebe0..c49e950969 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -123,7 +123,6 @@ def __init__(self, *args, **kwargs): super(Cargo, self).__init__(*args, **kwargs) self.cargo_home = os.path.join(self.builddir, '.cargo') self.vendor_dir = os.path.join(self.builddir, 'easybuild_vendor') - self.crates = [] # Define property in case EasyConfig has no 'crates' key env.setvar('CARGO_HOME', self.cargo_home) env.setvar('RUSTC', 'rustc') env.setvar('RUSTDOC', 'rustdoc') @@ -132,34 +131,32 @@ def __init__(self, *args, **kwargs): env.setvar('RUST_LOG', 'DEBUG') env.setvar('RUST_BACKTRACE', '1') - # Populate sources from "crates" list of tuples (only once) - if self.cfg['crates']: - # Move 'crates' list from easyconfig parameter to property, - # to avoid that creates are processed into 'sources' easyconfig parameter again - # when easyblock is initialized again using the same parsed easyconfig - # (for example when check_sha256_checksums function is called, like in easyconfigs test suite) - self.crates = self.cfg['crates'] - self.cfg['crates'] = [] - sources = [] - for crate_info in self.crates: - if len(crate_info) == 2: - sources.append({ - 'download_filename': self.crate_download_filename(*crate_info), - 'filename': self.crate_src_filename(*crate_info), - 'source_urls': [CRATESIO_SOURCE], - 'alt_location': 'crates.io', - }) - else: - crate, version, repo, rev = crate_info - url, repo_name = repo.rsplit('/', maxsplit=1) - if repo_name.endswith('.git'): - repo_name = repo_name[:-4] - sources.append({ - 'git_config': {'url': url, 'repo_name': repo_name, 'commit': rev}, - 'filename': self.crate_src_filename(crate, version), - }) - - self.cfg.update('sources', sources) + # Populate sources from "crates" list of tuples + sources = [] + for crate_info in self.crates: + if len(crate_info) == 2: + sources.append({ + 'download_filename': self.crate_download_filename(*crate_info), + 'filename': self.crate_src_filename(*crate_info), + 'source_urls': [CRATESIO_SOURCE], + 'alt_location': 'crates.io', + }) + else: + crate, version, repo, rev = crate_info + url, repo_name = repo.rsplit('/', maxsplit=1) + if repo_name.endswith('.git'): + repo_name = repo_name[:-4] + sources.append({ + 'git_config': {'url': url, 'repo_name': repo_name, 'commit': rev}, + 'filename': self.crate_src_filename(crate, version), + }) + + self.cfg.update('sources', sources) + + @property + def crates(self): + """Return the crates as defined in the EasyConfig""" + return self.cfg['crates'] def extract_step(self): """