blob: c748a94a14f63e16507230800563a5ee5e0bf232 [file] [log] [blame]
# 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
import logging
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)
logger = logging.getLogger('build_helpers')
# Configure simple logging backend.
formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
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:
logger.warning("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:
logger.critical(f'domains.yaml file not found: {domains_file}')
exit(1)
try:
pykwalify.core.Core(source_data=domains, schema_data=schema)\
.validate()
except pykwalify.errors.SchemaError:
logger.critical(f'ERROR: Malformed yaml in file: {domains_file}')
exit(1)
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:
logger.critical(f'domain {n} not found, '
f'valid domains are:', *self._domain_names)
exit(1)
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