Source code for spack.schema.packages

# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""Schema for packages.yaml configuration files.

.. literalinclude:: _spack_root/lib/spack/spack/schema/
   :lines: 13-

[docs]def deprecate_paths_and_modules(instance, deprecated_properties): """Function to produce warning/error messages if "paths" and "modules" are found in "packages.yaml" Args: instance: instance of the configuration file deprecated_properties: deprecated properties in instance Returns: Warning/Error message to be printed """ import copy import os.path import llnl.util.tty import spack.util.spack_yaml as syaml # Copy the instance to remove default attributes that are not related # to the part that needs to be reported instance_copy = copy.copy(instance) # Check if this configuration comes from an environment or not absolute_path = command_to_suggest = '$ spack config update packages' if os.path.basename(absolute_path) == 'spack.yaml': command_to_suggest = '$ spack env update <environment>' # Retrieve the relevant part of the configuration as YAML keys_to_be_removed = [ x for x in instance_copy if x not in deprecated_properties ] for key in keys_to_be_removed: instance_copy.pop(key) yaml_as_str = syaml.dump_config(instance_copy, blame=True) if llnl.util.tty.is_debug(): msg = 'OUTDATED CONFIGURATION FILE [file={0}]\n{1}' llnl.util.tty.debug(msg.format(absolute_path, yaml_as_str)) msg = ('detected deprecated properties in {0}\nActivate the debug ' 'flag to have more information on the deprecated parts or ' 'run:\n\n\t{2}\n\nto update the file to the new format\n') return msg.format( absolute_path, yaml_as_str, command_to_suggest )
#: Properties for inclusion in other schemas properties = { 'packages': { 'type': 'object', 'default': {}, 'additionalProperties': False, 'patternProperties': { r'\w[\w-]*': { # package name 'type': 'object', 'default': {}, 'additionalProperties': False, 'properties': { 'version': { 'type': 'array', 'default': [], # version strings 'items': {'anyOf': [{'type': 'string'}, {'type': 'number'}]}}, 'target': { 'type': 'array', 'default': [], # target names 'items': {'type': 'string'}, }, 'compiler': { 'type': 'array', 'default': [], 'items': {'type': 'string'}}, # compiler specs 'buildable': { 'type': 'boolean', 'default': True, }, 'permissions': { 'type': 'object', 'additionalProperties': False, 'properties': { 'read': { 'type': 'string', 'enum': ['user', 'group', 'world'], }, 'write': { 'type': 'string', 'enum': ['user', 'group', 'world'], }, 'group': { 'type': 'string', }, }, }, 'providers': { 'type': 'object', 'default': {}, 'additionalProperties': False, 'patternProperties': { r'\w[\w-]*': { 'type': 'array', 'default': [], 'items': {'type': 'string'}, }, }, }, 'variants': { 'oneOf': [ {'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}], }, 'externals': { 'type': 'array', 'items': { 'type': 'object', 'properties': { 'spec': {'type': 'string'}, 'prefix': {'type': 'string'}, 'modules': {'type': 'array', 'items': {'type': 'string'}}, 'extra_attributes': {'type': 'object'} }, 'additionalProperties': True, 'required': ['spec'] } }, # Deprecated properties, will trigger an error with a # message telling how to update. 'paths': {'type': 'object'}, 'modules': {'type': 'object'}, }, 'deprecatedProperties': { 'properties': ['modules', 'paths'], 'message': deprecate_paths_and_modules, 'error': False } }, }, }, } #: Full schema with metadata schema = { '$schema': '', 'title': 'Spack package configuration file schema', 'type': 'object', 'additionalProperties': False, 'properties': properties, }
[docs]def update(data): """Update the data in place to remove deprecated properties. Args: data (dict): dictionary to be updated Returns: True if data was changed, False otherwise """ changed = False for cfg_object in data.values(): externals = [] # If we don't have these deprecated attributes, continue if not any(x in cfg_object for x in ('paths', 'modules')): continue # If we arrive here we need to make some changes i.e. # we need to remove and eventually convert some attributes changed = True paths = cfg_object.pop('paths', {}) for spec, prefix in paths.items(): externals.append({ 'spec': str(spec), 'prefix': str(prefix) }) modules = cfg_object.pop('modules', {}) for spec, module in modules.items(): externals.append({ 'spec': str(spec), 'modules': [str(module)] }) if externals: cfg_object['externals'] = externals return changed