Add TAU package and routines to filter files, fix sed calls.

- TAU doesn't install to directories with '@' in the name.
- Need to fix up its scripts.
- routines to filter files as sed would, but using python regular expressions.
  - TAU package uses this.
This commit is contained in:
Todd Gamblin 2014-07-02 23:22:38 -07:00
parent a7fd8be514
commit 0551638944
4 changed files with 96 additions and 2 deletions

View File

@ -44,6 +44,7 @@ try:
working_dir = os.getcwd() working_dir = os.getcwd()
except OSError: except OSError:
os.chdir(SPACK_PREFIX) os.chdir(SPACK_PREFIX)
working_dir = SPACK_PREFIX
# clean up the scope and start using spack package instead. # clean up the scope and start using spack package instead.
del SPACK_FILE, SPACK_PREFIX, SPACK_LIB_PATH del SPACK_FILE, SPACK_PREFIX, SPACK_LIB_PATH

View File

@ -23,19 +23,91 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
__all__ = ['install', 'expand_user', 'working_dir', 'touch', 'mkdirp', __all__ = ['install', 'expand_user', 'working_dir', 'touch', 'mkdirp',
'join_path', 'ancestor', 'can_access'] 'join_path', 'ancestor', 'can_access', 'filter_file', 'change_sed_delimiter']
import os import os
import sys
import re import re
import shutil import shutil
import errno import errno
import getpass import getpass
from contextlib import contextmanager, closing from contextlib import contextmanager, closing
from tempfile import NamedTemporaryFile
import llnl.util.tty as tty import llnl.util.tty as tty
from spack.util.compression import ALLOWED_ARCHIVE_TYPES from spack.util.compression import ALLOWED_ARCHIVE_TYPES
def filter_file(regex, repl, *filenames):
"""Like sed, but uses python regular expressions.
Filters every line of file through regex and replaces the file
with a filtered version. Preserves mode of filtered files.
As with re.sub, ``repl`` can be either a string or a callable.
If it is a callable, it is passed the match object and should
return a suitable replacement string. If it is a string, it
can contain ``\1``, ``\2``, etc. to represent back-substitution
as sed would allow.
"""
# Keep callables intact
if not hasattr(repl, '__call__'):
# Allow strings to use \1, \2, etc. for replacement, like sed
unescaped = repl.replace(r'\\', '\\')
repl = lambda m: re.sub(
r'\\([0-9])', lambda x: m.group(int(x.group(1))), unescaped)
for filename in filenames:
backup = filename + "~"
shutil.copy(filename, backup)
try:
with closing(open(backup)) as infile:
with closing(open(filename, 'w')) as outfile:
for line in infile:
foo = re.sub(regex, repl, line)
outfile.write(foo)
except:
# clean up the original file on failure.
shutil.move(backup, filename)
raise
def change_sed_delimiter(old_delim, new_delim, *filenames):
"""Find all sed search/replace commands and change the delimiter.
e.g., if the file contains seds that look like 's///', you can
call change_sed_delimeter('/', '@', file) to change the
delimiter to '@'.
NOTE that this routine will fail if the delimiter is ' or ".
Handling those is left for future work.
"""
assert(len(old_delim) == 1)
assert(len(new_delim) == 1)
# TODO: handle these cases one day?
assert(old_delim != '"')
assert(old_delim != "'")
assert(new_delim != '"')
assert(new_delim != "'")
whole_lines = "^s@([^@]*)@(.*)@[gIp]$"
whole_lines = whole_lines.replace('@', old_delim)
single_quoted = r"'s@((?:\\'|[^@'])*)@((?:\\'|[^'])*)@[gIp]?'"
single_quoted = single_quoted.replace('@', old_delim)
double_quoted = r'"s@((?:\\"|[^@"])*)@((?:\\"|[^"])*)@[gIp]?"'
double_quoted = double_quoted.replace('@', old_delim)
repl = r's@\1@\2@g'
repl = repl.replace('@', new_delim)
for f in filenames:
filter_file(whole_lines, repl, f)
filter_file(single_quoted, "'%s'" % repl, f)
filter_file(double_quoted, '"%s"' % repl, f)
def install(src, dest): def install(src, dest):
"""Manually install a file to a particular location.""" """Manually install a file to a particular location."""
tty.info("Installing %s to %s" % (src, dest)) tty.info("Installing %s to %s" % (src, dest))

View File

@ -33,7 +33,8 @@
# TODO: it's not clear where all the stuff that needs to be included in packages # TODO: it's not clear where all the stuff that needs to be included in packages
# should live. This file is overloaded for spack core vs. for packages. # should live. This file is overloaded for spack core vs. for packages.
__all__ = ['Package', 'when', 'provides', 'depends_on', __all__ = ['Package', 'when', 'provides', 'depends_on',
'patch', 'Version', 'working_dir', 'which', 'Executable'] 'patch', 'Version', 'working_dir', 'which', 'Executable',
'filter_file', 'change_sed_delimiter']
import os import os
import tempfile import tempfile

View File

@ -0,0 +1,20 @@
from spack import *
class Tau(Package):
"""A portable profiling and tracing toolkit for performance
analysis of parallel programs written in Fortran, C, C++, UPC,
Java, Python."""
homepage = "http://www.cs.uoregon.edu/research/tau"
url = "http://www.cs.uoregon.edu/research/paracomp/tau/tauprofile/dist/tau-2.23.1.tar.gz"
versions = { '2.23.1' : '6593b47ae1e7a838e632652f0426fe72', }
def install(self, spec, prefix):
# TAU isn't happy with directories that have '@' in the path. Sigh.
change_sed_delimiter('@', ';', 'configure')
change_sed_delimiter('@', ';', 'utils/FixMakefile')
change_sed_delimiter('@', ';', 'utils/FixMakefile.sed.default')
# After that, it's relatively standard.
configure("-prefix=%s" % prefix)
make("install")