From 89181f253b0d81f94a447815be80f88adb9578e0 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Wed, 12 Aug 2020 11:57:32 +0200 Subject: Improve warning message for deprecated attributes in "packages.yaml" The deprecatedProperties custom validator now can accept a function to compute a better error message. Improve error/warning message for deprecated properties --- lib/spack/spack/config.py | 3 --- lib/spack/spack/schema/__init__.py | 18 +++++++------- lib/spack/spack/schema/config.py | 6 ++--- lib/spack/spack/schema/modules.py | 11 ++++----- lib/spack/spack/schema/packages.py | 49 +++++++++++++++++++++++++++++++++++--- lib/spack/spack/test/schema.py | 8 ++++--- 6 files changed, 67 insertions(+), 28 deletions(-) diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py index 531100e772..84d8e8ca3f 100644 --- a/lib/spack/spack/config.py +++ b/lib/spack/spack/config.py @@ -598,9 +598,6 @@ class Configuration(object): changed = _update_in_memory(data, section) if changed: self.format_updates[section].append(scope) - msg = ('OUTDATED CONFIGURATION FILE ' - '[section={0}, scope={1}, dir={2}]') - tty.debug(msg.format(section, scope.name, scope.path)) merged_section = merge_yaml(merged_section, data) diff --git a/lib/spack/spack/schema/__init__.py b/lib/spack/spack/schema/__init__.py index 38cc36caef..8c485a4bfd 100644 --- a/lib/spack/spack/schema/__init__.py +++ b/lib/spack/spack/schema/__init__.py @@ -2,7 +2,6 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) - """This module contains jsonschema files for all of Spack's YAML formats.""" import copy @@ -86,19 +85,18 @@ def _make_validator(): return # Retrieve the template message - msg = deprecated['message'] + msg_str_or_func = deprecated['message'] + if isinstance(msg_str_or_func, six.string_types): + msg = msg_str_or_func.format(properties=deprecated_properties) + else: + msg = msg_str_or_func(instance, deprecated_properties) + is_error = deprecated['error'] if not is_error: - for entry in deprecated_properties: - llnl.util.tty.warn( - msg.format(property=entry, entry=instance[entry]) - ) + llnl.util.tty.warn(msg) else: import jsonschema - for entry in deprecated_properties: - yield jsonschema.ValidationError( - msg.format(property=entry, entry=instance[entry]) - ) + yield jsonschema.ValidationError(msg) return jsonschema.validators.extend( jsonschema.Draft4Validator, { diff --git a/lib/spack/spack/schema/config.py b/lib/spack/spack/schema/config.py index bc9575d94a..b1d3332a3f 100644 --- a/lib/spack/spack/schema/config.py +++ b/lib/spack/spack/schema/config.py @@ -63,9 +63,9 @@ properties = { }, 'deprecatedProperties': { 'properties': ['dotkit'], - 'message': 'specifying a "{property}" module root has no ' - 'effect [support for {property} module files' - ' has been dropped]', + 'message': 'specifying a "dotkit" module root has no ' + 'effect [support for "dotkit" has been ' + 'dropped in v0.13.0]', 'error': False }, }, diff --git a/lib/spack/spack/schema/modules.py b/lib/spack/spack/schema/modules.py index d03dbfb410..f44ba7d97d 100644 --- a/lib/spack/spack/schema/modules.py +++ b/lib/spack/spack/schema/modules.py @@ -135,9 +135,9 @@ properties = { }, 'deprecatedProperties': { 'properties': ['dotkit'], - 'message': 'cannot enable "{property}" in modules.yaml ' - '[support for {property} module files has been' - ' dropped]', + 'message': 'cannot enable "dotkit" in modules.yaml ' + '[support for "dotkit" has been dropped ' + 'in v0.13.0]', 'error': False }, }, @@ -172,9 +172,8 @@ properties = { }, 'deprecatedProperties': { 'properties': ['dotkit'], - 'message': 'the section "{property}" in modules.yaml has no effect' - ' [support for {property} module files has been ' - 'dropped]', + 'message': 'the "dotkit" section in modules.yaml has no effect' + ' [support for "dotkit" has been dropped in v0.13.0]', 'error': False }, }, diff --git a/lib/spack/spack/schema/packages.py b/lib/spack/spack/schema/packages.py index 2efe00991a..f2626c83be 100644 --- a/lib/spack/spack/schema/packages.py +++ b/lib/spack/spack/schema/packages.py @@ -9,6 +9,51 @@ """ +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 = instance_copy._end_mark.name + command_to_suggest = '$ spack config update packages' + if os.path.basename(absolute_path) == 'spack.yaml': + command_to_suggest = '$ spack env update ' + + # 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': { @@ -95,9 +140,7 @@ properties = { }, 'deprecatedProperties': { 'properties': ['modules', 'paths'], - 'message': 'the attribute "{property}" in the "packages" ' - 'section of the configuration has been ' - 'deprecated [entry={entry}]', + 'message': deprecate_paths_and_modules, 'error': False } }, diff --git a/lib/spack/spack/test/schema.py b/lib/spack/spack/test/schema.py index a6e9986a01..14c9014d61 100644 --- a/lib/spack/spack/test/schema.py +++ b/lib/spack/spack/test/schema.py @@ -118,21 +118,23 @@ def test_schema_validation(meta_schema, config_name): def test_deprecated_properties(module_suffixes_schema): # Test that an error is reported when 'error: True' + msg_fmt = r'deprecated properties detected [properties={properties}]' module_suffixes_schema['deprecatedProperties'] = { 'properties': ['tcl'], - 'message': '{property} not allowed', + 'message': msg_fmt, 'error': True } v = spack.schema.Validator(module_suffixes_schema) data = {'tcl': {'all': {'suffixes': {'^python': 'py'}}}} - with pytest.raises(jsonschema.ValidationError, match='tcl not allowed'): + expected_match = 'deprecated properties detected' + with pytest.raises(jsonschema.ValidationError, match=expected_match): v.validate(data) # Test that just a warning is reported when 'error: False' module_suffixes_schema['deprecatedProperties'] = { 'properties': ['tcl'], - 'message': '{property} not allowed', + 'message': msg_fmt, 'error': False } v = spack.schema.Validator(module_suffixes_schema) -- cgit v1.2.3-60-g2f50