summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xlib/spack/env/cc6
l---------lib/spack/env/pgi/case-insensitive/pgCC1
l---------lib/spack/env/pgi/pgc++ (renamed from lib/spack/env/pgi/pgf77)0
l---------lib/spack/env/pgi/pgfortran (renamed from lib/spack/env/pgi/pgf90)0
-rw-r--r--lib/spack/llnl/util/filesystem.py36
-rw-r--r--lib/spack/spack/compilers/pgi.py18
-rw-r--r--lib/spack/spack/mirror.py55
-rw-r--r--lib/spack/spack/package.py128
-rw-r--r--lib/spack/spack/stage.py260
-rw-r--r--lib/spack/spack/test/concretize.py2
-rw-r--r--lib/spack/spack/test/config.py6
-rw-r--r--lib/spack/spack/test/configure_guess.py21
-rw-r--r--lib/spack/spack/test/database.py11
-rw-r--r--lib/spack/spack/test/directory_layout.py13
-rw-r--r--lib/spack/spack/test/git_fetch.py46
-rw-r--r--lib/spack/spack/test/hg_fetch.py44
-rw-r--r--lib/spack/spack/test/install.py9
-rw-r--r--lib/spack/spack/test/link_tree.py7
-rw-r--r--lib/spack/spack/test/lock.py8
-rw-r--r--lib/spack/spack/test/make_executable.py6
-rw-r--r--lib/spack/spack/test/mirror.py71
-rw-r--r--lib/spack/spack/test/mock_packages_test.py8
-rw-r--r--lib/spack/spack/test/mock_repo.py4
-rw-r--r--lib/spack/spack/test/multimethod.py5
-rw-r--r--lib/spack/spack/test/namespace_trie.py1
-rw-r--r--lib/spack/spack/test/optional_deps.py4
-rw-r--r--lib/spack/spack/test/packages.py6
-rw-r--r--lib/spack/spack/test/python_version.py3
-rw-r--r--lib/spack/spack/test/spec_dag.py2
-rw-r--r--lib/spack/spack/test/spec_semantics.py1
-rw-r--r--lib/spack/spack/test/spec_syntax.py3
-rw-r--r--lib/spack/spack/test/stage.py136
-rw-r--r--lib/spack/spack/test/svn_fetch.py47
-rw-r--r--lib/spack/spack/test/tally_plugin.py4
-rw-r--r--lib/spack/spack/test/unit_install.py3
-rw-r--r--lib/spack/spack/test/url_extrapolate.py3
-rw-r--r--lib/spack/spack/test/url_parse.py2
-rw-r--r--lib/spack/spack/test/url_substitution.py1
-rw-r--r--lib/spack/spack/test/versions.py1
-rw-r--r--lib/spack/spack/test/yaml.py1
-rw-r--r--var/spack/repos/builtin/packages/jdk/package.py4
-rw-r--r--var/spack/repos/builtin/packages/libevent/package.py9
-rw-r--r--var/spack/repos/builtin/packages/libsigsegv/package.py15
-rw-r--r--var/spack/repos/builtin/packages/llvm/package.py19
-rw-r--r--var/spack/repos/builtin/packages/m4/package.py12
-rw-r--r--var/spack/repos/builtin/packages/mpc/package.py6
46 files changed, 538 insertions, 510 deletions
diff --git a/lib/spack/env/cc b/lib/spack/env/cc
index a323c48124..b8b6c86e01 100755
--- a/lib/spack/env/cc
+++ b/lib/spack/env/cc
@@ -90,15 +90,15 @@ case "$command" in
command="$SPACK_CC"
language="C"
;;
- c++|CC|g++|clang++|icpc|pgCC|xlc++)
+ c++|CC|g++|clang++|icpc|pgc++|xlc++)
command="$SPACK_CXX"
language="C++"
;;
- f90|fc|f95|gfortran|ifort|pgf90|xlf90|nagfor)
+ f90|fc|f95|gfortran|ifort|pgfortran|xlf90|nagfor)
command="$SPACK_FC"
language="Fortran 90"
;;
- f77|gfortran|ifort|pgf77|xlf|nagfor)
+ f77|gfortran|ifort|pgfortran|xlf|nagfor)
command="$SPACK_F77"
language="Fortran 77"
;;
diff --git a/lib/spack/env/pgi/case-insensitive/pgCC b/lib/spack/env/pgi/case-insensitive/pgCC
deleted file mode 120000
index e2deb67f3b..0000000000
--- a/lib/spack/env/pgi/case-insensitive/pgCC
+++ /dev/null
@@ -1 +0,0 @@
-../../cc \ No newline at end of file
diff --git a/lib/spack/env/pgi/pgf77 b/lib/spack/env/pgi/pgc++
index 82c2b8e90a..82c2b8e90a 120000
--- a/lib/spack/env/pgi/pgf77
+++ b/lib/spack/env/pgi/pgc++
diff --git a/lib/spack/env/pgi/pgf90 b/lib/spack/env/pgi/pgfortran
index 82c2b8e90a..82c2b8e90a 120000
--- a/lib/spack/env/pgi/pgf90
+++ b/lib/spack/env/pgi/pgfortran
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py
index 10d25bdce8..9ba662d0e3 100644
--- a/lib/spack/llnl/util/filesystem.py
+++ b/lib/spack/llnl/util/filesystem.py
@@ -26,7 +26,7 @@ __all__ = ['set_install_permissions', 'install', 'install_tree', 'traverse_tree'
'expand_user', 'working_dir', 'touch', 'touchp', 'mkdirp',
'force_remove', 'join_path', 'ancestor', 'can_access', 'filter_file',
'FileFilter', 'change_sed_delimiter', 'is_exe', 'force_symlink',
- 'copy_mode', 'unset_executable_mode']
+ 'remove_dead_links', 'remove_linked_tree', 'copy_mode', 'unset_executable_mode']
import os
import sys
@@ -249,7 +249,7 @@ def touchp(path):
def force_symlink(src, dest):
try:
os.symlink(src, dest)
- except OSError, e:
+ except OSError as e:
os.remove(dest)
os.symlink(src, dest)
@@ -353,3 +353,35 @@ def traverse_tree(source_root, dest_root, rel_path='', **kwargs):
if order == 'post':
yield (source_path, dest_path)
+
+def remove_dead_links(root):
+ """
+ Removes any dead link that is present in root
+
+ Args:
+ root: path where to search for dead links
+
+ """
+ for file in os.listdir(root):
+ path = join_path(root, file)
+ if os.path.islink(path):
+ real_path = os.path.realpath(path)
+ if not os.path.exists(real_path):
+ os.unlink(path)
+
+def remove_linked_tree(path):
+ """
+ Removes a directory and its contents. If the directory is a
+ symlink, follows the link and removes the real directory before
+ removing the link.
+
+ Args:
+ path: directory to be removed
+
+ """
+ if os.path.exists(path):
+ if os.path.islink(path):
+ shutil.rmtree(os.path.realpath(path), True)
+ os.unlink(path)
+ else:
+ shutil.rmtree(path, True)
diff --git a/lib/spack/spack/compilers/pgi.py b/lib/spack/spack/compilers/pgi.py
index 9ac74cfbdb..c6a1078bd9 100644
--- a/lib/spack/spack/compilers/pgi.py
+++ b/lib/spack/spack/compilers/pgi.py
@@ -29,28 +29,28 @@ class Pgi(Compiler):
cc_names = ['pgcc']
# Subclasses use possible names of C++ compiler
- cxx_names = ['pgCC']
+ cxx_names = ['pgc++', 'pgCC']
# Subclasses use possible names of Fortran 77 compiler
- f77_names = ['pgf77']
+ f77_names = ['pgfortran', 'pgf77']
# Subclasses use possible names of Fortran 90 compiler
- fc_names = ['pgf95', 'pgf90']
+ fc_names = ['pgfortran', 'pgf95', 'pgf90']
# Named wrapper links within spack.build_env_path
link_paths = { 'cc' : 'pgi/pgcc',
- 'cxx' : 'pgi/case-insensitive/pgCC',
- 'f77' : 'pgi/pgf77',
- 'fc' : 'pgi/pgf90' }
+ 'cxx' : 'pgi/pgc++',
+ 'f77' : 'pgi/pgfortran',
+ 'fc' : 'pgi/pgfortran' }
@classmethod
def default_version(cls, comp):
"""The '-V' option works for all the PGI compilers.
Output looks like this::
- pgf95 10.2-0 64-bit target on x86-64 Linux -tp nehalem-64
- Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
- Copyright 2000-2010, STMicroelectronics, Inc. All Rights Reserved.
+ pgcc 15.10-0 64-bit target on x86-64 Linux -tp sandybridge
+ The Portland Group - PGI Compilers and Tools
+ Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
"""
return get_compiler_version(
comp, '-V', r'pg[^ ]* ([^ ]+) \d\d\d?-bit target')
diff --git a/lib/spack/spack/mirror.py b/lib/spack/spack/mirror.py
index 58e31c2c7b..fdc4e7967f 100644
--- a/lib/spack/spack/mirror.py
+++ b/lib/spack/spack/mirror.py
@@ -110,7 +110,6 @@ def suggest_archive_basename(resource):
return basename
-
def create(path, specs, **kwargs):
"""Create a directory to be used as a spack mirror, and fill it with
package archives.
@@ -158,17 +157,29 @@ def create(path, specs, **kwargs):
"Cannot create directory '%s':" % mirror_root, str(e))
# Things to keep track of while parsing specs.
- present = []
- mirrored = []
- error = []
+ categories = {
+ 'present': [],
+ 'mirrored': [],
+ 'error': []
+ }
# Iterate through packages and download all the safe tarballs for each of them
- everything_already_exists = True
for spec in version_specs:
- pkg = spec.package
- tty.msg("Adding package {pkg} to mirror".format(pkg=spec.format("$_$@")))
- try:
- for ii, stage in enumerate(pkg.stage):
+ add_single_spec(spec, mirror_root, categories, **kwargs)
+
+ return categories['present'], categories['mirrored'], categories['error']
+
+
+def add_single_spec(spec, mirror_root, categories, **kwargs):
+ tty.msg("Adding package {pkg} to mirror".format(pkg=spec.format("$_$@")))
+ spec_exists_in_mirror = True
+ try:
+ with spec.package.stage:
+ # fetcher = stage.fetcher
+ # fetcher.fetch()
+ # ...
+ # fetcher.archive(archive_path)
+ for ii, stage in enumerate(spec.package.stage):
fetcher = stage.fetcher
if ii == 0:
# create a subdirectory for the current package@version
@@ -184,7 +195,7 @@ def create(path, specs, **kwargs):
if os.path.exists(archive_path):
tty.msg("{name} : already added".format(name=name))
else:
- everything_already_exists = False
+ spec_exists_in_mirror = False
fetcher.fetch()
if not kwargs.get('no_checksum', False):
fetcher.check()
@@ -195,20 +206,16 @@ def create(path, specs, **kwargs):
fetcher.archive(archive_path)
tty.msg("{name} : added".format(name=name))
- if everything_already_exists:
- present.append(spec)
- else:
- mirrored.append(spec)
- except Exception, e:
- if spack.debug:
- sys.excepthook(*sys.exc_info())
- else:
- tty.warn("Error while fetching %s" % spec.format('$_$@'), e.message)
- error.append(spec)
- finally:
- pkg.stage.destroy()
-
- return (present, mirrored, error)
+ if spec_exists_in_mirror:
+ categories['present'].append(spec)
+ else:
+ categories['mirrored'].append(spec)
+ except Exception as e:
+ if spack.debug:
+ sys.excepthook(*sys.exc_info())
+ else:
+ tty.warn("Error while fetching %s" % spec.format('$_$@'), e.message)
+ categories['error'].append(spec)
class MirrorError(spack.error.SpackError):
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index fb96f61de9..ce8cce27e2 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -456,7 +456,7 @@ class Package(object):
# Construct a composite stage on top of the composite FetchStrategy
composite_fetcher = self.fetcher
composite_stage = StageComposite()
- resources = self._get_resources()
+ resources = self._get_needed_resources()
for ii, fetcher in enumerate(composite_fetcher):
if ii == 0:
# Construct root stage first
@@ -467,6 +467,11 @@ class Package(object):
stage = self._make_resource_stage(composite_stage[0], fetcher, resource)
# Append the item to the composite
composite_stage.append(stage)
+
+ # Create stage on first access. Needed because fetch, stage,
+ # patch, and install can be called independently of each
+ # other, so `with self.stage:` in do_install isn't sufficient.
+ composite_stage.create()
return composite_stage
@property
@@ -485,12 +490,14 @@ class Package(object):
def _make_fetcher(self):
- # Construct a composite fetcher that always contains at least one element (the root package). In case there
- # are resources associated with the package, append their fetcher to the composite.
+ # Construct a composite fetcher that always contains at least
+ # one element (the root package). In case there are resources
+ # associated with the package, append their fetcher to the
+ # composite.
root_fetcher = fs.for_package_version(self, self.version)
fetcher = fs.FetchStrategyComposite() # Composite fetcher
fetcher.append(root_fetcher) # Root fetcher is always present
- resources = self._get_resources()
+ resources = self._get_needed_resources()
for resource in resources:
fetcher.append(resource.fetcher)
return fetcher
@@ -503,7 +510,6 @@ class Package(object):
self._fetcher = self._make_fetcher()
return self._fetcher
-
@fetcher.setter
def fetcher(self, f):
self._fetcher = f
@@ -708,6 +714,7 @@ class Package(object):
self.stage.expand_archive()
self.stage.chdir_to_source()
+
def do_patch(self):
"""Calls do_stage(), then applied patches to the expanded tarball if they
haven't been applied already."""
@@ -735,7 +742,7 @@ class Package(object):
# If we encounter an archive that failed to patch, restage it
# so that we can apply all the patches again.
if os.path.isfile(bad_file):
- tty.msg("Patching failed last time. Restaging.")
+ tty.msg("Patching failed last time. Restaging.")
self.stage.restage()
self.stage.chdir_to_source()
@@ -800,7 +807,7 @@ class Package(object):
mkdirp(self.prefix.man1)
- def _get_resources(self):
+ def _get_needed_resources(self):
resources = []
# Select the resources that are needed for this build
for when_spec, resource_list in self.resources.items():
@@ -818,7 +825,7 @@ class Package(object):
def do_install(self,
- keep_prefix=False, keep_stage=False, ignore_deps=False,
+ keep_prefix=False, keep_stage=None, ignore_deps=False,
skip_patch=False, verbose=False, make_jobs=None, fake=False):
"""Called by commands to install a package and its dependencies.
@@ -827,7 +834,8 @@ class Package(object):
Args:
keep_prefix -- Keep install prefix on failure. By default, destroys it.
- keep_stage -- Keep stage on successful build. By default, destroys it.
+ keep_stage -- Set to True or false to always keep or always delete stage.
+ By default, stage is destroyed only if there are no exceptions.
ignore_deps -- Do not install dependencies before installing this package.
fake -- Don't really build -- install fake stub files instead.
skip_patch -- Skip patch stage of build if True.
@@ -843,87 +851,86 @@ class Package(object):
tty.msg("Installing %s" % self.name)
+ # First, install dependencies recursively.
if not ignore_deps:
self.do_install_dependencies(
keep_prefix=keep_prefix, keep_stage=keep_stage, ignore_deps=ignore_deps,
- fake=fake, skip_patch=skip_patch, verbose=verbose,
- make_jobs=make_jobs)
-
- start_time = time.time()
- if not fake:
- if not skip_patch:
- self.do_patch()
- else:
- self.do_stage()
-
- # create the install directory. The install layout
- # handles this in case so that it can use whatever
- # package naming scheme it likes.
- spack.install_layout.create_install_directory(self.spec)
+ fake=fake, skip_patch=skip_patch, verbose=verbose, make_jobs=make_jobs)
def cleanup():
+ """Handles removing install prefix on error."""
if not keep_prefix:
- # If anything goes wrong, remove the install prefix
self.remove_prefix()
else:
tty.warn("Keeping install prefix in place despite error.",
- "Spack will think this package is installed." +
+ "Spack will think this package is installed. " +
"Manually remove this directory to fix:",
self.prefix, wrap=True)
-
+ # Then install the package itself.
def real_work():
+ """Forked for each build. Has its own process and python
+ module space set up by build_environment.fork()."""
+ start_time = time.time()
+ if not fake:
+ if not skip_patch:
+ self.do_patch()
+ else:
+ self.do_stage()
+
+ # create the install directory. The install layout
+ # handles this in case so that it can use whatever
+ # package naming scheme it likes.
+ spack.install_layout.create_install_directory(self.spec)
+
try:
tty.msg("Building %s" % self.name)
- # Run the pre-install hook in the child process after
- # the directory is created.
- spack.hooks.pre_install(self)
+ self.stage.keep = keep_stage
+ with self.stage:
+ # Run the pre-install hook in the child process after
+ # the directory is created.
+ spack.hooks.pre_install(self)
- # Set up process's build environment before running install.
- if fake:
- self.do_fake_install()
- else:
- # Do the real install in the source directory.
- self.stage.chdir_to_source()
+ if fake:
+ self.do_fake_install()
- # Save the build environment in a file before building.
- env_path = join_path(os.getcwd(), 'spack-build.env')
+ else:
+ # Do the real install in the source directory.
+ self.stage.chdir_to_source()
- # This redirects I/O to a build log (and optionally to the terminal)
- log_path = join_path(os.getcwd(), 'spack-build.out')
- log_file = open(log_path, 'w')
- with log_output(log_file, verbose, sys.stdout.isatty(), True):
- dump_environment(env_path)
- self.install(self.spec, self.prefix)
+ # Save the build environment in a file before building.
+ env_path = join_path(os.getcwd(), 'spack-build.env')
- # Ensure that something was actually installed.
- self._sanity_check_install()
+ # Redirect I/O to a build log (and optionally to the terminal)
+ log_path = join_path(os.getcwd(), 'spack-build.out')
+ log_file = open(log_path, 'w')
+ with log_output(log_file, verbose, sys.stdout.isatty(), True):
+ dump_environment(env_path)
+ self.install(self.spec, self.prefix)
- # Move build log into install directory on success
- if not fake:
- log_install_path = spack.install_layout.build_log_path(self.spec)
- env_install_path = spack.install_layout.build_env_path(self.spec)
- install(log_path, log_install_path)
- install(env_path, env_install_path)
+ # Ensure that something was actually installed.
+ self._sanity_check_install()
- packages_dir = spack.install_layout.build_packages_path(self.spec)
- dump_packages(self.spec, packages_dir)
+ # Copy provenance into the install directory on success
+ log_install_path = spack.install_layout.build_log_path(self.spec)
+ env_install_path = spack.install_layout.build_env_path(self.spec)
+ packages_dir = spack.install_layout.build_packages_path(self.spec)
- # On successful install, remove the stage.
- if not keep_stage:
- self.stage.destroy()
+ install(log_path, log_install_path)
+ install(env_path, env_install_path)
+ dump_packages(self.spec, packages_dir)
# Stop timer.
self._total_time = time.time() - start_time
build_time = self._total_time - self._fetch_time
tty.msg("Successfully installed %s" % self.name,
- "Fetch: %s. Build: %s. Total: %s"
+ "Fetch: %s. Build: %s. Total: %s."
% (_hms(self._fetch_time), _hms(build_time), _hms(self._total_time)))
print_pkg(self.prefix)
- except ProcessError, e:
+ except ProcessError as e:
# Annotate with location of build log.
e.build_log = log_path
cleanup()
@@ -1152,8 +1159,7 @@ class Package(object):
def do_clean(self):
"""Removes the package's build stage and source tarball."""
- if os.path.exists(self.stage.path):
- self.stage.destroy()
+ self.stage.destroy()
def format_doc(self, **kwargs):
@@ -1192,7 +1198,7 @@ class Package(object):
try:
return spack.util.web.find_versions_of_archive(
*self.all_urls, list_url=self.list_url, list_depth=self.list_depth)
- except spack.error.NoNetworkConnectionError, e:
+ except spack.error.NoNetworkConnectionError as e:
tty.die("Package.fetch_versions couldn't connect to:",
e.url, e.message)
diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py
index 5591cb9ba5..b117c76aa1 100644
--- a/lib/spack/spack/stage.py
+++ b/lib/spack/spack/stage.py
@@ -42,36 +42,53 @@ STAGE_PREFIX = 'spack-stage-'
class Stage(object):
- """A Stage object manages a directory where some source code is
- downloaded and built before being installed. It handles
- fetching the source code, either as an archive to be expanded
- or by checking it out of a repository. A stage's lifecycle
- looks like this:
-
- Stage()
- Constructor creates the stage directory.
- fetch()
- Fetch a source archive into the stage.
- expand_archive()
- Expand the source archive.
- <install>
- Build and install the archive. This is handled by the Package class.
- destroy()
- Remove the stage once the package has been installed.
-
- If spack.use_tmp_stage is True, spack will attempt to create stages
- in a tmp directory. Otherwise, stages are created directly in
- spack.stage_path.
-
- There are two kinds of stages: named and unnamed. Named stages can
- persist between runs of spack, e.g. if you fetched a tarball but
- didn't finish building it, you won't have to fetch it again.
-
- Unnamed stages are created using standard mkdtemp mechanisms or
- similar, and are intended to persist for only one run of spack.
+ """Manages a temporary stage directory for building.
+
+ A Stage object is a context manager that handles a directory where
+ some source code is downloaded and built before being installed.
+ It handles fetching the source code, either as an archive to be
+ expanded or by checking it out of a repository. A stage's
+ lifecycle looks like this:
+
+ ```
+ with Stage() as stage: # Context manager creates and destroys the stage directory
+ stage.fetch() # Fetch a source archive into the stage.
+ stage.expand_archive() # Expand the source archive.
+ <install> # Build and install the archive. (handled by user of Stage)
+ ```
+
+ When used as a context manager, the stage is automatically
+ destroyed if no exception is raised by the context. If an
+ excpetion is raised, the stage is left in the filesystem and NOT
+ destroyed, for potential reuse later.
+
+ You can also use the stage's create/destroy functions manually,
+ like this:
+
+ ```
+ stage = Stage()
+ try:
+ stage.create() # Explicitly create the stage directory.
+ stage.fetch() # Fetch a source archive into the stage.
+ stage.expand_archive() # Expand the source archive.
+ <install> # Build and install the archive. (handled by user of Stage)
+ finally:
+ stage.destroy() # Explicitly destroy the stage directory.
+ ```
+
+ If spack.use_tmp_stage is True, spack will attempt to create
+ stages in a tmp directory. Otherwise, stages are created directly
+ in spack.stage_path.
+
+ There are two kinds of stages: named and unnamed. Named stages
+ can persist between runs of spack, e.g. if you fetched a tarball
+ but didn't finish building it, you won't have to fetch it again.
+
+ Unnamed stages are created using standard mkdtemp mechanisms or
+ similar, and are intended to persist for only one run of spack.
"""
- def __init__(self, url_or_fetch_strategy, **kwargs):
+ def __init__(self, url_or_fetch_strategy, name=None, mirror_path=None, keep=None):
"""Create a stage object.
Parameters:
url_or_fetch_strategy
@@ -83,6 +100,18 @@ class Stage(object):
and will persist between runs (or if you construct another
stage object later). If name is not provided, then this
stage will be given a unique name automatically.
+
+ mirror_path
+ If provided, Stage will search Spack's mirrors for
+ this archive at the mirror_path, before using the
+ default fetch strategy.
+
+ keep
+ By default, when used as a context manager, the Stage
+ is cleaned up when everything goes well, and it is
+ kept intact when an exception is raised. You can
+ override this behavior by setting keep to True
+ (always keep) or False (always delete).
"""
# TODO: fetch/stage coupling needs to be reworked -- the logic
# TODO: here is convoluted and not modular enough.
@@ -96,21 +125,55 @@ class Stage(object):
self.default_fetcher = self.fetcher # self.fetcher can change with mirrors.
self.skip_checksum_for_mirror = True # used for mirrored archives of repositories.
- self.name = kwargs.get('name')
- self.mirror_path = kwargs.get('mirror_path')
+ # TODO : this uses a protected member of tempfile, but seemed the only way to get a temporary name
+ # TODO : besides, the temporary link name won't be the same as the temporary stage area in tmp_root
+ self.name = name
+ if name is None:
+ self.name = STAGE_PREFIX + next(tempfile._get_candidate_names())
+ self.mirror_path = mirror_path
self.tmp_root = find_tmp_root()
- self.path = None
- self._setup()
+ # Try to construct here a temporary name for the stage directory
+ # If this is a named stage, then construct a named path.
+ self.path = join_path(spack.stage_path, self.name)
+
+ # Flag to decide whether to delete the stage folder on exit or not
+ self.keep = keep
+
+
+ def __enter__(self):
+ """
+ Entering a stage context will create the stage directory
+
+ Returns:
+ self
+ """
+ self.create()
+ return self
+
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ """
+ Exiting from a stage context will delete the stage directory unless:
+ - it was explicitly requested not to do so
+ - an exception has been raised
+
+ Args:
+ exc_type: exception type
+ exc_val: exception value
+ exc_tb: exception traceback
+
+ Returns:
+ Boolean
+ """
+ if self.keep is None:
+ # Default: delete when there are no exceptions.
+ if exc_type is None: self.destroy()
+
+ elif not self.keep:
+ # Overridden. Either always keep or always delete.
+ self.destroy()
- def _cleanup_dead_links(self):
- """Remove any dead links in the stage directory."""
- for file in os.listdir(spack.stage_path):
- path = join_path(spack.stage_path, file)
- if os.path.islink(path):
- real_path = os.path.realpath(path)
- if not os.path.exists(path):
- os.unlink(path)
def _need_to_create_path(self):
"""Makes sure nothing weird has happened since the last time we
@@ -148,54 +211,6 @@ class Stage(object):
return False
- def _setup(self):
- """Creates the stage directory.
- If spack.use_tmp_stage is False, the stage directory is created
- directly under spack.stage_path.
-
- If spack.use_tmp_stage is True, this will attempt to create a
- stage in a temporary directory and link it into spack.stage_path.
- Spack will use the first writable location in spack.tmp_dirs to
- create a stage. If there is no valid location in tmp_dirs, fall
- back to making the stage inside spack.stage_path.
- """
- # Create the top-level stage directory
- mkdirp(spack.stage_path)
- self._cleanup_dead_links()
-
- # If this is a named stage, then construct a named path.
- if self.name is not None:
- self.path = join_path(spack.stage_path, self.name)
-
- # If this is a temporary stage, them make the temp directory
- tmp_dir = None
- if self.tmp_root:
- if self.name is None:
- # Unnamed tmp root. Link the path in
- tmp_dir = tempfile.mkdtemp('', STAGE_PREFIX, self.tmp_root)
- self.name = os.path.basename(tmp_dir)
- self.path = join_path(spack.stage_path, self.name)
- if self._need_to_create_path():
- os.symlink(tmp_dir, self.path)
-
- else:
- if self._need_to_create_path():
- tmp_dir = tempfile.mkdtemp('', STAGE_PREFIX, self.tmp_root)
- os.symlink(tmp_dir, self.path)
-
- # if we're not using a tmp dir, create the stage directly in the
- # stage dir, rather than linking to it.
- else:
- if self.name is None:
- self.path = tempfile.mkdtemp('', STAGE_PREFIX, spack.stage_path)
- self.name = os.path.basename(self.path)
- else:
- if self._need_to_create_path():
- mkdirp(self.path)
-
- # Make sure we can actually do something with the stage we made.
- ensure_access(self.path)
-
@property
def archive_file(self):
"""Path to the source archive within this stage directory."""
@@ -231,7 +246,7 @@ class Stage(object):
if os.path.isdir(self.path):
os.chdir(self.path)
else:
- tty.die("Setup failed: no such directory: " + self.path)
+ raise ChdirError("Setup failed: no such directory: " + self.path)
def fetch(self, mirror_only=False):
"""Downloads an archive or checks out code from a repository."""
@@ -276,7 +291,7 @@ class Stage(object):
self.fetcher = fetcher
self.fetcher.fetch()
break
- except spack.error.SpackError, e:
+ except spack.error.SpackError as e:
tty.msg("Fetching from %s failed." % fetcher)
tty.debug(e)
continue
@@ -328,8 +343,35 @@ class Stage(object):
"""
self.fetcher.reset()
+ def create(self):
+ """
+ Creates the stage directory
+
+ If self.tmp_root evaluates to False, the stage directory is
+ created directly under spack.stage_path, otherwise this will
+ attempt to create a stage in a temporary directory and link it
+ into spack.stage_path.
+
+ Spack will use the first writable location in spack.tmp_dirs
+ to create a stage. If there is no valid location in tmp_dirs,
+ fall back to making the stage inside spack.stage_path.
+ """
+ # Create the top-level stage directory
+ mkdirp(spack.stage_path)
+ remove_dead_links(spack.stage_path)
+ # If a tmp_root exists then create a directory there and then link it in the stage area,
+ # otherwise create the stage directory in self.path
+ if self._need_to_create_path():
+ if self.tmp_root:
+ tmp_dir = tempfile.mkdtemp('', STAGE_PREFIX, self.tmp_root)
+ os.symlink(tmp_dir, self.path)
+ else:
+ mkdirp(self.path)
+ # Make sure we can actually do something with the stage we made.
+ ensure_access(self.path)
+
def destroy(self):
- """Remove this stage directory."""
+ """Removes this stage directory."""
remove_linked_tree(self.path)
# Make sure we don't end up in a removed directory
@@ -374,7 +416,7 @@ class ResourceStage(Stage):
shutil.move(source_path, destination_path)
-@pattern.composite(method_list=['fetch', 'check', 'expand_archive', 'restage', 'destroy'])
+@pattern.composite(method_list=['fetch', 'create', 'check', 'expand_archive', 'restage', 'destroy'])
class StageComposite:
"""
Composite for Stage type objects. The first item in this composite is considered to be the root package, and
@@ -389,6 +431,15 @@ class StageComposite:
def path(self):
return self[0].path
+ def __enter__(self):
+ for item in self:
+ item.__enter__()
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ for item in reversed(self):
+ item.__exit__(exc_type, exc_val, exc_tb)
+
def chdir_to_source(self):
return self[0].chdir_to_source()
@@ -405,7 +456,7 @@ class DIYStage(object):
if os.path.isdir(self.path):
os.chdir(self.path)
else:
- tty.die("Setup failed: no such directory: " + self.path)
+ raise ChdirError("Setup failed: no such directory: " + self.path)
def chdir_to_source(self):
self.chdir()
@@ -439,19 +490,6 @@ def ensure_access(file=spack.stage_path):
tty.die("Insufficient permissions for %s" % file)
-def remove_linked_tree(path):
- """Removes a directory and its contents. If the directory is a symlink,
- follows the link and reamoves the real directory before removing the
- link.
- """
- if os.path.exists(path):
- if os.path.islink(path):
- shutil.rmtree(os.path.realpath(path), True)
- os.unlink(path)
- else:
- shutil.rmtree(path, True)
-
-
def purge():
"""Remove all build directories in the top-level stage path."""
if os.path.isdir(spack.stage_path):
@@ -480,19 +518,15 @@ def find_tmp_root():
class StageError(spack.error.SpackError):
- def __init__(self, message, long_message=None):
- super(self, StageError).__init__(message, long_message)
+ """"Superclass for all errors encountered during staging."""
class RestageError(StageError):
- def __init__(self, message, long_msg=None):
- super(RestageError, self).__init__(message, long_msg)
+ """"Error encountered during restaging."""
class ChdirError(StageError):
- def __init__(self, message, long_msg=None):
- super(ChdirError, self).__init__(message, long_msg)
-
+ """Raised when Spack can't change directories."""
# Keep this in namespace for convenience
FailedDownloadError = fs.FailedDownloadError
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 7f2938aec5..794344fb6a 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -22,8 +22,6 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-import unittest
-
import spack
from spack.spec import Spec, CompilerSpec
from spack.test.mock_packages_test import *
diff --git a/lib/spack/spack/test/config.py b/lib/spack/spack/test/config.py
index d8be5a855b..0562d2d620 100644
--- a/lib/spack/spack/test/config.py
+++ b/lib/spack/spack/test/config.py
@@ -22,13 +22,13 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-import unittest
-import shutil
import os
+import shutil
from tempfile import mkdtemp
-from ordereddict_backport import OrderedDict
+
import spack
import spack.config
+from ordereddict_backport import OrderedDict
from spack.test.mock_packages_test import *
# Some sample compiler config data
diff --git a/lib/spack/spack/test/configure_guess.py b/lib/spack/spack/test/configure_guess.py
index a4e8565b62..2440d120e5 100644
--- a/lib/spack/spack/test/configure_guess.py
+++ b/lib/spack/spack/test/configure_guess.py
@@ -23,20 +23,15 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import os
-import unittest
import shutil
import tempfile
+import unittest
from llnl.util.filesystem import *
-
from spack.cmd.create import ConfigureGuesser
from spack.stage import Stage
-
-from spack.fetch_strategy import URLFetchStrategy
-from spack.directory_layout import YamlDirectoryLayout
-from spack.util.executable import which
from spack.test.mock_packages_test import *
-from spack.test.mock_repo import MockArchive
+from spack.util.executable import which
class InstallTest(unittest.TestCase):
@@ -52,8 +47,6 @@ class InstallTest(unittest.TestCase):
def tearDown(self):
shutil.rmtree(self.tmpdir, ignore_errors=True)
- if self.stage:
- self.stage.destroy()
os.chdir(self.orig_dir)
@@ -64,12 +57,12 @@ class InstallTest(unittest.TestCase):
url = 'file://' + join_path(os.getcwd(), 'archive.tar.gz')
print url
- self.stage = Stage(url)
- self.stage.fetch()
+ with Stage(url) as stage:
+ stage.fetch()
- guesser = ConfigureGuesser()
- guesser(self.stage)
- self.assertEqual(system, guesser.build_system)
+ guesser = ConfigureGuesser()
+ guesser(stage)
+ self.assertEqual(system, guesser.build_system)
def test_python(self):
diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py
index 0205f4b8ce..9a57e1f03e 100644
--- a/lib/spack/spack/test/database.py
+++ b/lib/spack/spack/test/database.py
@@ -26,19 +26,18 @@
These tests check the database is functioning properly,
both in memory and in its file
"""
-import tempfile
-import shutil
import multiprocessing
-
-from llnl.util.lock import *
-from llnl.util.filesystem import join_path
+import shutil
+import tempfile
import spack
+from llnl.util.filesystem import join_path
+from llnl.util.lock import *
+from llnl.util.tty.colify import colify
from spack.database import Database
from spack.directory_layout import YamlDirectoryLayout
from spack.test.mock_packages_test import *
-from llnl.util.tty.colify import colify
def _print_ref_counts():
"""Print out all ref counts for the graph used here, for debugging"""
diff --git a/lib/spack/spack/test/directory_layout.py b/lib/spack/spack/test/directory_layout.py
index 925cb648ed..d814572d4a 100644
--- a/lib/spack/spack/test/directory_layout.py
+++ b/lib/spack/spack/test/directory_layout.py
@@ -25,20 +25,17 @@
"""\
This test verifies that the Spack directory layout works properly.
"""
-import unittest
-import tempfile
-import shutil
import os
-
-from llnl.util.filesystem import *
+import shutil
+import tempfile
import spack
-from spack.spec import Spec
-from spack.repository import RepoPath
+from llnl.util.filesystem import *
from spack.directory_layout import YamlDirectoryLayout
+from spack.repository import RepoPath
+from spack.spec import Spec
from spack.test.mock_packages_test import *
-
# number of packages to test (to reduce test time)
max_packages = 10
diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py
index d84433176a..3578044116 100644
--- a/lib/spack/spack/test/git_fetch.py
+++ b/lib/spack/spack/test/git_fetch.py
@@ -23,19 +23,12 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import os
-import unittest
-import shutil
-import tempfile
-
-from llnl.util.filesystem import *
import spack
-from spack.version import ver
-from spack.stage import Stage
-from spack.util.executable import which
-
+from llnl.util.filesystem import *
from spack.test.mock_packages_test import *
from spack.test.mock_repo import MockGitRepo
+from spack.version import ver
class GitFetchTest(MockPackagesTest):
@@ -52,19 +45,15 @@ class GitFetchTest(MockPackagesTest):
spec.concretize()
self.pkg = spack.repo.get(spec, new=True)
-
def tearDown(self):
"""Destroy the stage space used by this test."""
super(GitFetchTest, self).tearDown()
self.repo.destroy()
- self.pkg.do_clean()
-
def assert_rev(self, rev):
"""Check that the current git revision is equal to the supplied rev."""
self.assertEqual(self.repo.rev_hash('HEAD'), self.repo.rev_hash(rev))
-
def try_fetch(self, rev, test_file, args):
"""Tries to:
1. Fetch the repo using a fetch strategy constructed with
@@ -76,26 +65,27 @@ class GitFetchTest(MockPackagesTest):
"""
self.pkg.versions[ver('git')] = args
- self.pkg.do_stage()
- self.assert_rev(rev)
+ with self.pkg.stage:
+ self.pkg.do_stage()
+ self.assert_rev(rev)
- file_path = join_path(self.pkg.stage.source_path, test_file)
- self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
- self.assertTrue(os.path.isfile(file_path))
+ file_path = join_path(self.pkg.stage.source_path, test_file)
+ self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
+ self.assertTrue(os.path.isfile(file_path))
- os.unlink(file_path)
- self.assertFalse(os.path.isfile(file_path))
+ os.unlink(file_path)
+ self.assertFalse(os.path.isfile(file_path))
- untracked_file = 'foobarbaz'
- touch(untracked_file)
- self.assertTrue(os.path.isfile(untracked_file))
- self.pkg.do_restage()
- self.assertFalse(os.path.isfile(untracked_file))
+ untracked_file = 'foobarbaz'
+ touch(untracked_file)
+ self.assertTrue(os.path.isfile(untracked_file))
+ self.pkg.do_restage()
+ self.assertFalse(os.path.isfile(untracked_file))
- self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
- self.assertTrue(os.path.isfile(file_path))
+ self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
+ self.assertTrue(os.path.isfile(file_path))
- self.assert_rev(rev)
+ self.assert_rev(rev)
def test_fetch_master(self):
diff --git a/lib/spack/spack/test/hg_fetch.py b/lib/spack/spack/test/hg_fetch.py
index bbcb64e4c1..b8a0c1ec46 100644
--- a/lib/spack/spack/test/hg_fetch.py
+++ b/lib/spack/spack/test/hg_fetch.py
@@ -23,16 +23,12 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import os
-import unittest
-
-from llnl.util.filesystem import *
-
import spack
+
from spack.version import ver
-from spack.stage import Stage
-from spack.util.executable import which
-from spack.test.mock_packages_test import *
from spack.test.mock_repo import MockHgRepo
+from llnl.util.filesystem import *
+from spack.test.mock_packages_test import *
class HgFetchTest(MockPackagesTest):
@@ -49,13 +45,10 @@ class HgFetchTest(MockPackagesTest):
spec.concretize()
self.pkg = spack.repo.get(spec, new=True)
-
def tearDown(self):
"""Destroy the stage space used by this test."""
super(HgFetchTest, self).tearDown()
self.repo.destroy()
- self.pkg.do_clean()
-
def try_fetch(self, rev, test_file, args):
"""Tries to:
@@ -68,26 +61,27 @@ class HgFetchTest(MockPackagesTest):
"""
self.pkg.versions[ver('hg')] = args
- self.pkg.do_stage()
- self.assertEqual(self.repo.get_rev(), rev)
+ with self.pkg.stage:
+ self.pkg.do_stage()
+ self.assertEqual(self.repo.get_rev(), rev)
- file_path = join_path(self.pkg.stage.source_path, test_file)
- self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
- self.assertTrue(os.path.isfile(file_path))
+ file_path = join_path(self.pkg.stage.source_path, test_file)
+ self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
+ self.assertTrue(os.path.isfile(file_path))
- os.unlink(file_path)
- self.assertFalse(os.path.isfile(file_path))
+ os.unlink(file_path)
+ self.assertFalse(os.path.isfile(file_path))
- untracked = 'foobarbaz'
- touch(untracked)
- self.assertTrue(os.path.isfile(untracked))
- self.pkg.do_restage()
- self.assertFalse(os.path.isfile(untracked))
+ untracked = 'foobarbaz'
+ touch(untracked)
+ self.assertTrue(os.path.isfile(untracked))
+ self.pkg.do_restage()
+ self.assertFalse(os.path.isfile(untracked))
- self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
- self.assertTrue(os.path.isfile(file_path))
+ self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
+ self.assertTrue(os.path.isfile(file_path))
- self.assertEqual(self.repo.get_rev(), rev)
+ self.assertEqual(self.repo.get_rev(), rev)
def test_fetch_default(self):
diff --git a/lib/spack/spack/test/install.py b/lib/spack/spack/test/install.py
index 8863d13c42..8297893f01 100644
--- a/lib/spack/spack/test/install.py
+++ b/lib/spack/spack/test/install.py
@@ -22,18 +22,13 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-import os
-import unittest
import shutil
import tempfile
-from llnl.util.filesystem import *
-
import spack
-from spack.stage import Stage
-from spack.fetch_strategy import URLFetchStrategy, FetchStrategyComposite
+from llnl.util.filesystem import *
from spack.directory_layout import YamlDirectoryLayout
-from spack.util.executable import which
+from spack.fetch_strategy import URLFetchStrategy, FetchStrategyComposite
from spack.test.mock_packages_test import *
from spack.test.mock_repo import MockArchive
diff --git a/lib/spack/spack/test/link_tree.py b/lib/spack/spack/test/link_tree.py
index 886b7ef4c5..ee37e765c7 100644
--- a/lib/spack/spack/test/link_tree.py
+++ b/lib/spack/spack/test/link_tree.py
@@ -24,8 +24,6 @@
##############################################################################
import os
import unittest
-import shutil
-import tempfile
from llnl.util.filesystem import *
from llnl.util.link_tree import LinkTree
@@ -38,6 +36,7 @@ class LinkTreeTest(unittest.TestCase):
def setUp(self):
self.stage = Stage('link-tree-test')
+ self.stage.create()
with working_dir(self.stage.path):
touchp('source/1')
@@ -51,10 +50,8 @@ class LinkTreeTest(unittest.TestCase):
source_path = os.path.join(self.stage.path, 'source')
self.link_tree = LinkTree(source_path)
-
def tearDown(self):
- if self.stage:
- self.stage.destroy()
+ self.stage.destroy()
def check_file_link(self, filename):
diff --git a/lib/spack/spack/test/lock.py b/lib/spack/spack/test/lock.py
index bc68df01db..3b11d18da4 100644
--- a/lib/spack/spack/test/lock.py
+++ b/lib/spack/spack/test/lock.py
@@ -25,15 +25,13 @@
"""
These tests ensure that our lock works correctly.
"""
-import unittest
-import os
-import tempfile
import shutil
+import tempfile
+import unittest
from multiprocessing import Process
-from llnl.util.lock import *
from llnl.util.filesystem import join_path, touch
-
+from llnl.util.lock import *
from spack.util.multiproc import Barrier
# This is the longest a failed test will take, as the barriers will
diff --git a/lib/spack/spack/test/make_executable.py b/lib/spack/spack/test/make_executable.py
index d568a28d44..a2606acf19 100644
--- a/lib/spack/spack/test/make_executable.py
+++ b/lib/spack/spack/test/make_executable.py
@@ -28,13 +28,13 @@ Tests for Spack's built-in parallel make support.
This just tests whether the right args are getting passed to make.
"""
import os
-import unittest
-import tempfile
import shutil
+import tempfile
+import unittest
from llnl.util.filesystem import *
-from spack.util.environment import path_put_first
from spack.build_environment import MakeExecutable
+from spack.util.environment import path_put_first
class MakeExecutableTest(unittest.TestCase):
diff --git a/lib/spack/spack/test/mirror.py b/lib/spack/spack/test/mirror.py
index f83cc8090c..e707adfe9d 100644
--- a/lib/spack/spack/test/mirror.py
+++ b/lib/spack/spack/test/mirror.py
@@ -23,11 +23,10 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import os
-from filecmp import dircmp
-
import spack
import spack.mirror
-from spack.util.compression import decompressor_for
+
+from filecmp import dircmp
from spack.test.mock_packages_test import *
from spack.test.mock_repo import *
@@ -74,14 +73,14 @@ class MirrorTest(MockPackagesTest):
def check_mirror(self):
- stage = Stage('spack-mirror-test')
- mirror_root = join_path(stage.path, 'test-mirror')
+ with Stage('spack-mirror-test') as stage:
+ mirror_root = join_path(stage.path, 'test-mirror')
+
+ # register mirror with spack config
+ mirrors = { 'spack-mirror-test' : 'file://' + mirror_root }
+ spack.config.update_config('mirrors', mirrors)
- # register mirror with spack config
- mirrors = { 'spack-mirror-test' : 'file://' + mirror_root }
- spack.config.update_config('mirrors', mirrors)
- try:
os.chdir(stage.path)
spack.mirror.create(
mirror_root, self.repos, no_checksum=True)
@@ -97,38 +96,28 @@ class MirrorTest(MockPackagesTest):
files = os.listdir(subdir)
self.assertEqual(len(files), 1)
- # Now try to fetch each package.
- for name, mock_repo in self.repos.items():
- spec = Spec(name).concretized()
- pkg = spec.package
-
- pkg._stage = None
- saved_checksum_setting = spack.do_checksum
- try:
- # Stage the archive from the mirror and cd to it.
- spack.do_checksum = False
- pkg.do_stage(mirror_only=True)
-
- # Compare the original repo with the expanded archive
- original_path = mock_repo.path
- if 'svn' in name:
- # have to check out the svn repo to compare.
- original_path = join_path(mock_repo.path, 'checked_out')
- svn('checkout', mock_repo.url, original_path)
-
- dcmp = dircmp(original_path, pkg.stage.source_path)
-
- # make sure there are no new files in the expanded tarball
- self.assertFalse(dcmp.right_only)
-
- # and that all original files are present.
- self.assertTrue(all(l in exclude for l in dcmp.left_only))
-
- finally:
- spack.do_checksum = saved_checksum_setting
- pkg.do_clean()
- finally:
- stage.destroy()
+ # Now try to fetch each package.
+ for name, mock_repo in self.repos.items():
+ spec = Spec(name).concretized()
+ pkg = spec.package
+
+ saved_checksum_setting = spack.do_checksum
+ with pkg.stage:
+ # Stage the archive from the mirror and cd to it.
+ spack.do_checksum = False
+ pkg.do_stage(mirror_only=True)
+ # Compare the original repo with the expanded archive
+ original_path = mock_repo.path
+ if 'svn' in name:
+ # have to check out the svn repo to compare.
+ original_path = join_path(mock_repo.path, 'checked_out')
+ svn('checkout', mock_repo.url, original_path)
+ dcmp = dircmp(original_path, pkg.stage.source_path)
+ # make sure there are no new files in the expanded tarball
+ self.assertFalse(dcmp.right_only)
+ # and that all original files are present.
+ self.assertTrue(all(l in exclude for l in dcmp.left_only))
+ spack.do_checksum = saved_checksum_setting
def test_git_mirror(self):
diff --git a/lib/spack/spack/test/mock_packages_test.py b/lib/spack/spack/test/mock_packages_test.py
index e9f1f95df5..0b8867b61e 100644
--- a/lib/spack/spack/test/mock_packages_test.py
+++ b/lib/spack/spack/test/mock_packages_test.py
@@ -22,17 +22,15 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-import sys
import os
import shutil
-import unittest
import tempfile
-from ordereddict_backport import OrderedDict
-
-from llnl.util.filesystem import mkdirp
+import unittest
import spack
import spack.config
+from llnl.util.filesystem import mkdirp
+from ordereddict_backport import OrderedDict
from spack.repository import RepoPath
from spack.spec import Spec
diff --git a/lib/spack/spack/test/mock_repo.py b/lib/spack/spack/test/mock_repo.py
index ed94023b0e..a8bdfb5571 100644
--- a/lib/spack/spack/test/mock_repo.py
+++ b/lib/spack/spack/test/mock_repo.py
@@ -26,13 +26,9 @@ import os
import shutil
from llnl.util.filesystem import *
-
-import spack
-from spack.version import ver
from spack.stage import Stage
from spack.util.executable import which
-
#
# VCS Systems used by mock repo code.
#
diff --git a/lib/spack/spack/test/multimethod.py b/lib/spack/spack/test/multimethod.py
index 7bf4ff0a0a..2d4b8cd584 100644
--- a/lib/spack/spack/test/multimethod.py
+++ b/lib/spack/spack/test/multimethod.py
@@ -25,14 +25,11 @@
"""
Test for multi_method dispatch.
"""
-import unittest
import spack
from spack.multimethod import *
-from spack.version import *
-from spack.spec import Spec
-from spack.multimethod import when
from spack.test.mock_packages_test import *
+from spack.version import *
class MultiMethodTest(MockPackagesTest):
diff --git a/lib/spack/spack/test/namespace_trie.py b/lib/spack/spack/test/namespace_trie.py
index 647976df21..2023ba6d96 100644
--- a/lib/spack/spack/test/namespace_trie.py
+++ b/lib/spack/spack/test/namespace_trie.py
@@ -23,6 +23,7 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import unittest
+
from spack.util.naming import NamespaceTrie
diff --git a/lib/spack/spack/test/optional_deps.py b/lib/spack/spack/test/optional_deps.py
index ebd7281999..55f35ea4c9 100644
--- a/lib/spack/spack/test/optional_deps.py
+++ b/lib/spack/spack/test/optional_deps.py
@@ -22,10 +22,8 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-import unittest
-import spack
-from spack.spec import Spec, CompilerSpec
+from spack.spec import Spec
from spack.test.mock_packages_test import *
class ConcretizeTest(MockPackagesTest):
diff --git a/lib/spack/spack/test/packages.py b/lib/spack/spack/test/packages.py
index 83984dc5f6..f0b5e05f3b 100644
--- a/lib/spack/spack/test/packages.py
+++ b/lib/spack/spack/test/packages.py
@@ -22,14 +22,12 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-import unittest
-
-from llnl.util.filesystem import join_path
import spack
+from llnl.util.filesystem import join_path
from spack.repository import Repo
-from spack.util.naming import mod_to_class
from spack.test.mock_packages_test import *
+from spack.util.naming import mod_to_class
class PackagesTest(MockPackagesTest):
diff --git a/lib/spack/spack/test/python_version.py b/lib/spack/spack/test/python_version.py
index d74d3b9b7d..4294975304 100644
--- a/lib/spack/spack/test/python_version.py
+++ b/lib/spack/spack/test/python_version.py
@@ -28,12 +28,11 @@ This test ensures that all Spack files are Python version 2.6 or less.
Spack was originally 2.7, but enough systems in 2014 are still using
2.6 on their frontend nodes that we need 2.6 to get adopted.
"""
-import unittest
import os
import re
+import unittest
import llnl.util.tty as tty
-
import pyqver2
import spack
diff --git a/lib/spack/spack/test/spec_dag.py b/lib/spack/spack/test/spec_dag.py
index 632f777cde..5e6162b6e6 100644
--- a/lib/spack/spack/test/spec_dag.py
+++ b/lib/spack/spack/test/spec_dag.py
@@ -31,8 +31,6 @@ You can find the dummy packages here::
import spack
import spack.package
-from llnl.util.lang import list_modules
-
from spack.spec import Spec
from spack.test.mock_packages_test import *
diff --git a/lib/spack/spack/test/spec_semantics.py b/lib/spack/spack/test/spec_semantics.py
index 44a09cbd7f..8c33d1ff6e 100644
--- a/lib/spack/spack/test/spec_semantics.py
+++ b/lib/spack/spack/test/spec_semantics.py
@@ -22,7 +22,6 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-import unittest
from spack.spec import *
from spack.test.mock_packages_test import *
diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py
index 1daaa4be8f..6e08e30e13 100644
--- a/lib/spack/spack/test/spec_syntax.py
+++ b/lib/spack/spack/test/spec_syntax.py
@@ -23,9 +23,10 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import unittest
+
import spack.spec
-from spack.spec import *
from spack.parse import Token
+from spack.spec import *
# Sample output for a complex lexing.
complex_lex = [Token(ID, 'mvapich_foo'),
diff --git a/lib/spack/spack/test/stage.py b/lib/spack/spack/test/stage.py
index c1b2a2a573..dbcf89d864 100644
--- a/lib/spack/spack/test/stage.py
+++ b/lib/spack/spack/test/stage.py
@@ -25,15 +25,13 @@
"""\
Test that the Stage class works correctly.
"""
-import unittest
-import shutil
import os
-import getpass
+import shutil
+import unittest
from contextlib import *
-from llnl.util.filesystem import *
-
import spack
+from llnl.util.filesystem import *
from spack.stage import Stage
from spack.util.executable import which
@@ -192,116 +190,90 @@ class StageTest(unittest.TestCase):
def test_setup_and_destroy_name_with_tmp(self):
with use_tmp(True):
- stage = Stage(archive_url, name=stage_name)
- self.check_setup(stage, stage_name)
-
- stage.destroy()
+ with Stage(archive_url, name=stage_name) as stage:
+ self.check_setup(stage, stage_name)
self.check_destroy(stage, stage_name)
def test_setup_and_destroy_name_without_tmp(self):
with use_tmp(False):
- stage = Stage(archive_url, name=stage_name)
- self.check_setup(stage, stage_name)
-
- stage.destroy()
+ with Stage(archive_url, name=stage_name) as stage:
+ self.check_setup(stage, stage_name)
self.check_destroy(stage, stage_name)
def test_setup_and_destroy_no_name_with_tmp(self):
with use_tmp(True):
- stage = Stage(archive_url)
- self.check_setup(stage, None)
-
- stage.destroy()
+ with Stage(archive_url) as stage:
+ self.check_setup(stage, None)
self.check_destroy(stage, None)
def test_setup_and_destroy_no_name_without_tmp(self):
with use_tmp(False):
- stage = Stage(archive_url)
- self.check_setup(stage, None)
-
- stage.destroy()
+ with Stage(archive_url) as stage:
+ self.check_setup(stage, None)
self.check_destroy(stage, None)
def test_chdir(self):
- stage = Stage(archive_url, name=stage_name)
-
- stage.chdir()
- self.check_setup(stage, stage_name)
- self.check_chdir(stage, stage_name)
-
- stage.destroy()
+ with Stage(archive_url, name=stage_name) as stage:
+ stage.chdir()
+ self.check_setup(stage, stage_name)
+ self.check_chdir(stage, stage_name)
self.check_destroy(stage, stage_name)
def test_fetch(self):
- stage = Stage(archive_url, name=stage_name)
-
- stage.fetch()
- self.check_setup(stage, stage_name)
- self.check_chdir(stage, stage_name)
- self.check_fetch(stage, stage_name)
-
- stage.destroy()
+ with Stage(archive_url, name=stage_name) as stage:
+ stage.fetch()
+ self.check_setup(stage, stage_name)
+ self.check_chdir(stage, stage_name)
+ self.check_fetch(stage, stage_name)
self.check_destroy(stage, stage_name)
def test_expand_archive(self):
- stage = Stage(archive_url, name=stage_name)
-
- stage.fetch()
- self.check_setup(stage, stage_name)
- self.check_fetch(stage, stage_name)
-
- stage.expand_archive()
- self.check_expand_archive(stage, stage_name)
-
- stage.destroy()
+ with Stage(archive_url, name=stage_name) as stage:
+ stage.fetch()
+ self.check_setup(stage, stage_name)
+ self.check_fetch(stage, stage_name)
+ stage.expand_archive()
+ self.check_expand_archive(stage, stage_name)
self.check_destroy(stage, stage_name)
def test_expand_archive(self):
- stage = Stage(archive_url, name=stage_name)
-
- stage.fetch()
- self.check_setup(stage, stage_name)
- self.check_fetch(stage, stage_name)
-
- stage.expand_archive()
- stage.chdir_to_source()
- self.check_expand_archive(stage, stage_name)
- self.check_chdir_to_source(stage, stage_name)
-
- stage.destroy()
+ with Stage(archive_url, name=stage_name) as stage:
+ stage.fetch()
+ self.check_setup(stage, stage_name)
+ self.check_fetch(stage, stage_name)
+ stage.expand_archive()
+ stage.chdir_to_source()
+ self.check_expand_archive(stage, stage_name)
+ self.check_chdir_to_source(stage, stage_name)
self.check_destroy(stage, stage_name)
def test_restage(self):
- stage = Stage(archive_url, name=stage_name)
-
- stage.fetch()
- stage.expand_archive()
- stage.chdir_to_source()
- self.check_expand_archive(stage, stage_name)
- self.check_chdir_to_source(stage, stage_name)
-
- # Try to make a file in the old archive dir
- with open('foobar', 'w') as file:
- file.write("this file is to be destroyed.")
-
- self.assertTrue('foobar' in os.listdir(stage.source_path))
-
- # Make sure the file is not there after restage.
- stage.restage()
- self.check_chdir(stage, stage_name)
- self.check_fetch(stage, stage_name)
-
- stage.chdir_to_source()
- self.check_chdir_to_source(stage, stage_name)
- self.assertFalse('foobar' in os.listdir(stage.source_path))
-
- stage.destroy()
+ with Stage(archive_url, name=stage_name) as stage:
+ stage.fetch()
+ stage.expand_archive()
+ stage.chdir_to_source()
+ self.check_expand_archive(stage, stage_name)
+ self.check_chdir_to_source(stage, stage_name)
+
+ # Try to make a file in the old archive dir
+ with open('foobar', 'w') as file:
+ file.write("this file is to be destroyed.")
+
+ self.assertTrue('foobar' in os.listdir(stage.source_path))
+
+ # Make sure the file is not there after restage.
+ stage.restage()
+ self.check_chdir(stage, stage_name)
+ self.check_fetch(stage, stage_name)
+ stage.chdir_to_source()
+ self.check_chdir_to_source(stage, stage_name)
+ self.assertFalse('foobar' in os.listdir(stage.source_path))
self.check_destroy(stage, stage_name)
diff --git a/lib/spack/spack/test/svn_fetch.py b/lib/spack/spack/test/svn_fetch.py
index 454a7f1d1f..1ee4ee700e 100644
--- a/lib/spack/spack/test/svn_fetch.py
+++ b/lib/spack/spack/test/svn_fetch.py
@@ -24,18 +24,12 @@
##############################################################################
import os
import re
-import unittest
-import shutil
-import tempfile
-
-from llnl.util.filesystem import *
-
import spack
+
+from spack.test.mock_repo import svn, MockSvnRepo
from spack.version import ver
-from spack.stage import Stage
-from spack.util.executable import which
from spack.test.mock_packages_test import *
-from spack.test.mock_repo import svn, MockSvnRepo
+from llnl.util.filesystem import *
class SvnFetchTest(MockPackagesTest):
@@ -51,13 +45,10 @@ class SvnFetchTest(MockPackagesTest):
spec.concretize()
self.pkg = spack.repo.get(spec, new=True)
-
def tearDown(self):
"""Destroy the stage space used by this test."""
super(SvnFetchTest, self).tearDown()
self.repo.destroy()
- self.pkg.do_clean()
-
def assert_rev(self, rev):
"""Check that the current revision is equal to the supplied rev."""
@@ -70,7 +61,6 @@ class SvnFetchTest(MockPackagesTest):
return match.group(1)
self.assertEqual(get_rev(), rev)
-
def try_fetch(self, rev, test_file, args):
"""Tries to:
1. Fetch the repo using a fetch strategy constructed with
@@ -82,26 +72,27 @@ class SvnFetchTest(MockPackagesTest):
"""
self.pkg.versions[ver('svn')] = args
- self.pkg.do_stage()
- self.assert_rev(rev)
+ with self.pkg.stage:
+ self.pkg.do_stage()
+ self.assert_rev(rev)
- file_path = join_path(self.pkg.stage.source_path, test_file)
- self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
- self.assertTrue(os.path.isfile(file_path))
+ file_path = join_path(self.pkg.stage.source_path, test_file)
+ self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
+ self.assertTrue(os.path.isfile(file_path))
- os.unlink(file_path)
- self.assertFalse(os.path.isfile(file_path))
+ os.unlink(file_path)
+ self.assertFalse(os.path.isfile(file_path))
- untracked = 'foobarbaz'
- touch(untracked)
- self.assertTrue(os.path.isfile(untracked))
- self.pkg.do_restage()
- self.assertFalse(os.path.isfile(untracked))
+ untracked = 'foobarbaz'
+ touch(untracked)
+ self.assertTrue(os.path.isfile(untracked))
+ self.pkg.do_restage()
+ self.assertFalse(os.path.isfile(untracked))
- self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
- self.assertTrue(os.path.isfile(file_path))
+ self.assertTrue(os.path.isdir(self.pkg.stage.source_path))
+ self.assertTrue(os.path.isfile(file_path))
- self.assert_rev(rev)
+ self.assert_rev(rev)
def test_fetch_default(self):
diff --git a/lib/spack/spack/test/tally_plugin.py b/lib/spack/spack/test/tally_plugin.py
index e0b9618e0c..4163ab95dd 100644
--- a/lib/spack/spack/test/tally_plugin.py
+++ b/lib/spack/spack/test/tally_plugin.py
@@ -22,10 +22,10 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-from nose.plugins import Plugin
-
import os
+from nose.plugins import Plugin
+
class Tally(Plugin):
name = 'tally'
diff --git a/lib/spack/spack/test/unit_install.py b/lib/spack/spack/test/unit_install.py
index ccc409dd60..18615b7efe 100644
--- a/lib/spack/spack/test/unit_install.py
+++ b/lib/spack/spack/test/unit_install.py
@@ -22,10 +22,11 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-import unittest
import itertools
+import unittest
import spack
+
test_install = __import__("spack.cmd.test-install",
fromlist=["BuildId", "create_test_output", "TestResult"])
diff --git a/lib/spack/spack/test/url_extrapolate.py b/lib/spack/spack/test/url_extrapolate.py
index 87adf89401..068a335b49 100644
--- a/lib/spack/spack/test/url_extrapolate.py
+++ b/lib/spack/spack/test/url_extrapolate.py
@@ -25,10 +25,7 @@
"""\
Tests ability of spack to extrapolate URL versions from existing versions.
"""
-import spack
import spack.url as url
-from spack.spec import Spec
-from spack.version import ver
from spack.test.mock_packages_test import *
diff --git a/lib/spack/spack/test/url_parse.py b/lib/spack/spack/test/url_parse.py
index efde7c0c73..561d4658a1 100644
--- a/lib/spack/spack/test/url_parse.py
+++ b/lib/spack/spack/test/url_parse.py
@@ -27,8 +27,8 @@ This file has a bunch of versions tests taken from the excellent version
detection in Homebrew.
"""
import unittest
+
import spack.url as url
-from pprint import pprint
class UrlParseTest(unittest.TestCase):
diff --git a/lib/spack/spack/test/url_substitution.py b/lib/spack/spack/test/url_substitution.py
index aec8baf4ea..2be38af0d3 100644
--- a/lib/spack/spack/test/url_substitution.py
+++ b/lib/spack/spack/test/url_substitution.py
@@ -27,7 +27,6 @@ This test does sanity checks on substituting new versions into URLs
"""
import unittest
-import spack
import spack.url as url
diff --git a/lib/spack/spack/test/versions.py b/lib/spack/spack/test/versions.py
index 108450e098..2732006eb3 100644
--- a/lib/spack/spack/test/versions.py
+++ b/lib/spack/spack/test/versions.py
@@ -28,6 +28,7 @@ We try to maintain compatibility with RPM's version semantics
where it makes sense.
"""
import unittest
+
from spack.version import *
diff --git a/lib/spack/spack/test/yaml.py b/lib/spack/spack/test/yaml.py
index 5a357b8e69..b930c022f2 100644
--- a/lib/spack/spack/test/yaml.py
+++ b/lib/spack/spack/test/yaml.py
@@ -26,6 +26,7 @@
Test Spack's custom YAML format.
"""
import unittest
+
import spack.util.spack_yaml as syaml
test_file = """\
diff --git a/var/spack/repos/builtin/packages/jdk/package.py b/var/spack/repos/builtin/packages/jdk/package.py
index f8f5fc21bd..cbcc53ac0a 100644
--- a/var/spack/repos/builtin/packages/jdk/package.py
+++ b/var/spack/repos/builtin/packages/jdk/package.py
@@ -28,7 +28,7 @@ class Jdk(Package):
'-H', # specify required License Agreement cookie
'Cookie: oraclelicense=accept-securebackup-cookie']
- def do_fetch(self):
+ def do_fetch(self, mirror_only=False):
# Add our custom curl commandline options
tty.msg(
"[Jdk] Adding required commandline options to curl " +
@@ -39,7 +39,7 @@ class Jdk(Package):
spack.curl.add_default_arg(option)
# Now perform the actual fetch
- super(Jdk, self).do_fetch()
+ super(Jdk, self).do_fetch(mirror_only)
def install(self, spec, prefix):
diff --git a/var/spack/repos/builtin/packages/libevent/package.py b/var/spack/repos/builtin/packages/libevent/package.py
index 11b1083d67..714a155dc0 100644
--- a/var/spack/repos/builtin/packages/libevent/package.py
+++ b/var/spack/repos/builtin/packages/libevent/package.py
@@ -22,9 +22,16 @@ class Libevent(Package):
version('2.0.13', 'af786b4b3f790c9d3279792edf7867fc')
version('2.0.12', '42986228baf95e325778ed328a93e070')
+ variant('openssl', default=True, description="Build with encryption enabled at the libevent level.")
+ depends_on('openssl', when='+openssl')
def install(self, spec, prefix):
- configure("--prefix=%s" % prefix)
+ configure_args = []
+ if '+openssl' in spec:
+ configure_args.append('--enable-openssl')
+ else:
+ configure_args.append('--enable-openssl')
+ configure("--prefix=%s" % prefix, *configure_args)
make()
make("install")
diff --git a/var/spack/repos/builtin/packages/libsigsegv/package.py b/var/spack/repos/builtin/packages/libsigsegv/package.py
new file mode 100644
index 0000000000..4b486198ec
--- /dev/null
+++ b/var/spack/repos/builtin/packages/libsigsegv/package.py
@@ -0,0 +1,15 @@
+from spack import *
+
+class Libsigsegv(Package):
+ """GNU libsigsegv is a library for handling page faults in user mode."""
+ homepage = "https://www.gnu.org/software/libsigsegv/"
+ url = "ftp://ftp.gnu.org/gnu/libsigsegv/libsigsegv-2.10.tar.gz"
+
+ version('2.10', '7f96fb1f65b3b8cbc1582fb7be774f0f')
+
+ def install(self, spec, prefix):
+ configure('--prefix=%s' % prefix,
+ '--enable-shared')
+
+ make()
+ make("install")
diff --git a/var/spack/repos/builtin/packages/llvm/package.py b/var/spack/repos/builtin/packages/llvm/package.py
index 934d994bd3..280e400f69 100644
--- a/var/spack/repos/builtin/packages/llvm/package.py
+++ b/var/spack/repos/builtin/packages/llvm/package.py
@@ -1,5 +1,5 @@
##############################################################################
-# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
+# Copyright (c) 2016, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
@@ -34,7 +34,7 @@ class Llvm(Package):
it is the full name of the project.
"""
homepage = 'http://llvm.org/'
- url = 'http://llvm.org/releases/3.7.0/llvm-3.7.0.src.tar.xz'
+ url = 'http://llvm.org/releases/3.7.1/llvm-3.7.1.src.tar.xz'
version('3.0', 'a8e5f5f1c1adebae7b4a654c376a6005', url='http://llvm.org/releases/3.0/llvm-3.0.tar.gz') # currently required by mesa package
@@ -133,6 +133,21 @@ class Llvm(Package):
}
},
{
+ 'version' : '3.7.1',
+ 'md5':'bf8b3a2c79e61212c5409041dfdbd319',
+ 'resources' : {
+ 'compiler-rt' : '1c6975daf30bb3b0473b53c3a1a6ff01',
+ 'openmp' : 'b4ad08cda4e5c22e42b66062b140438e',
+ 'polly' : '3a2a7367002740881637f4d47bca4dc3',
+ 'libcxx' : 'f9c43fa552a10e14ff53b94d04bea140',
+ 'libcxxabi' : '52d925afac9f97e9dcac90745255c169',
+ 'clang' : '0acd026b5529164197563d135a8fd83e',
+ 'clang-tools-extra' : '5d49ff745037f061a7c86aeb6a24c3d2',
+ 'lldb' : 'a106d8a0d21fc84d76953822fbaf3398',
+ 'llvm-libunwind' : '814bd52c9247c5d04629658fbcb3ab8c',
+ }
+ },
+ {
'version' : '3.7.0',
'md5':'b98b9495e5655a672d6cb83e1a180f8e',
'resources' : {
diff --git a/var/spack/repos/builtin/packages/m4/package.py b/var/spack/repos/builtin/packages/m4/package.py
index 5d76d8866b..d6829dbcd4 100644
--- a/var/spack/repos/builtin/packages/m4/package.py
+++ b/var/spack/repos/builtin/packages/m4/package.py
@@ -7,7 +7,17 @@ class M4(Package):
version('1.4.17', 'a5e9954b1dae036762f7b13673a2cf76')
+ variant('sigsegv', default=True, description="Build the libsigsegv dependency")
+
+ depends_on('libsigsegv', when='+sigsegv')
+
def install(self, spec, prefix):
- configure("--prefix=%s" % prefix)
+ configure_args = []
+ if 'libsigsegv' in spec:
+ configure_args.append('--with-libsigsegv-prefix=%s' % spec['libsigsegv'].prefix)
+ else:
+ configure_args.append('--without-libsigsegv-prefix')
+
+ configure("--prefix=%s" % prefix, *configure_args)
make()
make("install")
diff --git a/var/spack/repos/builtin/packages/mpc/package.py b/var/spack/repos/builtin/packages/mpc/package.py
index 50477a0ccb..108fec678f 100644
--- a/var/spack/repos/builtin/packages/mpc/package.py
+++ b/var/spack/repos/builtin/packages/mpc/package.py
@@ -37,6 +37,12 @@ class Mpc(Package):
depends_on("gmp")
depends_on("mpfr")
+ def url_for_version(self, version):
+ if version < Version("1.0.1"):
+ return "http://www.multiprecision.org/mpc/download/mpc-%s.tar.gz" % version
+ else:
+ return "ftp://ftp.gnu.org/gnu/mpc/mpc-%s.tar.gz" % version
+
def install(self, spec, prefix):
configure("--prefix=%s" % prefix)
make()