"""DefinitionValidator for Validating YAML and JSON Files""" import logging from pathlib import Path from typing import Any, Dict, Optional import yaml from samcli.yamlhelper import parse_yaml_file LOG = logging.getLogger(__name__) class DefinitionValidator: _path: Path _detect_change: bool _data: Optional[Dict[str, Any]] def __init__(self, path: Path, detect_change: bool = True, initialize_data: bool = True) -> None: """ Validator for JSON and YAML files. Calling validate_change() will return True if the definition is valid and has changes. Parameters ---------- path : Path Path to the definition file detect_change : bool, optional validation will only be successful if there are changes between current and previous data, by default True initialize_data : bool, optional Should initialize existing definition data before the first validate, by default True Used along with detect_change """ super().__init__() self._path = path self._detect_change = detect_change self._data = None if initialize_data: self.validate_change() def validate_change(self) -> bool: """Validate change on json or yaml file. Returns ------- bool True if it is valid, False otherwise. If detect_change is set, False will also be returned if there is no change compared to the previous validation. """ old_data = self._data if not self.validate_file(): return False return old_data != self._data if self._detect_change else True def validate_file(self) -> bool: """Validate json or yaml file. Returns ------- bool True if it is valid path and yaml file, False otherwise. """ if not self._path.exists(): LOG.debug( "File %s failed to validate due to file path does not exist. Please verify that the path is valid.", self._path, ) return False try: self._data = parse_yaml_file(str(self._path)) except (ValueError, yaml.YAMLError) as e: LOG.debug( "File %s failed to validate due to it file cannot be parsed. \ Please verify that file is in the correct json or yaml format.", self._path, exc_info=e, ) return False return True