129 lines
3.4 KiB
Python
129 lines
3.4 KiB
Python
# 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.
|
|
'''
|
|
|
|
from dataclasses import dataclass
|
|
|
|
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: true
|
|
type: seq
|
|
sequence:
|
|
- type: map
|
|
mapping:
|
|
name:
|
|
required: true
|
|
type: str
|
|
build_dir:
|
|
required: true
|
|
type: str
|
|
flash_order:
|
|
required: false
|
|
type: seq
|
|
sequence:
|
|
- 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, domains_yaml):
|
|
try:
|
|
data = yaml.safe_load(domains_yaml)
|
|
pykwalify.core.Core(source_data=data,
|
|
schema_data=schema).validate()
|
|
except (yaml.YAMLError, pykwalify.errors.SchemaError):
|
|
logger.critical(f'malformed domains.yaml')
|
|
exit(1)
|
|
|
|
self._build_dir = data['build_dir']
|
|
self._domains = {
|
|
d['name']: Domain(d['name'], d['build_dir'])
|
|
for d in data['domains']
|
|
}
|
|
|
|
# In the YAML data, the values for "default" and "flash_order"
|
|
# must not name any domains that aren't listed under "domains".
|
|
# Now that self._domains has been initialized, we can leverage
|
|
# the common checks in self.get_domain to verify this.
|
|
self._default_domain = self.get_domain(data['default'])
|
|
self._flash_order = self.get_domains(data.get('flash_order', []))
|
|
|
|
@staticmethod
|
|
def from_file(domains_file):
|
|
'''Load domains from a domains.yaml file.
|
|
'''
|
|
try:
|
|
with open(domains_file, 'r') as f:
|
|
domains_yaml = f.read()
|
|
except FileNotFoundError:
|
|
logger.critical(f'domains.yaml file not found: {domains_file}')
|
|
exit(1)
|
|
|
|
return Domains(domains_yaml)
|
|
|
|
@staticmethod
|
|
def from_yaml(domains_yaml):
|
|
'''Load domains from a string with YAML contents.
|
|
'''
|
|
return Domains(domains_yaml)
|
|
|
|
def get_domains(self, names=None, default_flash_order=False):
|
|
if names is None:
|
|
if default_flash_order:
|
|
return self._flash_order
|
|
return list(self._domains.values())
|
|
return list(map(self.get_domain, names))
|
|
|
|
def get_domain(self, name):
|
|
found = self._domains.get(name)
|
|
if not found:
|
|
logger.critical(f'domain "{name}" not found, '
|
|
f'valid domains are: {", ".join(self._domains)}')
|
|
exit(1)
|
|
return found
|
|
|
|
def get_default_domain(self):
|
|
return self._default_domain
|
|
|
|
def get_top_build_dir(self):
|
|
return self._build_dir
|
|
|
|
|
|
@dataclass
|
|
class Domain:
|
|
|
|
name: str
|
|
build_dir: str
|