Skip to content

Commit 7e899c3

Browse files
committed
Merge branch 'develop' into 5.0.x
2 parents 7d2b853 + 0546463 commit 7e899c3

File tree

6 files changed

+92
-16
lines changed

6 files changed

+92
-16
lines changed

RELEASE_NOTES

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,34 @@ For more detailed information, please see the git log.
44
These release notes can also be consulted at https://easybuild.readthedocs.io/en/latest/Release_notes.html.
55

66

7+
v4.8.1 (11 September 2023)
8+
--------------------------
9+
10+
update/bugfix release
11+
12+
- various enhancements, including:
13+
- add end-to-end test for running EasyBuild in different Linux distros using containers (#3968)
14+
- suggest default title in `--review-pr` (#4287)
15+
- add `build_and_install_loop` hooks to run before and after the install loop for individual easyconfigs (#4304)
16+
- implement support for `cancel_hook` and `fail_hook` (#4315, #4325)
17+
- add postiter hook to the list of steps so the corresponding hook can be used (#4316)
18+
- add `run_shell_cmd` hook (#4323)
19+
- add `build_info_msg` easyconfig parameter to print message during installation of an easyconfig (#4324)
20+
- add `--silence-hook-trigger` configuration option to supress printing of debug message every time a hook is triggered (#4329)
21+
- add support for using fine grained Github tokens (#4332)
22+
- add definitions for ifbf and iofbf toolchain (#4337)
23+
- add support for submodule filtering and specifying extra Git configuration in `git_config` (#4338, #4339)
24+
- various bug fixes, including:
25+
- improve error when checksum dict has no entry for a file (#4150)
26+
- avoid error being logged when `checksums.json` is not found (#4261)
27+
- don't fail in `mkdir` if path gets created while processing it (#4300, #4328)
28+
- ignore request for external module (meta)data when no modules tool is active (#4308)
29+
- use sys.executable to obtain path to `python` command in tests, rather than assuming that `python` command is available in `$PATH` (#4309)
30+
- fix `test_add_and_remove_module_path` by replacing string comparison of paths by checking whether they point to the same path (since symlinks may cause trouble) (#4312)
31+
- enhance `Toolchain.get_flag` to handle lists (#4319)
32+
- only add extensions in module file if there are extensions (#4331)
33+
34+
735
v4.8.0 (7 July 2023)
836
--------------------
937

easybuild/framework/easyblock.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -394,13 +394,13 @@ def get_checksums_from_json(self, always_read=False):
394394
:param always_read: always read the checksums.json file, even if it has been read before
395395
"""
396396
if always_read or self.json_checksums is None:
397-
try:
398-
path = self.obtain_file("checksums.json", no_download=True)
397+
path = self.obtain_file("checksums.json", no_download=True, warning_only=True)
398+
if path is not None:
399399
self.log.info("Loading checksums from file %s", path)
400400
json_txt = read_file(path)
401401
self.json_checksums = json.loads(json_txt)
402-
# if the file can't be found, return an empty dict
403-
except EasyBuildError:
402+
else:
403+
# if the file can't be found, return an empty dict
404404
self.json_checksums = {}
405405

406406
return self.json_checksums
@@ -727,7 +727,8 @@ def collect_exts_file_info(self, fetch_files=True, verify_checksums=True):
727727
return exts_sources
728728

729729
def obtain_file(self, filename, extension=False, urls=None, download_filename=None, force_download=False,
730-
git_config=None, no_download=False, download_instructions=None, alt_location=None):
730+
git_config=None, no_download=False, download_instructions=None, alt_location=None,
731+
warning_only=False):
731732
"""
732733
Locate the file with the given name
733734
- searches in different subdirectories of source path
@@ -780,7 +781,13 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
780781
return fullpath
781782

782783
except IOError as err:
783-
raise EasyBuildError("Downloading file %s from url %s to %s failed: %s", filename, url, fullpath, err)
784+
if not warning_only:
785+
raise EasyBuildError("Downloading file %s "
786+
"from url %s to %s failed: %s", filename, url, fullpath, err)
787+
else:
788+
self.log.warning("Downloading file %s "
789+
"from url %s to %s failed: %s", filename, url, fullpath, err)
790+
return None
784791

785792
else:
786793
# try and find file in various locations
@@ -857,8 +864,13 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
857864
self.dry_run_msg(" * %s (MISSING)", filename)
858865
return filename
859866
else:
860-
raise EasyBuildError("Couldn't find file %s anywhere, and downloading it is disabled... "
867+
if not warning_only:
868+
raise EasyBuildError("Couldn't find file %s anywhere, and downloading it is disabled... "
869+
"Paths attempted (in order): %s ", filename, ', '.join(failedpaths))
870+
else:
871+
self.log.warning("Couldn't find file %s anywhere, and downloading it is disabled... "
861872
"Paths attempted (in order): %s ", filename, ', '.join(failedpaths))
873+
return None
862874
elif git_config:
863875
return get_source_tarball_from_git(filename, targetdir, git_config)
864876
else:
@@ -950,7 +962,11 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
950962
error_msg += "and downloading it didn't work either... "
951963
error_msg += "Paths attempted (in order): %s " % failedpaths_msg
952964

953-
raise EasyBuildError(error_msg, filename)
965+
if not warning_only:
966+
raise EasyBuildError(error_msg, filename)
967+
else:
968+
self.log.warning(error_msg, filename)
969+
return None
954970

955971
#
956972
# GETTER/SETTER UTILITY FUNCTIONS

easybuild/tools/filetools.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,14 +1252,11 @@ def verify_checksum(path, checksums):
12521252

12531253
for checksum in checksums:
12541254
if isinstance(checksum, dict):
1255-
if filename in checksum:
1255+
try:
12561256
# Set this to a string-type checksum
12571257
checksum = checksum[filename]
1258-
elif build_option('enforce_checksums'):
1259-
raise EasyBuildError("Missing checksum for %s", filename)
1260-
else:
1261-
# Set to None and allow to fail elsewhere
1262-
checksum = None
1258+
except KeyError:
1259+
raise EasyBuildError("Missing checksum for %s in %s", filename, checksum)
12631260

12641261
if isinstance(checksum, str):
12651262
# if no checksum type is specified, it is assumed to be MD5 (32 characters) or SHA256 (64 characters)
@@ -1289,7 +1286,8 @@ def verify_checksum(path, checksums):
12891286
# no matching checksums
12901287
return False
12911288
else:
1292-
raise EasyBuildError("Invalid checksum spec '%s', should be a string (MD5) or 2-tuple (type, value).",
1289+
raise EasyBuildError("Invalid checksum spec '%s': should be a string (MD5 or SHA256), "
1290+
"2-tuple (type, value), or tuple of alternative checksum specs.",
12931291
checksum)
12941292

12951293
actual_checksum = compute_checksum(path, typ)

easybuild/tools/options.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ def override_options(self):
495495
'silence-deprecation-warnings': (
496496
"Silence specified deprecation warnings out of (%s)" % ', '.join(all_deprecations),
497497
'strlist', 'extend', []),
498-
'silence-hook-trigger': ("Supress printing of debug message every time a hook is triggered",
498+
'silence-hook-trigger': ("Suppress printing of debug message every time a hook is triggered",
499499
None, 'store_true', False),
500500
'skip-extensions': ("Skip installation of extensions", None, 'store_true', False),
501501
'skip-test-cases': ("Skip running test cases", None, 'store_true', False, 't'),

test/framework/easyblock.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from unittest import TextTestRunner
4040

4141
import easybuild.tools.systemtools as st
42+
from easybuild.base import fancylogger
4243
from easybuild.framework.easyblock import EasyBlock, get_easyblock_instance
4344
from easybuild.framework.easyconfig import CUSTOM
4445
from easybuild.framework.easyconfig.easyconfig import EasyConfig
@@ -2456,6 +2457,29 @@ def test_checksum_step(self):
24562457
eb.fetch_sources()
24572458
eb.checksum_step()
24582459

2460+
with self.mocked_stdout_stderr() as (stdout, stderr):
2461+
2462+
# using checksum-less test easyconfig in location that does not provide checksums.json
2463+
test_ec = os.path.join(self.test_prefix, 'test-no-checksums.eb')
2464+
copy_file(toy_ec, test_ec)
2465+
write_file(test_ec, 'checksums = []', append=True)
2466+
ec = process_easyconfig(test_ec)[0]
2467+
2468+
# enable logging to screen, so we can check whether error is logged when checksums.json is not found
2469+
fancylogger.logToScreen(enable=True, stdout=True)
2470+
2471+
eb = get_easyblock_instance(ec)
2472+
eb.fetch_sources()
2473+
eb.checksum_step()
2474+
2475+
fancylogger.logToScreen(enable=False, stdout=True)
2476+
stdout = self.get_stdout()
2477+
2478+
# make sure there's no error logged for not finding checksums.json,
2479+
# see also https://github.com/easybuilders/easybuild-framework/issues/4301
2480+
regex = re.compile("ERROR .*Couldn't find file checksums.json anywhere", re.M)
2481+
self.assertFalse(regex.search(stdout), "Pattern '%s' should not be found in log" % regex.pattern)
2482+
24592483
# fiddle with checksum to check whether faulty checksum is catched
24602484
copy_file(toy_ec, self.test_prefix)
24612485
toy_ec = os.path.join(self.test_prefix, os.path.basename(toy_ec))

test/framework/filetools.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,14 @@ def test_checksums(self):
351351
alt_checksums = ('7167b64b1ca062b9674ffef46f9325db7167b64b1ca062b9674ffef46f9325db', broken_checksums['sha256'])
352352
self.assertFalse(ft.verify_checksum(fp, alt_checksums))
353353

354+
# Check dictionary
355+
alt_checksums = (known_checksums['sha256'],)
356+
self.assertTrue(ft.verify_checksum(fp, {os.path.basename(fp): known_checksums['sha256']}))
357+
faulty_dict = {'wrong-name': known_checksums['sha256']}
358+
self.assertErrorRegex(EasyBuildError,
359+
"Missing checksum for " + os.path.basename(fp) + " in .*wrong-name.*",
360+
ft.verify_checksum, fp, faulty_dict)
361+
354362
# check whether missing checksums are enforced
355363
build_options = {
356364
'enforce_checksums': True,
@@ -365,6 +373,8 @@ def test_checksums(self):
365373
for checksum in [known_checksums[x] for x in ('md5', 'sha256')]:
366374
dict_checksum = {os.path.basename(fp): checksum, 'foo': 'baa'}
367375
self.assertTrue(ft.verify_checksum(fp, dict_checksum))
376+
del dict_checksum[os.path.basename(fp)]
377+
self.assertErrorRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, fp, dict_checksum)
368378

369379
def test_common_path_prefix(self):
370380
"""Test get common path prefix for a list of paths."""

0 commit comments

Comments
 (0)