Make ProviderIndex yaml-izable.

- allow a provider index to be stored and re-read.
This commit is contained in:
Todd Gamblin 2016-05-27 21:20:40 -05:00
parent 025609c63f
commit bf028990e7
4 changed files with 138 additions and 13 deletions

View File

@ -51,6 +51,7 @@
# These names describe how repos should be laid out in the filesystem.
#
repo_config_name = 'repo.yaml' # Top-level filename for repo config.
repo_index_name = 'index.yaml' # Top-level filename for repository index.
packages_dir_name = 'packages' # Top-level repo directory containing pkgs.
package_file_name = 'package.py' # Filename for packages in a repository.

View File

@ -33,15 +33,49 @@
"""Names of tests to be included in Spack's test suite"""
test_names = [
'architecture', 'versions', 'url_parse', 'url_substitution', 'packages',
'stage', 'spec_syntax', 'spec_semantics', 'spec_dag', 'concretize',
'multimethod', 'install', 'package_sanity', 'config', 'directory_layout',
'pattern', 'python_version', 'git_fetch', 'svn_fetch', 'hg_fetch',
'mirror', 'modules', 'url_extrapolate', 'cc', 'link_tree', 'spec_yaml',
'optional_deps', 'make_executable', 'build_system_guess', 'lock',
'database', 'namespace_trie', 'yaml', 'sbang', 'environment',
'concretize_preferences', 'cmd.find', 'cmd.uninstall', 'cmd.test_install',
'cmd.test_compiler_cmd', 'cmd.module'
'architecture',
'build_system_guess',
'cc',
'cmd.find',
'cmd.module',
'cmd.test_compiler_cmd',
'cmd.test_install',
'cmd.uninstall',
'concretize',
'concretize_preferences',
'config',
'configure_guess',
'database',
'directory_layout',
'environment',
'git_fetch',
'hg_fetch',
'install',
'link_tree',
'lock',
'make_executable',
'mirror',
'modules',
'multimethod',
'namespace_trie',
'optional_deps',
'package_sanity',
'packages',
'pattern',
'python_version',
'sbang',
'spec_dag',
'spec_semantics',
'spec_syntax',
'spec_yaml',
'stage',
'svn_fetch',
'url_extrapolate',
'url_parse',
'url_substitution',
'versions',
'virtual',
'yaml',
]

View File

@ -0,0 +1,43 @@
##############################################################################
# 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 StringIO import StringIO
import unittest
import spack
from spack.virtual import ProviderIndex
class VirtualTest(unittest.TestCase):
def test_write_and_read(self):
p = ProviderIndex(spack.repo.all_package_names())
ostream = StringIO ()
p.to_yaml(ostream)
istream = StringIO(ostream.getvalue())
q = ProviderIndex.from_yaml(istream)
self.assertTrue(p == q)

View File

@ -25,8 +25,12 @@
"""
The ``virtual`` module contains utility classes for virtual dependencies.
"""
import spack.spec
import itertools
import yaml
from yaml.error import MarkedYAMLError
import spack
class ProviderIndex(object):
"""This is a dict of dicts used for finding providers of particular
@ -45,10 +49,11 @@ class ProviderIndex(object):
Calling providers_for(spec) will find specs that provide a
matching implementation of MPI.
"""
def __init__(self, specs, **kwargs):
def __init__(self, specs=None, **kwargs):
# TODO: come up with another name for this. This "restricts" values to
# the verbatim impu specs (i.e., it doesn't pre-apply package's constraints, and
# keeps things as broad as possible, so it's really the wrong name)
if specs is None: specs = []
self.restrict = kwargs.setdefault('restrict', False)
self.providers = {}
@ -64,7 +69,7 @@ def __init__(self, specs, **kwargs):
def update(self, spec):
if type(spec) != spack.spec.Spec:
if not isinstance(spec, spack.spec.Spec):
spec = spack.spec.Spec(spec)
if not spec.name:
@ -75,7 +80,8 @@ def update(self, spec):
pkg = spec.package
for provided_spec, provider_spec in pkg.provided.iteritems():
provider_spec.compiler_flags = spec.compiler_flags.copy()#We want satisfaction other than flags
# We want satisfaction other than flags
provider_spec.compiler_flags = spec.compiler_flags.copy()
if provider_spec.satisfies(spec, deps=False):
provided_name = provided_spec.name
@ -164,3 +170,44 @@ def satisfies(self, other):
result[name] = crossed
return all(c in result for c in common)
def to_yaml(self, stream=None):
provider_list = dict(
(name, [[vpkg.to_node_dict(), [p.to_node_dict() for p in pset]]
for vpkg, pset in pdict.items()])
for name, pdict in self.providers.items())
yaml.dump({'provider_index': {'providers': provider_list}},
stream=stream)
@staticmethod
def from_yaml(stream):
try:
yfile = yaml.load(stream)
except MarkedYAMLError, e:
raise spack.spec.SpackYAMLError(
"error parsing YAML ProviderIndex cache:", str(e))
if not isinstance(yfile, dict):
raise spack.spec.SpackYAMLError(
"YAML ProviderIndex was not a dict.")
if not 'provider_index' in yfile:
raise spack.spec.SpackYAMLError(
"YAML ProviderIndex does not start with 'provider_index'")
index = ProviderIndex()
providers = yfile['provider_index']['providers']
index.providers = dict(
(name, dict((spack.spec.Spec.from_node_dict(vpkg),
set(spack.spec.Spec.from_node_dict(p) for p in plist))
for vpkg, plist in pdict_list))
for name, pdict_list in providers.items())
return index
def __eq__(self, other):
return self.providers == other.providers