You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.4 KiB
128 lines
3.4 KiB
# 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
|
|
|