Skip to content

Commit 4038b80

Browse files
authored
Merge pull request #3613 from ComputeCanada/configurable_env_for_shebang
added configuration option to define the env command to use for shebangs
2 parents 644dcd9 + babe523 commit 4038b80

File tree

4 files changed

+48
-3
lines changed

4 files changed

+48
-3
lines changed

easybuild/framework/easyblock.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2367,7 +2367,7 @@ def fix_shebang(self):
23672367
if isinstance(fix_shebang_for, string_type):
23682368
fix_shebang_for = [fix_shebang_for]
23692369

2370-
shebang = '#!/usr/bin/env %s' % lang
2370+
shebang = '#!%s %s' % (build_option('env_for_shebang'), lang)
23712371
for glob_pattern in fix_shebang_for:
23722372
paths = glob.glob(os.path.join(self.installdir, glob_pattern))
23732373
self.log.info("Fixing '%s' shebang to '%s' for files that match '%s': %s",

easybuild/tools/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
DEFAULT_CONT_TYPE = CONT_TYPE_SINGULARITY
8080

8181
DEFAULT_BRANCH = 'develop'
82+
DEFAULT_ENV_FOR_SHEBANG = '/usr/bin/env'
8283
DEFAULT_ENVVAR_USERS_MODULES = 'HOME'
8384
DEFAULT_INDEX_MAX_AGE = 7 * 24 * 60 * 60 # 1 week (in seconds)
8485
DEFAULT_JOB_BACKEND = 'GC3Pie'
@@ -295,6 +296,9 @@ def mk_full_default_path(name, prefix=DEFAULT_PREFIX):
295296
DEFAULT_BRANCH: [
296297
'pr_target_branch',
297298
],
299+
DEFAULT_ENV_FOR_SHEBANG: [
300+
'env_for_shebang',
301+
],
298302
DEFAULT_INDEX_MAX_AGE: [
299303
'index_max_age',
300304
],

easybuild/tools/options.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@
6060
from easybuild.tools.build_log import DEVEL_LOG_LEVEL, EasyBuildError
6161
from easybuild.tools.build_log import init_logging, log_start, print_msg, print_warning, raise_easybuilderror
6262
from easybuild.tools.config import CONT_IMAGE_FORMATS, CONT_TYPES, DEFAULT_CONT_TYPE, DEFAULT_ALLOW_LOADED_MODULES
63-
from easybuild.tools.config import DEFAULT_BRANCH, DEFAULT_ENVVAR_USERS_MODULES, DEFAULT_FORCE_DOWNLOAD
64-
from easybuild.tools.config import DEFAULT_INDEX_MAX_AGE
63+
from easybuild.tools.config import DEFAULT_BRANCH, DEFAULT_ENV_FOR_SHEBANG, DEFAULT_ENVVAR_USERS_MODULES
64+
from easybuild.tools.config import DEFAULT_FORCE_DOWNLOAD, DEFAULT_INDEX_MAX_AGE
6565
from easybuild.tools.config import DEFAULT_JOB_BACKEND, DEFAULT_LOGFILE_FORMAT, DEFAULT_MAX_FAIL_RATIO_PERMS
6666
from easybuild.tools.config import DEFAULT_MINIMAL_BUILD_ENV, DEFAULT_MNS, DEFAULT_MODULE_SYNTAX, DEFAULT_MODULES_TOOL
6767
from easybuild.tools.config import DEFAULT_MODULECLASSES, DEFAULT_PATH_SUBDIRS, DEFAULT_PKG_RELEASE, DEFAULT_PKG_TOOL
@@ -375,6 +375,8 @@ def override_options(self):
375375
None, 'store', None, 'e', {'metavar': 'CLASS'}),
376376
'enforce-checksums': ("Enforce availability of checksums for all sources/patches, so they can be verified",
377377
None, 'store_true', False),
378+
'env-for-shebang': ("Define the env command to use when fixing shebangs", None, 'store',
379+
DEFAULT_ENV_FOR_SHEBANG),
378380
'experimental': ("Allow experimental code (with behaviour that can be changed/removed at any given time).",
379381
None, 'store_true', False),
380382
'extra-modules': ("List of extra modules to load after setting up the build environment",

test/framework/toy_build.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2860,6 +2860,45 @@ def test_fix_shebang(self):
28602860
self.assertTrue(bash_shebang_regex.match(bashbin_txt),
28612861
"Pattern '%s' found in %s: %s" % (bash_shebang_regex.pattern, bashbin_path, bashbin_txt))
28622862

2863+
# now test with a custom env command
2864+
extra_args = ['--env-for-shebang=/usr/bin/env -S']
2865+
self.test_toy_build(ec_file=test_ec, extra_args=extra_args, raise_error=True)
2866+
2867+
toy_bindir = os.path.join(self.test_installpath, 'software', 'toy', '0.0', 'bin')
2868+
2869+
# bin/toy and bin/toy2 should *not* be patched, since they're binary files
2870+
toy_txt = read_file(os.path.join(toy_bindir, 'toy'), mode='rb')
2871+
for fn in ['toy.perl', 'toy.python']:
2872+
fn_txt = read_file(os.path.join(toy_bindir, fn), mode='rb')
2873+
# no shebang added
2874+
self.assertFalse(fn_txt.startswith(b"#!/"))
2875+
# exact same file as original binary (untouched)
2876+
self.assertEqual(toy_txt, fn_txt)
2877+
2878+
# no re.M, this should match at start of file!
2879+
py_shebang_regex = re.compile(r'^#!/usr/bin/env -S python\n# test$')
2880+
for pybin in ['t1.py', 't2.py', 't3.py', 't4.py', 't5.py', 't6.py', 't7.py']:
2881+
pybin_path = os.path.join(toy_bindir, pybin)
2882+
pybin_txt = read_file(pybin_path)
2883+
self.assertTrue(py_shebang_regex.match(pybin_txt),
2884+
"Pattern '%s' found in %s: %s" % (py_shebang_regex.pattern, pybin_path, pybin_txt))
2885+
2886+
# no re.M, this should match at start of file!
2887+
perl_shebang_regex = re.compile(r'^#!/usr/bin/env -S perl\n# test$')
2888+
for perlbin in ['t1.pl', 't2.pl', 't3.pl', 't4.pl', 't5.pl', 't6.pl', 't7.pl']:
2889+
perlbin_path = os.path.join(toy_bindir, perlbin)
2890+
perlbin_txt = read_file(perlbin_path)
2891+
self.assertTrue(perl_shebang_regex.match(perlbin_txt),
2892+
"Pattern '%s' found in %s: %s" % (perl_shebang_regex.pattern, perlbin_path, perlbin_txt))
2893+
2894+
# There are 2 bash files which shouldn't be influenced by fix_shebang
2895+
bash_shebang_regex = re.compile(r'^#!/usr/bin/env bash\n# test$')
2896+
for bashbin in ['b1.sh', 'b2.sh']:
2897+
bashbin_path = os.path.join(toy_bindir, bashbin)
2898+
bashbin_txt = read_file(bashbin_path)
2899+
self.assertTrue(bash_shebang_regex.match(bashbin_txt),
2900+
"Pattern '%s' found in %s: %s" % (bash_shebang_regex.pattern, bashbin_path, bashbin_txt))
2901+
28632902
def test_toy_system_toolchain_alias(self):
28642903
"""Test use of 'system' toolchain alias."""
28652904
toy_ec = os.path.join(os.path.dirname(__file__), 'easyconfigs', 'test_ecs', 't', 'toy', 'toy-0.0.eb')

0 commit comments

Comments
 (0)