Source code for wiz.validator

# :coding: utf-8

import re

import six
from packaging.version import VERSION_PATTERN

import wiz.exception

_REGEXP_VERSION = re.compile(
    "^{}$".format(VERSION_PATTERN), re.VERBOSE | re.IGNORECASE
)


[docs]def validate_definition(data): """Validate *data* mapping used to create a definition. An error will be raised if the *data* mapping cannot be used to create an instance of :class:`wiz.definition.Definition`.. :param data: Mapping to validate. :raise: :exc:`wiz.exception.IncorrectDefinition` if the *data* mapping is incorrect. """ keywords = { "identifier", "version", "namespace", "description", "auto-use", "disabled", "install-root", "install-location", "system", "command", "environ", "requirements", "conditions", "variants" } try: validate_type(data, dict) validate_keywords(data, keywords) validate_identifier_keyword(data) validate_version_keyword(data) validate_namespace_keyword(data) validate_description_keyword(data) validate_auto_use_keyword(data) validate_disabled_keyword(data) validate_install_root_keyword(data) validate_install_location_keyword(data) validate_system_keyword(data) validate_command_keyword(data) validate_environ_keyword(data) validate_requirements_keyword(data) validate_conditions_keyword(data) validate_variants_keyword(data) except ValueError as error: raise wiz.exception.DefinitionError(str(error))
[docs]def validate_identifier_keyword(data, variant_index=None): """Validate 'identifier' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "identifier": "foo" } :param data: Mapping to validate. :param variant_index: Index number of the variant mapping if applicable. Default is None. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("identifier") name = "'identifier'" if variant_index is not None: name = "'variants/{}/identifier'".format(variant_index) validate_required(data, label=name) validate_type(data, six.string_types, label=name)
[docs]def validate_version_keyword(data): """Validate 'version' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "version": "0.1.0" } :param data: Mapping to validate. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("version") validate_type(data, six.string_types, label="'version'") if data is not None: match = _REGEXP_VERSION.match(data) if not match: raise ValueError("Invalid version: '{}'".format(data))
[docs]def validate_namespace_keyword(data): """Validate 'namespace' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "namespace": "foo" } :param data: Mapping to validate. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("namespace") validate_type(data, six.string_types, label="'namespace'")
[docs]def validate_description_keyword(data): """Validate 'description' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "description": "This is a description" } :param data: Mapping to validate. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("description") validate_type(data, six.string_types, label="'description'")
[docs]def validate_auto_use_keyword(data): """Validate 'auto-use' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "auto-use": true } :param data: Mapping to validate. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("auto-use") validate_type(data, bool, label="'auto-use'")
[docs]def validate_disabled_keyword(data): """Validate 'disabled' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "disabled": true } :param data: Mapping to validate. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("disabled") validate_type(data, bool, label="'disabled'")
[docs]def validate_install_root_keyword(data): """Validate 'install-root' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "install-root": "/path/to/install/root" } :param data: Mapping to validate. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("install-root") validate_type(data, six.string_types, label="'install-root'")
[docs]def validate_install_location_keyword(data, variant_index=None): """Validate 'install-location' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "install-location": "/path/to/install/location" } :param data: Mapping to validate. :param variant_index: Index number of the variant mapping if applicable. Default is None. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("install-location") name = "'install-location'" if variant_index is not None: name = "'variants/{}/install-location'".format(variant_index) validate_type(data, six.string_types, label=name)
[docs]def validate_system_keyword(data): """Validate 'system' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "system": { "platform": "linux" } } :param data: Mapping to validate. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ _data = data.get("system") validate_type(_data, dict, label="'system'") validate_not_empty(_data, label="'system'") _data = data.get("system", {}) validate_keywords(_data, {"platform", "os", "arch"}, label="'system'") _data = data.get("system", {}).get("platform") validate_type(_data, six.string_types, label="'system/platform'") _data = data.get("system", {}).get("os") validate_type(_data, six.string_types, label="'system/os'") _data = data.get("system", {}).get("arch") validate_type(_data, six.string_types, label="'system/arch'")
[docs]def validate_command_keyword(data, variant_index=None): """Validate 'command' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "command": { "foo": "FooExe" } } :param data: Mapping to validate. :param variant_index: Index number of the variant mapping if applicable. Default is None. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("command") name = "'command'" if variant_index is not None: name = "'variants/{}/command'".format(variant_index) validate_type(data, dict, label=name) validate_not_empty(data, label=name)
[docs]def validate_environ_keyword(data, variant_index=None): """Validate 'environ' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "environ": { "KEY": "VALUE" } } :param data: Mapping to validate. :param variant_index: Index number of the variant mapping if applicable. Default is None. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("environ") name = "'environ'" if variant_index is not None: name = "'variants/{}/environ'".format(variant_index) validate_type(data, dict, label=name) validate_not_empty(data, label=name)
[docs]def validate_requirements_keyword(data, variant_index=None): """Validate 'requirements' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "requirements": [ "foo == 1.0.0", "bar >= 1, < 2" ] } :param data: Mapping to validate. :param variant_index: Index number of the variant mapping if applicable. Default is None. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("requirements") name = "'requirements'" if variant_index is not None: name = "'variants/{}/requirements'".format(variant_index) validate_type(data, list, label=name) validate_not_empty(data, label=name)
[docs]def validate_conditions_keyword(data): """Validate 'conditions' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "conditions": [ "bim >= 3.0.0" ] } :param data: Mapping to validate. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("conditions") validate_type(data, list, label="'conditions'") validate_not_empty(data, label="'conditions'")
[docs]def validate_variants_keyword(data): """Validate 'variants' keyword within *data* mapping. A correct *data* mapping should be in the form of:: { "variants": [ { "identifier": "foo", "install-location": "/path/to/install/location", "requirements": [ "bar >= 1, < 2" ] } ] } :param data: Mapping to validate. :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ data = data.get("variants") validate_type(data, list, label="'variants'") validate_not_empty(data, label="'variants'") keywords = { "identifier", "install-location", "command", "environ", "requirements" } for index, data in enumerate(data or []): validate_type(data, dict, label="'variants/{}'".format(index)) validate_keywords(data, keywords, label="'variants/{}'".format(index)) validate_identifier_keyword(data, variant_index=index) validate_install_location_keyword(data, variant_index=index) validate_command_keyword(data, variant_index=index) validate_environ_keyword(data, variant_index=index) validate_requirements_keyword(data, variant_index=index)
[docs]def validate_keywords(data, keywords, label="Data"): """Ensure that no invalid keywords are in *data* mapping. :param data: Mapping to validate. :param keywords: Set of authorized keywords. :param label: String to describe *data* if an error is raised. Default is "Data". :raise: :exc:`ValueError` if the *data* mapping is incorrect. """ remaining_keywords = set(data.keys()).difference(keywords) if remaining_keywords != set(): raise ValueError( "{} contains invalid keywords: {}" .format(label, ", ".join(remaining_keywords)) )
[docs]def validate_required(data, label="Data"): """Ensure that *data* exists. :param data: Content to validate. :param label: String to describe *data* if an error is raised. Default is "Data". :raise: :exc:`ValueError` if *data* is incorrect. """ if data is None: raise ValueError("{} is required.".format(label))
[docs]def validate_type(data, data_type, label="Data"): """Ensure that *data* has correct type. :param data: Content to validate. :param data_type: Type expected for *data*. It can be a tuple if several types are authorized. :param label: String to describe *data* if an error is raised. Default is "Data". :raise: :exc:`ValueError` if *data* is incorrect. """ if data is not None and not isinstance(data, data_type): raise ValueError("{} has incorrect type.".format(label))
[docs]def validate_not_empty(data, label="Data"): """Ensure that *data* container is not empty. :param data: Content to validate. It could be a list or a mapping. :param label: String to describe *data* if an error is raised. Default is "Data". :raise: :exc:`ValueError` if *data* is incorrect. """ if data is not None and not len(data): raise ValueError("{} should not be empty.".format(label))