Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

automatically prepend value for env-for-shebang configuration setting with sysroot #3919

Merged
merged 1 commit into from
Dec 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -2758,14 +2758,24 @@ def package_step(self):

def fix_shebang(self):
"""Fix shebang lines for specified files."""

env_for_shebang = build_option('env_for_shebang')
sysroot = build_option('sysroot')
if sysroot and not env_for_shebang.startswith(sysroot):
env_for_shebang = os.path.join(sysroot, env_for_shebang.lstrip('/'))
if os.path.exists(env_for_shebang.split(' ')[0]):
self.log.info("Path to 'env' command to use in patched shebang lines: %s", env_for_shebang)
else:
raise EasyBuildError("Path to 'env' command to use in shebang lines does not exist: %s", env_for_shebang)

for lang in ['bash', 'perl', 'python']:
shebang_regex = re.compile(r'^#![ ]*.*[/ ]%s.*' % lang)
fix_shebang_for = self.cfg['fix_%s_shebang_for' % lang]
if fix_shebang_for:
if isinstance(fix_shebang_for, string_type):
fix_shebang_for = [fix_shebang_for]

shebang = '#!%s %s' % (build_option('env_for_shebang'), lang)
shebang = '#!%s %s' % (env_for_shebang, lang)
for glob_pattern in fix_shebang_for:
paths = glob.glob(os.path.join(self.installdir, glob_pattern))
self.log.info("Fixing '%s' shebang to '%s' for files that match '%s': %s",
Expand Down
61 changes: 46 additions & 15 deletions test/framework/toy_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -3209,23 +3209,54 @@ def test_fix_shebang(self):
# exact same file as original binary (untouched)
self.assertEqual(toy_txt, fn_txt)

regexes_S = {}
regexes_shebang = {}

def check_shebangs():
for ext in ['sh', 'pl', 'py']:
for script in scripts[ext]:
bin_path = os.path.join(toy_bindir, script)
bin_txt = read_file(bin_path)
# the scripts b1.py, b1.pl, b1.sh, b2.sh should keep their original shebang
if script.startswith('b'):
self.assertTrue(regexes[ext].match(bin_txt),
"Pattern '%s' found in %s: %s" % (regexes[ext].pattern, bin_path, bin_txt))
else:
regex_shebang = regexes_shebang[ext]
self.assertTrue(regex_shebang.match(bin_txt),
"Pattern '%s' found in %s: %s" % (regex_shebang.pattern, bin_path, bin_txt))

# no re.M, this should match at start of file!
regexes_S['py'] = re.compile(r'^#!/usr/bin/env -S python\n# test$')
regexes_S['pl'] = re.compile(r'^#!/usr/bin/env -S perl\n# test$')
regexes_S['sh'] = re.compile(r'^#!/usr/bin/env -S bash\n# test$')
regexes_shebang['py'] = re.compile(r'^#!/usr/bin/env -S python\n# test$')
regexes_shebang['pl'] = re.compile(r'^#!/usr/bin/env -S perl\n# test$')
regexes_shebang['sh'] = re.compile(r'^#!/usr/bin/env -S bash\n# test$')

for ext in ['sh', 'pl', 'py']:
for script in scripts[ext]:
bin_path = os.path.join(toy_bindir, script)
bin_txt = read_file(bin_path)
# the scripts b1.py, b1.pl, b1.sh, b2.sh should keep their original shebang
if script.startswith('b'):
self.assertTrue(regexes[ext].match(bin_txt),
"Pattern '%s' found in %s: %s" % (regexes[ext].pattern, bin_path, bin_txt))
else:
self.assertTrue(regexes_S[ext].match(bin_txt),
"Pattern '%s' found in %s: %s" % (regexes_S[ext].pattern, bin_path, bin_txt))
check_shebangs()

# test again with EasyBuild configured with sysroot, which should be prepended
# automatically to env-for-shebang value (unless it's prefixed with sysroot already)
extra_args = [
'--env-for-shebang=/usr/bin/env -S',
'--sysroot=/usr/../', # sysroot must exist, and so must /usr/bin/env when appended to it
]
self.test_toy_build(ec_file=test_ec, extra_args=extra_args, raise_error=True)

regexes_shebang['py'] = re.compile(r'^#!/usr/../usr/bin/env -S python\n# test$')
regexes_shebang['pl'] = re.compile(r'^#!/usr/../usr/bin/env -S perl\n# test$')
regexes_shebang['sh'] = re.compile(r'^#!/usr/../usr/bin/env -S bash\n# test$')

check_shebangs()

extra_args = [
'--env-for-shebang=/usr/../usr/../usr/bin/env -S',
'--sysroot=/usr/../', # sysroot must exist, and so must /usr/bin/env when appended to it
]
self.test_toy_build(ec_file=test_ec, extra_args=extra_args, raise_error=True)

regexes_shebang['py'] = re.compile(r'^#!/usr/../usr/../usr/bin/env -S python\n# test$')
regexes_shebang['pl'] = re.compile(r'^#!/usr/../usr/../usr/bin/env -S perl\n# test$')
regexes_shebang['sh'] = re.compile(r'^#!/usr/../usr/../usr/bin/env -S bash\n# test$')

check_shebangs()

def test_toy_system_toolchain_alias(self):
"""Test use of 'system' toolchain alias."""
Expand Down