Skip to content

Commit 121b4b0

Browse files
authored
Merge pull request #5016 from Flamefire/20251007085255_new_pr_IpOuRJvyQP
Handle `post_install_patches` in GitHub uploads
2 parents cb8b421 + 2102678 commit 121b4b0

File tree

3 files changed

+40
-29
lines changed

3 files changed

+40
-29
lines changed

easybuild/base/testing.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,15 @@ def get_stderr(self):
201201
"""Return output captured from stderr until now."""
202202
return sys.stderr.getvalue()
203203

204+
@contextmanager
205+
def mocked_stdout(self):
206+
"""Context manager to mock stdout"""
207+
self.mock_stdout(True)
208+
try:
209+
yield sys.stdout
210+
finally:
211+
self.mock_stdout(False)
212+
204213
@contextmanager
205214
def mocked_stdout_stderr(self, mock_stdout=True, mock_stderr=True):
206215
"""Context manager to mock stdout and stderr"""

easybuild/tools/github.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
from easybuild.framework.easyconfig.easyconfig import EASYCONFIGS_ARCHIVE_DIR
5454
from easybuild.framework.easyconfig.easyconfig import copy_easyconfigs, copy_patch_files, det_file_info
5555
from easybuild.framework.easyconfig.easyconfig import process_easyconfig
56-
from easybuild.framework.easyconfig.parser import EasyConfigParser
56+
from easybuild.framework.easyconfig.parser import ALTERNATIVE_EASYCONFIG_PARAMETERS, EasyConfigParser
5757
from easybuild.tools import LooseVersion
5858
from easybuild.tools.build_log import EasyBuildError, EasyBuildExit, print_msg, print_warning
5959
from easybuild.tools.config import build_option
@@ -754,13 +754,6 @@ def commit_request_fn(gh):
754754
# download tarball for specific commit
755755
repo_commit = download_repo(repo=github_repo, commit=commit, account=github_account)
756756

757-
if github_repo == GITHUB_EASYCONFIGS_REPO:
758-
files_subdir = 'easybuild/easyconfigs/'
759-
elif github_repo == GITHUB_EASYBLOCKS_REPO:
760-
files_subdir = 'easybuild/easyblocks/'
761-
else:
762-
raise EasyBuildError("Unknown repo: %s", github_repo, exit_code=EasyBuildExit.OPTION_ERROR)
763-
764757
# symlink subdirectories of 'easybuild/easy{blocks,configs}' into path that gets added to robot search path
765758
mkdir(path, parents=True)
766759
dirpath = os.path.join(repo_commit, easybuild_subdir)
@@ -769,6 +762,7 @@ def commit_request_fn(gh):
769762

770763
# copy specified files to directory where they're expected to be found
771764
file_paths = []
765+
subdir_prefix = easybuild_subdir + os.path.sep
772766
for file in files:
773767

774768
# if only filename is specified, we need to determine the file path
@@ -783,8 +777,8 @@ def commit_request_fn(gh):
783777

784778
# strip of leading subdirectory like easybuild/easyconfigs/ or easybuild/easyblocks/
785779
# because that's what expected by robot_find_easyconfig
786-
if file.startswith(files_subdir):
787-
file = file[len(files_subdir):]
780+
if file.startswith(subdir_prefix):
781+
file = file[len(subdir_prefix):]
788782

789783
# if file is found, copy it to dedicated directory;
790784
# if not, just skip it (may be an easyconfig file in local directory);
@@ -1352,7 +1346,7 @@ def get_name(patch):
13521346
exit_code=EasyBuildExit.VALUE_ERROR)
13531347
return patch
13541348

1355-
patches = [get_name(p) for p in ec['patches']]
1349+
patches = [get_name(p) for p in itertools.chain(ec['patches'], ec['postinstallpatches'])]
13561350

13571351
with ec.disable_templating():
13581352
# take into account both list of extensions (via exts_list) and components (cfr. Bundle easyblock)
@@ -1364,7 +1358,12 @@ def get_name(patch):
13641358
'version': entry[1],
13651359
}
13661360
options = entry[2]
1367-
patches.extend(get_name(p) % templates for p in options.get('patches', []))
1361+
patches.extend(get_name(p) % templates for p in
1362+
itertools.chain(
1363+
options.get('patches', []),
1364+
options.get(ALTERNATIVE_EASYCONFIG_PARAMETERS['post_install_patches'],
1365+
options.get('post_install_patches', []))
1366+
))
13681367

13691368
return patch_name in patches
13701369

test/framework/github.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ def tearDown(self):
130130

131131
def test_det_pr_title(self):
132132
"""Test det_pr_title function"""
133-
# check if patches for extensions are found
134133
rawtxt = textwrap.dedent("""
135134
easyblock = 'ConfigureMake'
136135
name = '%s'
@@ -1007,9 +1006,8 @@ def test_github_det_patch_specs(self):
10071006
file_info['ecs'].append(EasyConfig(None, rawtxt=rawtxt))
10081007

10091008
error_pattern = "Failed to determine software name to which patch file .*/2.patch relates"
1010-
self.mock_stdout(True)
1011-
self.assertErrorRegex(EasyBuildError, error_pattern, gh.det_patch_specs, patch_paths, file_info, [])
1012-
self.mock_stdout(False)
1009+
with self.mocked_stdout():
1010+
self.assertErrorRegex(EasyBuildError, error_pattern, gh.det_patch_specs, patch_paths, file_info, [])
10131011

10141012
rawtxt = textwrap.dedent("""
10151013
easyblock = 'ConfigureMake'
@@ -1019,12 +1017,11 @@ def test_github_det_patch_specs(self):
10191017
description = ''
10201018
toolchain = {"name":"GCC", "version": "4.6.3"}
10211019
1022-
patches = [('3.patch', 'subdir'), '2.patch']
1020+
postinstallpatches = [('3.patch', 'subdir'), '2.patch']
10231021
""")
10241022
file_info['ecs'].append(EasyConfig(None, rawtxt=rawtxt))
1025-
self.mock_stdout(True)
1026-
res = gh.det_patch_specs(patch_paths, file_info, [])
1027-
self.mock_stdout(False)
1023+
with self.mocked_stdout():
1024+
res = gh.det_patch_specs(patch_paths, file_info, [])
10281025

10291026
self.assertEqual([i[0] for i in res], patch_paths)
10301027
self.assertEqual([i[1] for i in res], ['A', 'C', 'C'])
@@ -1043,20 +1040,24 @@ def test_github_det_patch_specs(self):
10431040
('bar', '1.2.3'),
10441041
('patched', '4.5.6', {
10451042
'patches': [('%(name)s-2.patch', 1), '%(name)s-3.patch'],
1043+
'postinstallpatches': ['%(name)s-4.patch'],
10461044
}),
10471045
]
1046+
postinstallpatches = ['%(name)s-5.patch'],
10481047
""")
1049-
patch_paths[1:3] = [os.path.join(self.test_prefix, p) for p in ['patched-2.patch', 'patched-3.patch']]
1048+
patch_paths[1:] = [os.path.join(self.test_prefix, p) for p in
1049+
['patched-2.patch', 'patched-3.patch', 'patched-4.patch', 'patched_ext-5.patch']]
10501050
file_info['ecs'][-1] = EasyConfig(None, rawtxt=rawtxt)
10511051

1052-
self.mock_stdout(True)
1053-
res = gh.det_patch_specs(patch_paths, file_info, [])
1054-
self.mock_stdout(False)
1052+
with self.mocked_stdout():
1053+
res = gh.det_patch_specs(patch_paths, file_info, [])
10551054

10561055
self.assertEqual([i[0] for i in res], patch_paths)
1057-
self.assertEqual([i[1] for i in res], ['A', 'patched_ext', 'patched_ext'])
1056+
self.assertEqual([i[1] for i in res], ['A'] + ['patched_ext'] * 4)
10581057

10591058
# check if patches for components are found
1059+
# NOTE: Using alternative name and tuple format for post_install_patches, different to above test case
1060+
# to verify handling either way works without adding another sub-test
10601061
rawtxt = textwrap.dedent("""
10611062
easyblock = 'PythonBundle'
10621063
name = 'patched_bundle'
@@ -1069,17 +1070,19 @@ def test_github_det_patch_specs(self):
10691070
('bar', '1.2.3'),
10701071
('patched', '4.5.6', {
10711072
'patches': [('%(name)s-2.patch', 1), '%(name)s-3.patch'],
1073+
'post_install_patches': [('%(name)s-4.patch', 1)],
10721074
}),
10731075
]
1076+
post_install_patches = [('%(name)s-5.patch', 2)]
10741077
""")
1078+
patch_paths[-1] = 'patched_bundle-5.patch'
10751079
file_info['ecs'][-1] = EasyConfig(None, rawtxt=rawtxt)
10761080

1077-
self.mock_stdout(True)
1078-
res = gh.det_patch_specs(patch_paths, file_info, [])
1079-
self.mock_stdout(False)
1081+
with self.mocked_stdout():
1082+
res = gh.det_patch_specs(patch_paths, file_info, [])
10801083

10811084
self.assertEqual([i[0] for i in res], patch_paths)
1082-
self.assertEqual([i[1] for i in res], ['A', 'patched_bundle', 'patched_bundle'])
1085+
self.assertEqual([i[1] for i in res], ['A'] + ['patched_bundle'] * 4)
10831086

10841087
def test_github_restclient(self):
10851088
"""Test use of RestClient."""

0 commit comments

Comments
 (0)