# Copyright (c) 2022 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 '''Domain handling for west extension commands. This provides parsing of domains yaml file and creation of objects of the Domain class. ''' import yaml import pykwalify.core from west import log DOMAINS_SCHEMA = ''' ## A pykwalify schema for basic validation of the structure of a ## domains YAML file. ## # The domains.yaml file is a simple list of domains from a multi image build # along with the default domain to use. type: map mapping: default: required: true type: str build_dir: required: true type: str domains: required: false type: seq sequence: - type: map mapping: name: required: true type: str build_dir: required: true type: str ''' schema = yaml.safe_load(DOMAINS_SCHEMA) class Domains: def __init__(self, data): self._domains = [] self._domain_names = [] self._domain_default = [] self._build_dir = data.get('build_dir') domain_list = data.get('domains') if not domain_list: log.wrn("no domains defined; this probably won't work") for d in domain_list: domain = Domain(d['name'], d['build_dir']) self._domains.append(domain) self._domain_names.append(domain.name) if domain.name == data['default']: self._default_domain = domain @staticmethod def from_file(domains_file): '''Load domains from domains.yaml. Exception raised: - ``FileNotFoundError`` if the domains file is not found. ''' try: with open(domains_file, 'r') as f: domains = yaml.safe_load(f.read()) except FileNotFoundError: log.die(f'domains.yaml file not found: {domains_file}') try: pykwalify.core.Core(source_data=domains, schema_data=schema)\ .validate() except pykwalify.errors.SchemaError: log.die(f'ERROR: Malformed yaml in file: {domains_file}') return Domains(domains) @staticmethod def from_data(domains_data): '''Load domains from domains dictionary. ''' return Domains(domains_data) def get_domains(self, names=None): ret = [] if not names: return self._domains for n in names: found = False for d in self._domains: if n == d.name: ret.append(d) found = True break # Getting here means the domain was not found. # Todo: throw an error. if not found: log.die(f'domain {n} not found, ' f'valid domains are:', *self._domain_names) return ret def get_default_domain(self): return self._default_domain def get_top_build_dir(self): return self._build_dir class Domain: def __init__(self, name, build_dir): self.name = name self.build_dir = build_dir @property def name(self): return self._name @name.setter def name(self, value): self._name = value @property def build_dir(self): return self._build_dir @build_dir.setter def build_dir(self, value): self._build_dir = value