Fixes #469: Store package.py files in the .spack directory.
- Adds packages in spack repos inside the .spack directory, so that packages can be rebuilt automatically later.
This commit is contained in:
parent
21d125c914
commit
52081c46d6
@ -58,6 +58,7 @@
|
|||||||
import spack.mirror
|
import spack.mirror
|
||||||
import spack.hooks
|
import spack.hooks
|
||||||
import spack.directives
|
import spack.directives
|
||||||
|
import spack.repository
|
||||||
import spack.build_environment
|
import spack.build_environment
|
||||||
import spack.url
|
import spack.url
|
||||||
import spack.util.web
|
import spack.util.web
|
||||||
@ -502,6 +503,7 @@ def fetcher(self):
|
|||||||
self._fetcher = self._make_fetcher()
|
self._fetcher = self._make_fetcher()
|
||||||
return self._fetcher
|
return self._fetcher
|
||||||
|
|
||||||
|
|
||||||
@fetcher.setter
|
@fetcher.setter
|
||||||
def fetcher(self, f):
|
def fetcher(self, f):
|
||||||
self._fetcher = f
|
self._fetcher = f
|
||||||
@ -905,6 +907,9 @@ def real_work():
|
|||||||
install(log_path, log_install_path)
|
install(log_path, log_install_path)
|
||||||
install(env_path, env_install_path)
|
install(env_path, env_install_path)
|
||||||
|
|
||||||
|
packages_dir = spack.install_layout.build_packages_path(self.spec)
|
||||||
|
dump_packages(self.spec, packages_dir)
|
||||||
|
|
||||||
# On successful install, remove the stage.
|
# On successful install, remove the stage.
|
||||||
if not keep_stage:
|
if not keep_stage:
|
||||||
self.stage.destroy()
|
self.stage.destroy()
|
||||||
@ -1219,6 +1224,52 @@ def validate_package_url(url_string):
|
|||||||
tty.die("Invalid file type in URL: '%s'" % url_string)
|
tty.die("Invalid file type in URL: '%s'" % url_string)
|
||||||
|
|
||||||
|
|
||||||
|
def dump_packages(spec, path):
|
||||||
|
"""Dump all package information for a spec and its dependencies.
|
||||||
|
|
||||||
|
This creates a package repository within path for every
|
||||||
|
namespace in the spec DAG, and fills the repos wtih package
|
||||||
|
files and patch files for every node in the DAG.
|
||||||
|
"""
|
||||||
|
mkdirp(path)
|
||||||
|
|
||||||
|
# Copy in package.py files from any dependencies.
|
||||||
|
# Note that we copy them in as they are in the *install* directory
|
||||||
|
# NOT as they are in the repository, because we want a snapshot of
|
||||||
|
# how *this* particular build was done.
|
||||||
|
for node in spec.traverse():
|
||||||
|
if node is not spec:
|
||||||
|
# Locate the dependency package in the install tree and find
|
||||||
|
# its provenance information.
|
||||||
|
source = spack.install_layout.build_packages_path(node)
|
||||||
|
source_repo_root = join_path(source, node.namespace)
|
||||||
|
|
||||||
|
# There's no provenance installed for the source package. Skip it.
|
||||||
|
# User can always get something current from the builtin repo.
|
||||||
|
if not os.path.isdir(source_repo_root):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Create a source repo and get the pkg directory out of it.
|
||||||
|
try:
|
||||||
|
source_repo = spack.repository.Repo(source_repo_root)
|
||||||
|
source_pkg_dir = source_repo.dirname_for_package_name(node.name)
|
||||||
|
except RepoError as e:
|
||||||
|
tty.warn("Warning: Couldn't copy in provenance for %s" % node.name)
|
||||||
|
|
||||||
|
# Create a destination repository
|
||||||
|
dest_repo_root = join_path(path, node.namespace)
|
||||||
|
if not os.path.exists(dest_repo_root):
|
||||||
|
spack.repository.create_repo(dest_repo_root)
|
||||||
|
repo = spack.repository.Repo(dest_repo_root)
|
||||||
|
|
||||||
|
# Get the location of the package in the dest repo.
|
||||||
|
dest_pkg_dir = repo.dirname_for_package_name(node.name)
|
||||||
|
if node is not spec:
|
||||||
|
install_tree(source_pkg_dir, dest_pkg_dir)
|
||||||
|
else:
|
||||||
|
spack.repo.dump_provenance(node, dest_pkg_dir)
|
||||||
|
|
||||||
|
|
||||||
def print_pkg(message):
|
def print_pkg(message):
|
||||||
"""Outputs a message with a package icon."""
|
"""Outputs a message with a package icon."""
|
||||||
from llnl.util.tty.color import cwrite
|
from llnl.util.tty.color import cwrite
|
||||||
|
@ -316,6 +316,16 @@ def get(self, spec, new=False):
|
|||||||
return self.repo_for_pkg(spec).get(spec)
|
return self.repo_for_pkg(spec).get(spec)
|
||||||
|
|
||||||
|
|
||||||
|
@_autospec
|
||||||
|
def dump_provenance(self, spec, path):
|
||||||
|
"""Dump provenance information for a spec to a particular path.
|
||||||
|
|
||||||
|
This dumps the package file and any associated patch files.
|
||||||
|
Raises UnknownPackageError if not found.
|
||||||
|
"""
|
||||||
|
return self.repo_for_pkg(spec).dump_provenance(spec, path)
|
||||||
|
|
||||||
|
|
||||||
def dirname_for_package_name(self, pkg_name):
|
def dirname_for_package_name(self, pkg_name):
|
||||||
return self.repo_for_pkg(pkg_name).dirname_for_package_name(pkg_name)
|
return self.repo_for_pkg(pkg_name).dirname_for_package_name(pkg_name)
|
||||||
|
|
||||||
@ -552,6 +562,35 @@ def get(self, spec, new=False):
|
|||||||
return self._instances[key]
|
return self._instances[key]
|
||||||
|
|
||||||
|
|
||||||
|
@_autospec
|
||||||
|
def dump_provenance(self, spec, path):
|
||||||
|
"""Dump provenance information for a spec to a particular path.
|
||||||
|
|
||||||
|
This dumps the package file and any associated patch files.
|
||||||
|
Raises UnknownPackageError if not found.
|
||||||
|
"""
|
||||||
|
# Some preliminary checks.
|
||||||
|
if spec.virtual:
|
||||||
|
raise UnknownPackageError(spec.name)
|
||||||
|
|
||||||
|
if spec.namespace and spec.namespace != self.namespace:
|
||||||
|
raise UnknownPackageError("Repository %s does not contain package %s."
|
||||||
|
% (self.namespace, spec.fullname))
|
||||||
|
|
||||||
|
# Install any patch files needed by packages.
|
||||||
|
mkdirp(path)
|
||||||
|
for spec, patches in spec.package.patches.items():
|
||||||
|
for patch in patches:
|
||||||
|
if patch.path:
|
||||||
|
if os.path.exists(patch.path):
|
||||||
|
install(patch.path, path)
|
||||||
|
else:
|
||||||
|
tty.warn("Patch file did not exist: %s" % patch.path)
|
||||||
|
|
||||||
|
# Install the package.py file itself.
|
||||||
|
install(self.filename_for_package_name(spec), path)
|
||||||
|
|
||||||
|
|
||||||
def purge(self):
|
def purge(self):
|
||||||
"""Clear entire package instance cache."""
|
"""Clear entire package instance cache."""
|
||||||
self._instances.clear()
|
self._instances.clear()
|
||||||
|
Loading…
Reference in New Issue
Block a user