summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/spack4
-rw-r--r--lib/spack/spack/hooks/__init__.py7
-rw-r--r--lib/spack/spack/hooks/case_consistency.py101
-rw-r--r--lib/spack/spack/hooks/yaml_version_check.py (renamed from lib/spack/spack/yaml_version_check.py)2
4 files changed, 109 insertions, 5 deletions
diff --git a/bin/spack b/bin/spack
index 454a9a5b2d..cc9450ade7 100755
--- a/bin/spack
+++ b/bin/spack
@@ -156,8 +156,8 @@ def main():
import spack.util.debug as debug
debug.register_interrupt_handler()
- from spack.yaml_version_check import check_yaml_versions
- check_yaml_versions()
+ # Run any available pre-run hooks
+ spack.hooks.pre_run()
spack.spack_working_dir = working_dir
if args.mock:
diff --git a/lib/spack/spack/hooks/__init__.py b/lib/spack/spack/hooks/__init__.py
index ff4ebc2e57..6454a865b6 100644
--- a/lib/spack/spack/hooks/__init__.py
+++ b/lib/spack/spack/hooks/__init__.py
@@ -64,16 +64,19 @@ class HookRunner(object):
def __init__(self, hook_name):
self.hook_name = hook_name
- def __call__(self, pkg):
+ def __call__(self, *args, **kwargs):
for module in all_hook_modules():
if hasattr(module, self.hook_name):
hook = getattr(module, self.hook_name)
if hasattr(hook, '__call__'):
- hook(pkg)
+ hook(*args, **kwargs)
+
#
# Define some functions that can be called to fire off hooks.
#
+pre_run = HookRunner('pre_run')
+
pre_install = HookRunner('pre_install')
post_install = HookRunner('post_install')
diff --git a/lib/spack/spack/hooks/case_consistency.py b/lib/spack/spack/hooks/case_consistency.py
new file mode 100644
index 0000000000..faf38f7ae3
--- /dev/null
+++ b/lib/spack/spack/hooks/case_consistency.py
@@ -0,0 +1,101 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from __future__ import absolute_import
+import os
+import re
+import platform
+
+from llnl.util.filesystem import *
+
+import spack
+from spack.util.executable import *
+
+
+def pre_run():
+ if platform.system() != "Darwin":
+ return
+
+ git_case_consistency_check(spack.repo.get_repo('builtin').packages_path)
+
+
+def git_case_consistency_check(path):
+ """Re-sync case of files in a directory with git.
+
+ On case-insensitive but case-preserving filesystems like Mac OS X,
+ Git doesn't properly rename files that only had their case changed.
+
+ This checks files in a directory against git and does a
+ case-restoring rename (actually two renames, e.g.::
+
+ name -> tmp -> NAME
+
+ We use this in Spack to ensure package directories are named
+ correctly.
+
+ TODO: this check can probably be removed once package names have been
+ TODO: lowercase for a long while.
+
+ """
+ with working_dir(path):
+ # Don't bother fixing case if Spack isn't in a git repository
+ git = which('git')
+ if not git:
+ return
+
+ try:
+ git_filenames = git('ls-tree', '--name-only', 'HEAD', output=str)
+ git_filenames = set(re.split(r'\s+', git_filenames.strip()))
+ except ProcessError:
+ return # Ignore errors calling git
+
+ lower_to_mixed = {}
+ for fn in git_filenames:
+ lower = fn.lower()
+ mixed = lower_to_mixed.setdefault(lower, [])
+ mixed.append(fn)
+
+ # Iterate through all actual files and make sure their names are
+ # the same as corresponding names in git
+ actual_filenames = os.listdir('.')
+ for actual in actual_filenames:
+ lower = actual.lower()
+
+ # not tracked by git
+ if lower not in lower_to_mixed:
+ continue
+
+ # Don't know what to do with multiple matches
+ if len(lower_to_mixed[lower]) != 1:
+ continue
+
+ # Skip if case is already correct
+ git_name = lower_to_mixed[lower][0]
+ if git_name == actual:
+ continue
+
+ # restore case with two renames
+ tmp_name = actual + '.spack.tmp'
+ os.rename(actual, tmp_name)
+ os.rename(tmp_name, git_name)
diff --git a/lib/spack/spack/yaml_version_check.py b/lib/spack/spack/hooks/yaml_version_check.py
index 2c5b511d7f..a4b38198bc 100644
--- a/lib/spack/spack/yaml_version_check.py
+++ b/lib/spack/spack/hooks/yaml_version_check.py
@@ -31,7 +31,7 @@ import spack.util.spack_yaml as syaml
import spack.config
-def check_yaml_versions():
+def pre_run():
check_compiler_yaml_version()