Skip to content
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
2 changes: 1 addition & 1 deletion easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -2367,7 +2367,7 @@ def fix_shebang(self):
if isinstance(fix_shebang_for, string_type):
fix_shebang_for = [fix_shebang_for]

shebang = '#!/usr/bin/env %s' % lang
shebang = '#!%s %s' % (build_option('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
4 changes: 4 additions & 0 deletions easybuild/tools/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
DEFAULT_CONT_TYPE = CONT_TYPE_SINGULARITY

DEFAULT_BRANCH = 'develop'
DEFAULT_ENV_FOR_SHEBANG = '/usr/bin/env'
DEFAULT_ENVVAR_USERS_MODULES = 'HOME'
DEFAULT_INDEX_MAX_AGE = 7 * 24 * 60 * 60 # 1 week (in seconds)
DEFAULT_JOB_BACKEND = 'GC3Pie'
Expand Down Expand Up @@ -295,6 +296,9 @@ def mk_full_default_path(name, prefix=DEFAULT_PREFIX):
DEFAULT_BRANCH: [
'pr_target_branch',
],
DEFAULT_ENV_FOR_SHEBANG: [
'env_for_shebang',
],
DEFAULT_INDEX_MAX_AGE: [
'index_max_age',
],
Expand Down
6 changes: 4 additions & 2 deletions easybuild/tools/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
from easybuild.tools.build_log import DEVEL_LOG_LEVEL, EasyBuildError
from easybuild.tools.build_log import init_logging, log_start, print_msg, print_warning, raise_easybuilderror
from easybuild.tools.config import CONT_IMAGE_FORMATS, CONT_TYPES, DEFAULT_CONT_TYPE, DEFAULT_ALLOW_LOADED_MODULES
from easybuild.tools.config import DEFAULT_BRANCH, DEFAULT_ENVVAR_USERS_MODULES, DEFAULT_FORCE_DOWNLOAD
from easybuild.tools.config import DEFAULT_INDEX_MAX_AGE
from easybuild.tools.config import DEFAULT_BRANCH, DEFAULT_ENV_FOR_SHEBANG, DEFAULT_ENVVAR_USERS_MODULES
from easybuild.tools.config import DEFAULT_FORCE_DOWNLOAD, DEFAULT_INDEX_MAX_AGE
from easybuild.tools.config import DEFAULT_JOB_BACKEND, DEFAULT_LOGFILE_FORMAT, DEFAULT_MAX_FAIL_RATIO_PERMS
from easybuild.tools.config import DEFAULT_MINIMAL_BUILD_ENV, DEFAULT_MNS, DEFAULT_MODULE_SYNTAX, DEFAULT_MODULES_TOOL
from easybuild.tools.config import DEFAULT_MODULECLASSES, DEFAULT_PATH_SUBDIRS, DEFAULT_PKG_RELEASE, DEFAULT_PKG_TOOL
Expand Down Expand Up @@ -375,6 +375,8 @@ def override_options(self):
None, 'store', None, 'e', {'metavar': 'CLASS'}),
'enforce-checksums': ("Enforce availability of checksums for all sources/patches, so they can be verified",
None, 'store_true', False),
'env-for-shebang': ("Define the env command to use when fixing shebangs", None, 'store',
DEFAULT_ENV_FOR_SHEBANG),
'experimental': ("Allow experimental code (with behaviour that can be changed/removed at any given time).",
None, 'store_true', False),
'extra-modules': ("List of extra modules to load after setting up the build environment",
Expand Down
39 changes: 39 additions & 0 deletions test/framework/toy_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -2854,6 +2854,45 @@ def test_fix_shebang(self):
self.assertTrue(bash_shebang_regex.match(bashbin_txt),
"Pattern '%s' found in %s: %s" % (bash_shebang_regex.pattern, bashbin_path, bashbin_txt))

# now test with a custom env command
extra_args = ['--env-for-shebang=/usr/bin/env -S']
self.test_toy_build(ec_file=test_ec, extra_args=extra_args, raise_error=True)

toy_bindir = os.path.join(self.test_installpath, 'software', 'toy', '0.0', 'bin')

# bin/toy and bin/toy2 should *not* be patched, since they're binary files
toy_txt = read_file(os.path.join(toy_bindir, 'toy'), mode='rb')
for fn in ['toy.perl', 'toy.python']:
fn_txt = read_file(os.path.join(toy_bindir, fn), mode='rb')
# no shebang added
self.assertFalse(fn_txt.startswith(b"#!/"))
# exact same file as original binary (untouched)
self.assertEqual(toy_txt, fn_txt)

# no re.M, this should match at start of file!
py_shebang_regex = re.compile(r'^#!/usr/bin/env -S python\n# test$')
for pybin in ['t1.py', 't2.py', 't3.py', 't4.py', 't5.py', 't6.py', 't7.py']:
pybin_path = os.path.join(toy_bindir, pybin)
pybin_txt = read_file(pybin_path)
self.assertTrue(py_shebang_regex.match(pybin_txt),
"Pattern '%s' found in %s: %s" % (py_shebang_regex.pattern, pybin_path, pybin_txt))

# no re.M, this should match at start of file!
perl_shebang_regex = re.compile(r'^#!/usr/bin/env -S perl\n# test$')
for perlbin in ['t1.pl', 't2.pl', 't3.pl', 't4.pl', 't5.pl', 't6.pl', 't7.pl']:
perlbin_path = os.path.join(toy_bindir, perlbin)
perlbin_txt = read_file(perlbin_path)
self.assertTrue(perl_shebang_regex.match(perlbin_txt),
"Pattern '%s' found in %s: %s" % (perl_shebang_regex.pattern, perlbin_path, perlbin_txt))

# There are 2 bash files which shouldn't be influenced by fix_shebang
bash_shebang_regex = re.compile(r'^#!/usr/bin/env bash\n# test$')
for bashbin in ['b1.sh', 'b2.sh']:
bashbin_path = os.path.join(toy_bindir, bashbin)
bashbin_txt = read_file(bashbin_path)
self.assertTrue(bash_shebang_regex.match(bashbin_txt),
"Pattern '%s' found in %s: %s" % (bash_shebang_regex.pattern, bashbin_path, bashbin_txt))

def test_toy_system_toolchain_alias(self):
"""Test use of 'system' toolchain alias."""
toy_ec = os.path.join(os.path.dirname(__file__), 'easyconfigs', 'test_ecs', 't', 'toy', 'toy-0.0.eb')
Expand Down