schemas: rework schemas so that they can be included from other files
- Each schema now has a top-level `properties` and `schema` attribute. - The `properties` is a fragment that can be included in other jsonschemas, via Python, not via '$ref' - Th `schema` is a complete `jsonschema` with `title` and `$schema` properties.
This commit is contained in:
parent
83323f4e71
commit
c19000038b
@ -51,7 +51,12 @@
|
|||||||
|
|
||||||
import spack.paths
|
import spack.paths
|
||||||
import spack.architecture
|
import spack.architecture
|
||||||
import spack.schema
|
import spack.schema.compilers
|
||||||
|
import spack.schema.mirrors
|
||||||
|
import spack.schema.repos
|
||||||
|
import spack.schema.packages
|
||||||
|
import spack.schema.modules
|
||||||
|
import spack.schema.config
|
||||||
from spack.error import SpackError
|
from spack.error import SpackError
|
||||||
|
|
||||||
# Hacked yaml for configuration files preserves line numbers.
|
# Hacked yaml for configuration files preserves line numbers.
|
||||||
@ -175,7 +180,7 @@ def write_section(self, section):
|
|||||||
try:
|
try:
|
||||||
mkdirp(self.path)
|
mkdirp(self.path)
|
||||||
with open(filename, 'w') as f:
|
with open(filename, 'w') as f:
|
||||||
_validate_section(data, section_schemas[section])
|
_validate(data, section_schemas[section])
|
||||||
syaml.dump(data, stream=f, default_flow_style=False)
|
syaml.dump(data, stream=f, default_flow_style=False)
|
||||||
except (yaml.YAMLError, IOError) as e:
|
except (yaml.YAMLError, IOError) as e:
|
||||||
raise ConfigFileError(
|
raise ConfigFileError(
|
||||||
@ -216,7 +221,7 @@ def __init__(self, name, data=None):
|
|||||||
if data:
|
if data:
|
||||||
for section in data:
|
for section in data:
|
||||||
dsec = data[section]
|
dsec = data[section]
|
||||||
_validate_section({section: dsec}, section_schemas[section])
|
_validate({section: dsec}, section_schemas[section])
|
||||||
self.sections[section] = _mark_internal(
|
self.sections[section] = _mark_internal(
|
||||||
syaml.syaml_dict({section: dsec}), name)
|
syaml.syaml_dict({section: dsec}), name)
|
||||||
|
|
||||||
@ -234,7 +239,7 @@ def write_section(self, section):
|
|||||||
"""This only validates, as the data is already in memory."""
|
"""This only validates, as the data is already in memory."""
|
||||||
data = self.get_section(section)
|
data = self.get_section(section)
|
||||||
if data is not None:
|
if data is not None:
|
||||||
_validate_section(data, section_schemas[section])
|
_validate(data, section_schemas[section])
|
||||||
self.sections[section] = _mark_internal(data, self.name)
|
self.sections[section] = _mark_internal(data, self.name)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -585,7 +590,7 @@ def _validate_section_name(section):
|
|||||||
% (section, " ".join(section_schemas.keys())))
|
% (section, " ".join(section_schemas.keys())))
|
||||||
|
|
||||||
|
|
||||||
def _validate_section(data, schema):
|
def _validate(data, schema):
|
||||||
"""Validate data read in from a Spack YAML file.
|
"""Validate data read in from a Spack YAML file.
|
||||||
|
|
||||||
This leverages the line information (start_mark, end_mark) stored
|
This leverages the line information (start_mark, end_mark) stored
|
||||||
@ -593,13 +598,13 @@ def _validate_section(data, schema):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
import jsonschema
|
import jsonschema
|
||||||
if not hasattr(_validate_section, 'validator'):
|
if not hasattr(_validate, 'validator'):
|
||||||
default_setting_validator = _extend_with_default(
|
default_setting_validator = _extend_with_default(
|
||||||
jsonschema.Draft4Validator)
|
jsonschema.Draft4Validator)
|
||||||
_validate_section.validator = default_setting_validator
|
_validate.validator = default_setting_validator
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_validate_section.validator(schema).validate(data)
|
_validate.validator(schema).validate(data)
|
||||||
except jsonschema.ValidationError as e:
|
except jsonschema.ValidationError as e:
|
||||||
raise ConfigFormatError(e, data)
|
raise ConfigFormatError(e, data)
|
||||||
|
|
||||||
@ -623,7 +628,7 @@ def _read_config_file(filename, schema):
|
|||||||
data = _mark_overrides(syaml.load(f))
|
data = _mark_overrides(syaml.load(f))
|
||||||
|
|
||||||
if data:
|
if data:
|
||||||
_validate_section(data, schema)
|
_validate(data, schema)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
except MarkedYAMLError as e:
|
except MarkedYAMLError as e:
|
||||||
|
@ -85,7 +85,6 @@ def deactivate():
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def root(name):
|
def root(name):
|
||||||
"""Get the root directory for an environment by name."""
|
"""Get the root directory for an environment by name."""
|
||||||
return fs.join_path(env_path, name)
|
return fs.join_path(env_path, name)
|
||||||
|
@ -3,12 +3,4 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
"""This module contains jsonschema files for all of Spack's YAML formats.
|
"""This module contains jsonschema files for all of Spack's YAML formats."""
|
||||||
"""
|
|
||||||
from llnl.util.lang import list_modules
|
|
||||||
|
|
||||||
# Automatically bring in all sub-modules
|
|
||||||
__all__ = []
|
|
||||||
for mod in list_modules(__path__[0]):
|
|
||||||
__import__('%s.%s' % (__name__, mod))
|
|
||||||
__all__.append(mod)
|
|
||||||
|
@ -10,114 +10,119 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
#: Properties for inclusion in other schemas
|
||||||
|
properties = {
|
||||||
|
'compilers': {
|
||||||
|
'type': 'array',
|
||||||
|
'items': [{
|
||||||
|
'type': 'object',
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': {
|
||||||
|
'compiler': {
|
||||||
|
'type': 'object',
|
||||||
|
'additionalProperties': False,
|
||||||
|
'required': [
|
||||||
|
'paths', 'spec', 'modules', 'operating_system'],
|
||||||
|
'properties': {
|
||||||
|
'paths': {
|
||||||
|
'type': 'object',
|
||||||
|
'required': ['cc', 'cxx', 'f77', 'fc'],
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': {
|
||||||
|
'cc': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]},
|
||||||
|
'cxx': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]},
|
||||||
|
'f77': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]},
|
||||||
|
'fc': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]}}},
|
||||||
|
'flags': {
|
||||||
|
'type': 'object',
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': {
|
||||||
|
'cflags': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]},
|
||||||
|
'cxxflags': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]},
|
||||||
|
'fflags': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]},
|
||||||
|
'cppflags': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]},
|
||||||
|
'ldflags': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]},
|
||||||
|
'ldlibs': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]}}},
|
||||||
|
'spec': {'type': 'string'},
|
||||||
|
'operating_system': {'type': 'string'},
|
||||||
|
'target': {'type': 'string'},
|
||||||
|
'alias': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'}]},
|
||||||
|
'modules': {'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'null'},
|
||||||
|
{'type': 'array'}]},
|
||||||
|
'environment': {
|
||||||
|
'type': 'object',
|
||||||
|
'default': {},
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': {
|
||||||
|
'set': {
|
||||||
|
'type': 'object',
|
||||||
|
'patternProperties': {
|
||||||
|
# Variable name
|
||||||
|
r'\w[\w-]*': {
|
||||||
|
'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'number'}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'unset': {
|
||||||
|
'type': 'object',
|
||||||
|
'patternProperties': {
|
||||||
|
# Variable name
|
||||||
|
r'\w[\w-]*': {'type': 'null'}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'prepend-path': {
|
||||||
|
'type': 'object',
|
||||||
|
'patternProperties': {
|
||||||
|
# Variable name
|
||||||
|
r'\w[\w-]*': {
|
||||||
|
'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'number'}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'append-path': {
|
||||||
|
'type': 'object',
|
||||||
|
'patternProperties': {
|
||||||
|
# Variable name
|
||||||
|
r'\w[\w-]*': {
|
||||||
|
'anyOf': [{'type': 'string'},
|
||||||
|
{'type': 'number'}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'extra_rpaths': {
|
||||||
|
'type': 'array',
|
||||||
|
'default': [],
|
||||||
|
'items': {'type': 'string'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#: Full schema with metadata
|
||||||
schema = {
|
schema = {
|
||||||
'$schema': 'http://json-schema.org/schema#',
|
'$schema': 'http://json-schema.org/schema#',
|
||||||
'title': 'Spack compiler configuration file schema',
|
'title': 'Spack compiler configuration file schema',
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
'properties': {
|
'properties': properties,
|
||||||
'compilers': {
|
|
||||||
'type': 'array',
|
|
||||||
'items': {
|
|
||||||
'type': 'object',
|
|
||||||
'additionalProperties': False,
|
|
||||||
'properties': {
|
|
||||||
'compiler': {
|
|
||||||
'type': 'object',
|
|
||||||
'additionalProperties': False,
|
|
||||||
'required': [
|
|
||||||
'paths', 'spec', 'modules', 'operating_system'],
|
|
||||||
'properties': {
|
|
||||||
'paths': {
|
|
||||||
'type': 'object',
|
|
||||||
'required': ['cc', 'cxx', 'f77', 'fc'],
|
|
||||||
'additionalProperties': False,
|
|
||||||
'properties': {
|
|
||||||
'cc': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]},
|
|
||||||
'cxx': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]},
|
|
||||||
'f77': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]},
|
|
||||||
'fc': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]}}},
|
|
||||||
'flags': {
|
|
||||||
'type': 'object',
|
|
||||||
'additionalProperties': False,
|
|
||||||
'properties': {
|
|
||||||
'cflags': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]},
|
|
||||||
'cxxflags': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]},
|
|
||||||
'fflags': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]},
|
|
||||||
'cppflags': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]},
|
|
||||||
'ldflags': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]},
|
|
||||||
'ldlibs': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]}}},
|
|
||||||
'spec': {'type': 'string'},
|
|
||||||
'operating_system': {'type': 'string'},
|
|
||||||
'target': {'type': 'string'},
|
|
||||||
'alias': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'}]},
|
|
||||||
'modules': {'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'null'},
|
|
||||||
{'type': 'array'}]},
|
|
||||||
'environment': {
|
|
||||||
'type': 'object',
|
|
||||||
'default': {},
|
|
||||||
'additionalProperties': False,
|
|
||||||
'properties': {
|
|
||||||
'set': {
|
|
||||||
'type': 'object',
|
|
||||||
'patternProperties': {
|
|
||||||
# Variable name
|
|
||||||
r'\w[\w-]*': {
|
|
||||||
'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'number'}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'unset': {
|
|
||||||
'type': 'object',
|
|
||||||
'patternProperties': {
|
|
||||||
# Variable name
|
|
||||||
r'\w[\w-]*': {'type': 'null'}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'prepend-path': {
|
|
||||||
'type': 'object',
|
|
||||||
'patternProperties': {
|
|
||||||
# Variable name
|
|
||||||
r'\w[\w-]*': {
|
|
||||||
'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'number'}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'append-path': {
|
|
||||||
'type': 'object',
|
|
||||||
'patternProperties': {
|
|
||||||
# Variable name
|
|
||||||
r'\w[\w-]*': {
|
|
||||||
'anyOf': [{'type': 'string'},
|
|
||||||
{'type': 'number'}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'extra_rpaths': {
|
|
||||||
'type': 'array',
|
|
||||||
'default': [],
|
|
||||||
'items': {'type': 'string'}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,56 +10,61 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
#: Properties for inclusion in other schemas
|
||||||
|
properties = {
|
||||||
|
'config': {
|
||||||
|
'type': 'object',
|
||||||
|
'default': {},
|
||||||
|
'properties': {
|
||||||
|
'install_tree': {'type': 'string'},
|
||||||
|
'install_hash_length': {'type': 'integer', 'minimum': 1},
|
||||||
|
'install_path_scheme': {'type': 'string'},
|
||||||
|
'build_stage': {
|
||||||
|
'oneOf': [
|
||||||
|
{'type': 'string'},
|
||||||
|
{'type': 'array',
|
||||||
|
'items': {'type': 'string'}}],
|
||||||
|
},
|
||||||
|
'template_dirs': {
|
||||||
|
'type': 'array',
|
||||||
|
'items': {'type': 'string'}
|
||||||
|
},
|
||||||
|
'module_roots': {
|
||||||
|
'type': 'object',
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': {
|
||||||
|
'tcl': {'type': 'string'},
|
||||||
|
'lmod': {'type': 'string'},
|
||||||
|
'dotkit': {'type': 'string'},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'source_cache': {'type': 'string'},
|
||||||
|
'misc_cache': {'type': 'string'},
|
||||||
|
'verify_ssl': {'type': 'boolean'},
|
||||||
|
'debug': {'type': 'boolean'},
|
||||||
|
'checksum': {'type': 'boolean'},
|
||||||
|
'locks': {'type': 'boolean'},
|
||||||
|
'dirty': {'type': 'boolean'},
|
||||||
|
'build_language': {'type': 'string'},
|
||||||
|
'build_jobs': {'type': 'integer', 'minimum': 1},
|
||||||
|
'ccache': {'type': 'boolean'},
|
||||||
|
'db_lock_timeout': {'type': 'integer', 'minimum': 1},
|
||||||
|
'package_lock_timeout': {
|
||||||
|
'anyOf': [
|
||||||
|
{'type': 'integer', 'minimum': 1},
|
||||||
|
{'type': 'null'}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#: Full schema with metadata
|
||||||
schema = {
|
schema = {
|
||||||
'$schema': 'http://json-schema.org/schema#',
|
'$schema': 'http://json-schema.org/schema#',
|
||||||
'title': 'Spack core configuration file schema',
|
'title': 'Spack core configuration file schema',
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
'patternProperties': {
|
'properties': properties,
|
||||||
'config': {
|
|
||||||
'type': 'object',
|
|
||||||
'default': {},
|
|
||||||
'properties': {
|
|
||||||
'install_tree': {'type': 'string'},
|
|
||||||
'install_hash_length': {'type': 'integer', 'minimum': 1},
|
|
||||||
'install_path_scheme': {'type': 'string'},
|
|
||||||
'build_stage': {
|
|
||||||
'oneOf': [
|
|
||||||
{'type': 'string'},
|
|
||||||
{'type': 'array',
|
|
||||||
'items': {'type': 'string'}}],
|
|
||||||
},
|
|
||||||
'template_dirs': {
|
|
||||||
'type': 'array',
|
|
||||||
'items': {'type': 'string'}
|
|
||||||
},
|
|
||||||
'module_roots': {
|
|
||||||
'type': 'object',
|
|
||||||
'additionalProperties': False,
|
|
||||||
'properties': {
|
|
||||||
'tcl': {'type': 'string'},
|
|
||||||
'lmod': {'type': 'string'},
|
|
||||||
'dotkit': {'type': 'string'},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'source_cache': {'type': 'string'},
|
|
||||||
'misc_cache': {'type': 'string'},
|
|
||||||
'verify_ssl': {'type': 'boolean'},
|
|
||||||
'debug': {'type': 'boolean'},
|
|
||||||
'checksum': {'type': 'boolean'},
|
|
||||||
'locks': {'type': 'boolean'},
|
|
||||||
'dirty': {'type': 'boolean'},
|
|
||||||
'build_language': {'type': 'string'},
|
|
||||||
'build_jobs': {'type': 'integer', 'minimum': 1},
|
|
||||||
'ccache': {'type': 'boolean'},
|
|
||||||
'db_lock_timeout': {'type': 'integer', 'minimum': 1},
|
|
||||||
'package_lock_timeout': {
|
|
||||||
'anyOf': [
|
|
||||||
{'type': 'integer', 'minimum': 1},
|
|
||||||
{'type': 'null'}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
@ -12,19 +12,22 @@
|
|||||||
|
|
||||||
schema = {
|
schema = {
|
||||||
'$schema': 'http://json-schema.org/schema#',
|
'$schema': 'http://json-schema.org/schema#',
|
||||||
'title': 'Spack Environments user configuration file schema',
|
'title': 'Spack environment file schema',
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
'properties': {
|
'patternProperties': {
|
||||||
'env': {
|
'^env|spack$': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'default': {},
|
'default': {},
|
||||||
'properties': {
|
'properties': {
|
||||||
'configs': {
|
'include': {
|
||||||
'type': 'array',
|
'type': 'array',
|
||||||
'default': [],
|
'items': {
|
||||||
'items': {'type': 'string'}
|
'type': 'string'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
'specs': {
|
'specs': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'default': {},
|
'default': {},
|
||||||
|
@ -10,20 +10,24 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
#: Properties for inclusion in other schemas
|
||||||
|
properties = {
|
||||||
|
'mirrors': {
|
||||||
|
'type': 'object',
|
||||||
|
'default': {},
|
||||||
|
'additionalProperties': False,
|
||||||
|
'patternProperties': {
|
||||||
|
r'\w[\w-]*': {'type': 'string'},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#: Full schema with metadata
|
||||||
schema = {
|
schema = {
|
||||||
'$schema': 'http://json-schema.org/schema#',
|
'$schema': 'http://json-schema.org/schema#',
|
||||||
'title': 'Spack mirror configuration file schema',
|
'title': 'Spack mirror configuration file schema',
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
'patternProperties': {
|
'properties': properties,
|
||||||
r'mirrors': {
|
|
||||||
'type': 'object',
|
|
||||||
'default': {},
|
|
||||||
'additionalProperties': False,
|
|
||||||
'patternProperties': {
|
|
||||||
r'\w[\w-]*': {
|
|
||||||
'type': 'string'},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
@ -10,158 +10,170 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
schema = {
|
#: Definitions for parts of module schema
|
||||||
'$schema': 'http://json-schema.org/schema#',
|
definitions = {
|
||||||
'title': 'Spack module file configuration file schema',
|
'array_of_strings': {
|
||||||
'type': 'object',
|
'type': 'array',
|
||||||
'additionalProperties': False,
|
'default': [],
|
||||||
'definitions': {
|
'items': {
|
||||||
'array_of_strings': {
|
'type': 'string'
|
||||||
'type': 'array',
|
|
||||||
'default': [],
|
|
||||||
'items': {
|
|
||||||
'type': 'string'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'dictionary_of_strings': {
|
|
||||||
'type': 'object',
|
|
||||||
'patternProperties': {
|
|
||||||
r'\w[\w-]*': { # key
|
|
||||||
'type': 'string'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'dependency_selection': {
|
|
||||||
'type': 'string',
|
|
||||||
'enum': ['none', 'direct', 'all']
|
|
||||||
},
|
|
||||||
'module_file_configuration': {
|
|
||||||
'type': 'object',
|
|
||||||
'default': {},
|
|
||||||
'additionalProperties': False,
|
|
||||||
'properties': {
|
|
||||||
'filter': {
|
|
||||||
'type': 'object',
|
|
||||||
'default': {},
|
|
||||||
'additionalProperties': False,
|
|
||||||
'properties': {
|
|
||||||
'environment_blacklist': {
|
|
||||||
'type': 'array',
|
|
||||||
'default': [],
|
|
||||||
'items': {
|
|
||||||
'type': 'string'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'template': {
|
|
||||||
'type': 'string'
|
|
||||||
},
|
|
||||||
'autoload': {
|
|
||||||
'$ref': '#/definitions/dependency_selection'},
|
|
||||||
'prerequisites': {
|
|
||||||
'$ref': '#/definitions/dependency_selection'},
|
|
||||||
'conflict': {
|
|
||||||
'$ref': '#/definitions/array_of_strings'},
|
|
||||||
'load': {
|
|
||||||
'$ref': '#/definitions/array_of_strings'},
|
|
||||||
'suffixes': {
|
|
||||||
'$ref': '#/definitions/dictionary_of_strings'},
|
|
||||||
'environment': {
|
|
||||||
'type': 'object',
|
|
||||||
'default': {},
|
|
||||||
'additionalProperties': False,
|
|
||||||
'properties': {
|
|
||||||
'set': {
|
|
||||||
'$ref': '#/definitions/dictionary_of_strings'},
|
|
||||||
'unset': {
|
|
||||||
'$ref': '#/definitions/array_of_strings'},
|
|
||||||
'prepend_path': {
|
|
||||||
'$ref': '#/definitions/dictionary_of_strings'},
|
|
||||||
'append_path': {
|
|
||||||
'$ref': '#/definitions/dictionary_of_strings'}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'module_type_configuration': {
|
|
||||||
'type': 'object',
|
|
||||||
'default': {},
|
|
||||||
'anyOf': [
|
|
||||||
{'properties': {
|
|
||||||
'verbose': {
|
|
||||||
'type': 'boolean',
|
|
||||||
'default': False
|
|
||||||
},
|
|
||||||
'hash_length': {
|
|
||||||
'type': 'integer',
|
|
||||||
'minimum': 0,
|
|
||||||
'default': 7
|
|
||||||
},
|
|
||||||
'whitelist': {
|
|
||||||
'$ref': '#/definitions/array_of_strings'},
|
|
||||||
'blacklist': {
|
|
||||||
'$ref': '#/definitions/array_of_strings'},
|
|
||||||
'blacklist_implicits': {
|
|
||||||
'type': 'boolean',
|
|
||||||
'default': False
|
|
||||||
},
|
|
||||||
'naming_scheme': {
|
|
||||||
'type': 'string' # Can we be more specific here?
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
{'patternProperties': {
|
|
||||||
r'\w[\w-]*': {
|
|
||||||
'$ref': '#/definitions/module_file_configuration'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'patternProperties': {
|
'dictionary_of_strings': {
|
||||||
r'modules': {
|
'type': 'object',
|
||||||
'type': 'object',
|
'patternProperties': {
|
||||||
'default': {},
|
r'\w[\w-]*': { # key
|
||||||
'additionalProperties': False,
|
'type': 'string'
|
||||||
'properties': {
|
|
||||||
'prefix_inspections': {
|
|
||||||
'type': 'object',
|
|
||||||
'patternProperties': {
|
|
||||||
# prefix-relative path to be inspected for existence
|
|
||||||
r'\w[\w-]*': {
|
|
||||||
'$ref': '#/definitions/array_of_strings'}}},
|
|
||||||
'enable': {
|
|
||||||
'type': 'array',
|
|
||||||
'default': [],
|
|
||||||
'items': {
|
|
||||||
'type': 'string',
|
|
||||||
'enum': ['tcl', 'dotkit', 'lmod']}},
|
|
||||||
'lmod': {
|
|
||||||
'allOf': [
|
|
||||||
# Base configuration
|
|
||||||
{'$ref': '#/definitions/module_type_configuration'},
|
|
||||||
{
|
|
||||||
'core_compilers': {
|
|
||||||
'$ref': '#/definitions/array_of_strings'
|
|
||||||
},
|
|
||||||
'hierarchical_scheme': {
|
|
||||||
'$ref': '#/definitions/array_of_strings'
|
|
||||||
}
|
|
||||||
} # Specific lmod extensions
|
|
||||||
]},
|
|
||||||
'tcl': {
|
|
||||||
'allOf': [
|
|
||||||
# Base configuration
|
|
||||||
{'$ref': '#/definitions/module_type_configuration'},
|
|
||||||
{} # Specific tcl extensions
|
|
||||||
]},
|
|
||||||
'dotkit': {
|
|
||||||
'allOf': [
|
|
||||||
# Base configuration
|
|
||||||
{'$ref': '#/definitions/module_type_configuration'},
|
|
||||||
{} # Specific dotkit extensions
|
|
||||||
]},
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'dependency_selection': {
|
||||||
|
'type': 'string',
|
||||||
|
'enum': ['none', 'direct', 'all']
|
||||||
|
},
|
||||||
|
'module_file_configuration': {
|
||||||
|
'type': 'object',
|
||||||
|
'default': {},
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': {
|
||||||
|
'filter': {
|
||||||
|
'type': 'object',
|
||||||
|
'default': {},
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': {
|
||||||
|
'environment_blacklist': {
|
||||||
|
'type': 'array',
|
||||||
|
'default': [],
|
||||||
|
'items': {
|
||||||
|
'type': 'string'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'template': {
|
||||||
|
'type': 'string'
|
||||||
|
},
|
||||||
|
'autoload': {
|
||||||
|
'$ref': '#/definitions/dependency_selection'},
|
||||||
|
'prerequisites': {
|
||||||
|
'$ref': '#/definitions/dependency_selection'},
|
||||||
|
'conflict': {
|
||||||
|
'$ref': '#/definitions/array_of_strings'},
|
||||||
|
'load': {
|
||||||
|
'$ref': '#/definitions/array_of_strings'},
|
||||||
|
'suffixes': {
|
||||||
|
'$ref': '#/definitions/dictionary_of_strings'},
|
||||||
|
'environment': {
|
||||||
|
'type': 'object',
|
||||||
|
'default': {},
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': {
|
||||||
|
'set': {
|
||||||
|
'$ref': '#/definitions/dictionary_of_strings'},
|
||||||
|
'unset': {
|
||||||
|
'$ref': '#/definitions/array_of_strings'},
|
||||||
|
'prepend_path': {
|
||||||
|
'$ref': '#/definitions/dictionary_of_strings'},
|
||||||
|
'append_path': {
|
||||||
|
'$ref': '#/definitions/dictionary_of_strings'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'module_type_configuration': {
|
||||||
|
'type': 'object',
|
||||||
|
'default': {},
|
||||||
|
'anyOf': [
|
||||||
|
{'properties': {
|
||||||
|
'verbose': {
|
||||||
|
'type': 'boolean',
|
||||||
|
'default': False
|
||||||
|
},
|
||||||
|
'hash_length': {
|
||||||
|
'type': 'integer',
|
||||||
|
'minimum': 0,
|
||||||
|
'default': 7
|
||||||
|
},
|
||||||
|
'whitelist': {
|
||||||
|
'$ref': '#/definitions/array_of_strings'},
|
||||||
|
'blacklist': {
|
||||||
|
'$ref': '#/definitions/array_of_strings'},
|
||||||
|
'blacklist_implicits': {
|
||||||
|
'type': 'boolean',
|
||||||
|
'default': False
|
||||||
|
},
|
||||||
|
'naming_scheme': {
|
||||||
|
'type': 'string' # Can we be more specific here?
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{'patternProperties': {
|
||||||
|
r'\w[\w-]*': {
|
||||||
|
'$ref': '#/definitions/module_file_configuration'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Properties for inclusion into other schemas (requires definitions)
|
||||||
|
properties = {
|
||||||
|
'modules': {
|
||||||
|
'type': 'object',
|
||||||
|
'default': {},
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': {
|
||||||
|
'prefix_inspections': {
|
||||||
|
'type': 'object',
|
||||||
|
'patternProperties': {
|
||||||
|
# prefix-relative path to be inspected for existence
|
||||||
|
r'\w[\w-]*': {
|
||||||
|
'$ref': '#/definitions/array_of_strings'}}},
|
||||||
|
'enable': {
|
||||||
|
'type': 'array',
|
||||||
|
'default': [],
|
||||||
|
'items': {
|
||||||
|
'type': 'string',
|
||||||
|
'enum': ['tcl', 'dotkit', 'lmod']}},
|
||||||
|
'lmod': {
|
||||||
|
'allOf': [
|
||||||
|
# Base configuration
|
||||||
|
{'$ref': '#/definitions/module_type_configuration'},
|
||||||
|
{
|
||||||
|
'core_compilers': {
|
||||||
|
'$ref': '#/definitions/array_of_strings'
|
||||||
|
},
|
||||||
|
'hierarchical_scheme': {
|
||||||
|
'$ref': '#/definitions/array_of_strings'
|
||||||
|
}
|
||||||
|
} # Specific lmod extensions
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'tcl': {
|
||||||
|
'allOf': [
|
||||||
|
# Base configuration
|
||||||
|
{'$ref': '#/definitions/module_type_configuration'},
|
||||||
|
{} # Specific tcl extensions
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'dotkit': {
|
||||||
|
'allOf': [
|
||||||
|
# Base configuration
|
||||||
|
{'$ref': '#/definitions/module_type_configuration'},
|
||||||
|
{} # Specific dotkit extensions
|
||||||
|
]
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#: Full schema with metadata
|
||||||
|
schema = {
|
||||||
|
'$schema': 'http://json-schema.org/schema#',
|
||||||
|
'title': 'Spack module file configuration file schema',
|
||||||
|
'definitions': definitions,
|
||||||
|
'type': 'object',
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': properties,
|
||||||
|
}
|
||||||
|
@ -10,79 +10,84 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
schema = {
|
#: Properties for inclusion in other schemas
|
||||||
'$schema': 'http://json-schema.org/schema#',
|
properties = {
|
||||||
'title': 'Spack package configuration file schema',
|
'packages': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'additionalProperties': False,
|
'default': {},
|
||||||
'patternProperties': {
|
'additionalProperties': False,
|
||||||
r'packages': {
|
'patternProperties': {
|
||||||
'type': 'object',
|
r'\w[\w-]*': { # package name
|
||||||
'default': {},
|
'type': 'object',
|
||||||
'additionalProperties': False,
|
'default': {},
|
||||||
'patternProperties': {
|
'additionalProperties': False,
|
||||||
r'\w[\w-]*': { # package name
|
'properties': {
|
||||||
'type': 'object',
|
'version': {
|
||||||
'default': {},
|
'type': 'array',
|
||||||
'additionalProperties': False,
|
'default': [],
|
||||||
'properties': {
|
# version strings
|
||||||
'version': {
|
'items': {'anyOf': [{'type': 'string'},
|
||||||
'type': 'array',
|
{'type': 'number'}]}},
|
||||||
'default': [],
|
'compiler': {
|
||||||
# version strings
|
'type': 'array',
|
||||||
'items': {'anyOf': [{'type': 'string'},
|
'default': [],
|
||||||
{'type': 'number'}]}},
|
'items': {'type': 'string'}}, # compiler specs
|
||||||
'compiler': {
|
'buildable': {
|
||||||
'type': 'array',
|
'type': 'boolean',
|
||||||
'default': [],
|
'default': True,
|
||||||
'items': {'type': 'string'}}, # compiler specs
|
},
|
||||||
'buildable': {
|
'permissions': {
|
||||||
'type': 'boolean',
|
'type': 'object',
|
||||||
'default': True,
|
'additionalProperties': False,
|
||||||
},
|
'properties': {
|
||||||
'permissions': {
|
'read': {
|
||||||
'type': 'object',
|
'type': 'string',
|
||||||
'additionalProperties': False,
|
'enum': ['user', 'group', 'world'],
|
||||||
'properties': {
|
},
|
||||||
'read': {
|
'write': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'enum': ['user', 'group', 'world'],
|
'enum': ['user', 'group', 'world'],
|
||||||
},
|
},
|
||||||
'write': {
|
'group': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'enum': ['user', 'group', 'world'],
|
|
||||||
},
|
|
||||||
'group': {
|
|
||||||
'type': 'string',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'modules': {
|
},
|
||||||
'type': 'object',
|
'modules': {
|
||||||
'default': {},
|
'type': 'object',
|
||||||
},
|
'default': {},
|
||||||
'providers': {
|
},
|
||||||
'type': 'object',
|
'providers': {
|
||||||
'default': {},
|
'type': 'object',
|
||||||
'additionalProperties': False,
|
'default': {},
|
||||||
'patternProperties': {
|
'additionalProperties': False,
|
||||||
r'\w[\w-]*': {
|
'patternProperties': {
|
||||||
'type': 'array',
|
r'\w[\w-]*': {
|
||||||
'default': [],
|
'type': 'array',
|
||||||
'items': {'type': 'string'}, }, }, },
|
'default': [],
|
||||||
'paths': {
|
'items': {'type': 'string'}, }, }, },
|
||||||
'type': 'object',
|
'paths': {
|
||||||
'default': {},
|
'type': 'object',
|
||||||
},
|
'default': {},
|
||||||
'variants': {
|
},
|
||||||
'oneOf': [
|
'variants': {
|
||||||
{'type': 'string'},
|
'oneOf': [
|
||||||
{'type': 'array',
|
{'type': 'string'},
|
||||||
'items': {'type': 'string'}}],
|
{'type': 'array',
|
||||||
},
|
'items': {'type': 'string'}}],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#: Full schema with metadata
|
||||||
|
schema = {
|
||||||
|
'$schema': 'http://json-schema.org/schema#',
|
||||||
|
'title': 'Spack package configuration file schema',
|
||||||
|
'type': 'object',
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': properties,
|
||||||
|
}
|
||||||
|
@ -10,17 +10,21 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
#: Properties for inclusion in other schemas
|
||||||
|
properties = {
|
||||||
|
'repos': {
|
||||||
|
'type': 'array',
|
||||||
|
'default': [],
|
||||||
|
'items': {'type': 'string'},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#: Full schema with metadata
|
||||||
schema = {
|
schema = {
|
||||||
'$schema': 'http://json-schema.org/schema#',
|
'$schema': 'http://json-schema.org/schema#',
|
||||||
'title': 'Spack repository configuration file schema',
|
'title': 'Spack repository configuration file schema',
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
'patternProperties': {
|
'properties': properties,
|
||||||
r'repos': {
|
|
||||||
'type': 'array',
|
|
||||||
'default': [],
|
|
||||||
'items': {
|
|
||||||
'type': 'string'},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
import collections
|
import collections
|
||||||
import getpass
|
import getpass
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from six import StringIO
|
||||||
|
|
||||||
from llnl.util.filesystem import touch, mkdirp
|
from llnl.util.filesystem import touch, mkdirp
|
||||||
|
|
||||||
@ -15,6 +16,12 @@
|
|||||||
|
|
||||||
import spack.paths
|
import spack.paths
|
||||||
import spack.config
|
import spack.config
|
||||||
|
import spack.schema.compilers
|
||||||
|
import spack.schema.config
|
||||||
|
import spack.schema.packages
|
||||||
|
import spack.schema.mirrors
|
||||||
|
import spack.schema.repos
|
||||||
|
import spack.util.spack_yaml as syaml
|
||||||
from spack.util.path import canonicalize_path
|
from spack.util.path import canonicalize_path
|
||||||
|
|
||||||
|
|
||||||
@ -631,7 +638,7 @@ def test_add_command_line_scopes(tmpdir, mutable_config):
|
|||||||
spack.config._add_command_line_scopes(mutable_config, [str(tmpdir)])
|
spack.config._add_command_line_scopes(mutable_config, [str(tmpdir)])
|
||||||
|
|
||||||
|
|
||||||
def test_immuntable_scope(tmpdir):
|
def test_immutable_scope(tmpdir):
|
||||||
config_yaml = str(tmpdir.join('config.yaml'))
|
config_yaml = str(tmpdir.join('config.yaml'))
|
||||||
with open(config_yaml, 'w') as f:
|
with open(config_yaml, 'w') as f:
|
||||||
f.write("""\
|
f.write("""\
|
||||||
@ -645,3 +652,58 @@ def test_immuntable_scope(tmpdir):
|
|||||||
|
|
||||||
with pytest.raises(spack.config.ConfigError):
|
with pytest.raises(spack.config.ConfigError):
|
||||||
scope.write_section('config')
|
scope.write_section('config')
|
||||||
|
|
||||||
|
|
||||||
|
def check_schema(name, file_contents):
|
||||||
|
"""Check a Spack YAML schema against some data"""
|
||||||
|
f = StringIO(file_contents)
|
||||||
|
data = syaml.load(f)
|
||||||
|
spack.config._validate(data, name)
|
||||||
|
|
||||||
|
|
||||||
|
def test_bad_config_yaml(tmpdir):
|
||||||
|
with pytest.raises(spack.config.ConfigFormatError):
|
||||||
|
check_schema(spack.schema.config.schema, """\
|
||||||
|
config:
|
||||||
|
verify_ssl: False
|
||||||
|
module_roots:
|
||||||
|
fmod: /some/fake/location
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
def test_bad_mirrors_yaml(tmpdir):
|
||||||
|
with pytest.raises(spack.config.ConfigFormatError):
|
||||||
|
check_schema(spack.schema.mirrors.schema, """\
|
||||||
|
mirrors:
|
||||||
|
local: True
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
def test_bad_repos_yaml(tmpdir):
|
||||||
|
with pytest.raises(spack.config.ConfigFormatError):
|
||||||
|
check_schema(spack.schema.repos.schema, """\
|
||||||
|
repos:
|
||||||
|
True
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
def test_bad_compilers_yaml(tmpdir):
|
||||||
|
with pytest.raises(spack.config.ConfigFormatError):
|
||||||
|
check_schema(spack.schema.compilers.schema, """\
|
||||||
|
compilers:
|
||||||
|
key_instead_of_list: 'value'
|
||||||
|
""")
|
||||||
|
|
||||||
|
with pytest.raises(spack.config.ConfigFormatError):
|
||||||
|
check_schema(spack.schema.compilers.schema, """\
|
||||||
|
compilers:
|
||||||
|
- shmompiler:
|
||||||
|
environment: /bad/value
|
||||||
|
""")
|
||||||
|
|
||||||
|
with pytest.raises(spack.config.ConfigFormatError):
|
||||||
|
check_schema(spack.schema.compilers.schema, """\
|
||||||
|
compilers:
|
||||||
|
- compiler:
|
||||||
|
fenfironfent: /bad/value
|
||||||
|
""")
|
||||||
|
Loading…
Reference in New Issue
Block a user