diff options
-rw-r--r-- | lib/spack/spack/hooks/sbang.py | 4 | ||||
-rw-r--r-- | lib/spack/spack/test/sbang.py | 11 |
2 files changed, 15 insertions, 0 deletions
diff --git a/lib/spack/spack/hooks/sbang.py b/lib/spack/spack/hooks/sbang.py index 1c18c46dc6..ce2cf3435d 100644 --- a/lib/spack/spack/hooks/sbang.py +++ b/lib/spack/spack/hooks/sbang.py @@ -110,6 +110,10 @@ def filter_shebang(path): # Store the file permissions, the patched version needs the same. saved_mode = os.stat(path).st_mode + # Change non-writable files to be writable if needed. + if not os.access(path, os.W_OK): + os.chmod(path, saved_mode | stat.S_IWUSR) + # No need to delete since we'll move it and overwrite the original. patched = tempfile.NamedTemporaryFile('wb', delete=False) patched.write(new_sbang_line) diff --git a/lib/spack/spack/test/sbang.py b/lib/spack/spack/test/sbang.py index e9beebc43d..6d26bd1ba8 100644 --- a/lib/spack/spack/test/sbang.py +++ b/lib/spack/spack/test/sbang.py @@ -374,3 +374,14 @@ def test_shebang_exceeds_spack_shebang_limit(shebang_limits_system_8_spack_16, t with open(file, 'rb') as f: assert b'sbang' not in f.read() + + +def test_sbang_hook_handles_non_writable_files_preserving_permissions(tmpdir): + path = str(tmpdir.join('file.sh')) + with open(path, 'w') as f: + f.write(long_line) + os.chmod(path, 0o555) + sbang.filter_shebang(path) + with open(path, 'r') as f: + assert 'sbang' in f.readline() + assert os.stat(path).st_mode & 0o777 == 0o555 |