def validate_yaml(yaml_file, depth=__MAX_IMPORT_DEPTH__): """Validate clowder.yaml :param str yaml_file: Yaml file path to validate :param Optional[int] depth: Max depth of clowder.yaml imports Raises: ClowderExit ClowderYAMLError """ parsed_yaml = parse_yaml(yaml_file) if depth < 0: raise ClowderYAMLError(fmt.recursive_import_error(__MAX_IMPORT_DEPTH__)) if 'import' not in parsed_yaml: _validate_yaml(yaml_file) return _validate_yaml_import(yaml_file) imported_yaml_file = get_clowder_yaml_import_path(parsed_yaml['import']) if not os.path.isfile(imported_yaml_file): raise ClowderYAMLError(fmt.missing_imported_yaml_error(imported_yaml_file, yaml_file)) try: validate_yaml(imported_yaml_file, depth=depth - 1) except ClowderYAMLError as err: raise ClowderYAMLError(err) except (KeyboardInterrupt, SystemExit): raise ClowderExit(1)
def load_yaml(): """Load clowder from yaml file :raise ClowderYAMLError: """ yaml_file = os.path.join(ROOT_DIR, 'clowder.yaml') parsed_yaml = parse_yaml(yaml_file) imported_yaml_files = [] combined_yaml = {} while True: if 'import' not in parsed_yaml: _load_yaml_base(parsed_yaml, combined_yaml) break imported_yaml_files.append(parsed_yaml) imported_yaml_file = get_clowder_yaml_import_path(parsed_yaml['import']) parsed_yaml = parse_yaml(imported_yaml_file) if len(imported_yaml_files) > __MAX_IMPORT_DEPTH__: raise ClowderYAMLError(fmt.recursive_import_error(__MAX_IMPORT_DEPTH__)) for parsed_yaml in reversed(imported_yaml_files): _load_yaml_import(parsed_yaml, combined_yaml) return combined_yaml
def _validate_yaml(yaml_file): """Validate clowder.yaml with no import :param str yaml_file: Path to yaml file :raise ClowderYAMLError: """ parsed_yaml = parse_yaml(yaml_file) validate_type(parsed_yaml, fmt.yaml_file('clowder.yaml'), dict, 'dict', yaml_file) if not parsed_yaml: raise ClowderYAMLError(fmt.empty_yaml_error(yaml_file)) validate_required_dict(parsed_yaml, 'defaults', validate_yaml_defaults, yaml_file) validate_required_dict(parsed_yaml, 'sources', validate_yaml_sources, yaml_file) validate_required_dict(parsed_yaml, 'groups', validate_yaml_groups, yaml_file) if parsed_yaml: raise ClowderYAMLError(fmt.unknown_entry_error(fmt.yaml_file('clowder.yaml'), parsed_yaml, yaml_file))
def validate_type_depth(value, yaml_file): """Validate depth value :param int value: Integer depth value :param str yaml_file: Path to yaml file :raise ClowderYAMLError: """ if not isinstance(value, int) or int(value) < 0: raise ClowderYAMLError(fmt.depth_error(value, yaml_file))
def validate_not_empty(collection, name, yaml_file): """Check whether collection is empty :param collection: Parsed YAML python object :param str name: Name of collection to print if empty :param str yaml_file: Path to yaml file :raise ClowderYAMLError: """ if not collection: raise ClowderYAMLError(fmt.missing_entries_error(name, yaml_file))
def validate_ref_type(dictionary, yaml_file): """Check whether ref type is valid :param dict dictionary: Parsed YAML python object :param str yaml_file: Path to yaml file :raise ClowderYAMLError: """ if not _valid_ref_type(dictionary['ref']): raise ClowderYAMLError( fmt.invalid_ref_error(dictionary['ref'], yaml_file))
def validate_empty(collection, name, yaml_file): """Check whether collection is not empty :param collection: Parsed YAML python object :param str name: Name of collection to print if empty :param str yaml_file: Path to yaml file :raise ClowderYAMLError: """ if collection: raise ClowderYAMLError( fmt.unknown_entry_error(name, collection, yaml_file))
def validate_dict_contains_value(dictionary, dict_name, value, yaml_file): """Check whether yaml file contains value :param dict dictionary: Parsed YAML python object :param str dict_name: Name of dict to print if missing :param str value: Name of entry to check :param str yaml_file: Path to yaml file :raise ClowderYAMLError: """ if value not in dictionary: raise ClowderYAMLError( fmt.missing_entry_error(value, dict_name, yaml_file))
def validate_type(value, name, classinfo, type_name, yaml_file): """Validate value type :param value: Value to check :param str name: Name of value to print if invalid :param type classinfo: Type to check :param str type_name: Name of type to print if invalid :param str yaml_file: Path to yaml file :raise ClowderYAMLError: """ if not isinstance(value, classinfo): raise ClowderYAMLError(fmt.type_error(name, yaml_file, type_name))
def validate_clowder_yaml_contains_value(parsed_yaml, value, yaml_file): """Check whether yaml file contains value :param dict parsed_yaml: Parsed YAML python object :param str value: Name of entry to check :param str yaml_file: Path to yaml file :raise ClowderYAMLError: """ if value not in parsed_yaml: raise ClowderYAMLError( fmt.missing_entry_error(value, fmt.yaml_file('clowder.yaml'), yaml_file))
def _validate_yaml_import(yaml_file): """Validate clowder.yaml with an import :param str yaml_file: Path to yaml file :raise ClowderYAMLError: """ parsed_yaml = parse_yaml(yaml_file) validate_type(parsed_yaml, fmt.yaml_file('clowder.yaml'), dict, 'dict', yaml_file) validate_clowder_yaml_contains_value(parsed_yaml, 'import', yaml_file) validate_type(parsed_yaml['import'], 'import', str, 'str', yaml_file) del parsed_yaml['import'] if not parsed_yaml: raise ClowderYAMLError(fmt.empty_yaml_error(yaml_file)) validate_optional_dict(parsed_yaml, 'defaults', validate_yaml_defaults_import, yaml_file) validate_optional_dict(parsed_yaml, 'sources', validate_yaml_sources, yaml_file) validate_optional_dict(parsed_yaml, 'groups', validate_yaml_groups_import, yaml_file) if parsed_yaml: raise ClowderYAMLError(fmt.unknown_entry_error(fmt.yaml_file('clowder.yaml'), parsed_yaml, yaml_file))
def parse_yaml(yaml_file): """Parse yaml file :param str yaml_file: Path to yaml file :return: YAML python object :rtype: dict Raises: ClowderExit ClowderYAMLError """ if not os.path.isfile(yaml_file): raise ClowderYAMLError(fmt.missing_yaml_error()) try: with open(yaml_file) as raw_file: parsed_yaml = yaml.safe_load(raw_file) if parsed_yaml is None: raise ClowderYAMLError(fmt.empty_yaml_error(yaml_file)) return parsed_yaml except yaml.YAMLError: raise ClowderYAMLError(fmt.open_file_error(yaml_file)) except (KeyboardInterrupt, SystemExit): raise ClowderExit(1)
def __init__(self, project, group, defaults, sources): """Project __init__ :param dict project: Parsed YAML python object for project :param dict group: Parsed YAML python object for group :param Defaults defaults: Defaults instance :param list[Source] sources: List of Source instances :raise ClowderYAMLError: """ self.name = project['name'] self.path = project['path'] self.ref = project.get('ref', group.get('ref', defaults.ref)) self.remote = project.get('remote', group.get('remote', defaults.remote)) self.depth = project.get('depth', group.get('depth', defaults.depth)) self.recursive = project.get( 'recursive', group.get('recursive', defaults.recursive)) self._protocol = defaults.protocol self._timestamp_author = project.get( 'timestamp_author', group.get('timestamp_author', defaults.timestamp_author)) self._print_output = True self.source = None source_name = project.get('source', group.get('source', defaults.source)) for source in sources: if source.name == source_name: self.source = source self.fork = None if 'fork' in project: fork = project['fork'] if fork['remote'] == self.remote: raise ClowderYAMLError( fmt.remote_name_error(fork['name'], self.name, self.remote)) self.fork = Fork(fork, self.path, self.source, self._protocol)