summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/hooks/sbang.py12
-rw-r--r--lib/spack/spack/test/sbang.py17
2 files changed, 26 insertions, 3 deletions
diff --git a/lib/spack/spack/hooks/sbang.py b/lib/spack/spack/hooks/sbang.py
index 3a957c6e0e..02c1ce3816 100644
--- a/lib/spack/spack/hooks/sbang.py
+++ b/lib/spack/spack/hooks/sbang.py
@@ -23,6 +23,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import os
+import stat
import re
import llnl.util.tty as tty
@@ -62,10 +63,21 @@ def filter_shebang(path):
if re.search(r'^#!(/[^/]*)*lua\b', original):
original = re.sub(r'^#', '--', original)
+ # Change non-writable files to be writable if needed.
+ saved_mode = None
+ if not os.access(path, os.W_OK):
+ st = os.stat(path)
+ saved_mode = st.st_mode
+ os.chmod(path, saved_mode | stat.S_IWRITE)
+
with open(path, 'w') as new_file:
new_file.write(new_sbang_line)
new_file.write(original)
+ # Restore original permissions.
+ if saved_mode is not None:
+ os.chmod(path, saved_mode)
+
tty.warn("Patched overlong shebang in %s" % path)
diff --git a/lib/spack/spack/test/sbang.py b/lib/spack/spack/test/sbang.py
index ed54ff90b0..4ce854a1d8 100644
--- a/lib/spack/spack/test/sbang.py
+++ b/lib/spack/spack/test/sbang.py
@@ -26,6 +26,7 @@
Test that Spack's shebang filtering works correctly.
"""
import os
+import stat
import unittest
import tempfile
import shutil
@@ -41,6 +42,7 @@ lua_line_patched = "--!/this/" + ('x' * 200) + "/is/lua\n"
sbang_line = '#!/bin/bash %s/bin/sbang\n' % spack.spack_root
last_line = "last!\n"
+
class SbangTest(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.mkdtemp()
@@ -74,10 +76,8 @@ class SbangTest(unittest.TestCase):
f.write(long_line)
f.write(last_line)
-
def tearDown(self):
- shutil.rmtree(self.tempdir, ignore_errors=True)
-
+ shutil.rmtree(self.tempdir, ignore_errors=True)
def test_shebang_handling(self):
filter_shebangs_in_directory(self.tempdir)
@@ -104,3 +104,14 @@ class SbangTest(unittest.TestCase):
self.assertEqual(f.readline(), sbang_line)
self.assertEqual(f.readline(), long_line)
self.assertEqual(f.readline(), last_line)
+
+ def test_shebang_handles_non_writable_files(self):
+ # make a file non-writable
+ st = os.stat(self.long_shebang)
+ not_writable_mode = st.st_mode & ~stat.S_IWRITE
+ os.chmod(self.long_shebang, not_writable_mode)
+
+ self.test_shebang_handling()
+
+ st = os.stat(self.long_shebang)
+ self.assertEqual(oct(not_writable_mode), oct(st.st_mode))