blob: c748a94a14f63e16507230800563a5ee5e0bf232 [file] [log] [blame]
Torsten Rasmussen8408af62021-11-22 10:29:56 +01001# Copyright (c) 2022 Nordic Semiconductor ASA
2#
3# SPDX-License-Identifier: Apache-2.0
4
5'''Domain handling for west extension commands.
6
7This provides parsing of domains yaml file and creation of objects of the
8Domain class.
9'''
10
11import yaml
12import pykwalify.core
Daniel DeGrassec303c6f2022-11-01 12:16:39 -050013import logging
Torsten Rasmussen8408af62021-11-22 10:29:56 +010014
15DOMAINS_SCHEMA = '''
16## A pykwalify schema for basic validation of the structure of a
17## domains YAML file.
18##
19# The domains.yaml file is a simple list of domains from a multi image build
20# along with the default domain to use.
21type: map
22mapping:
23 default:
24 required: true
25 type: str
26 build_dir:
27 required: true
28 type: str
29 domains:
30 required: false
31 type: seq
32 sequence:
33 - type: map
34 mapping:
35 name:
36 required: true
37 type: str
38 build_dir:
39 required: true
40 type: str
41'''
42
43schema = yaml.safe_load(DOMAINS_SCHEMA)
Daniel DeGrassec303c6f2022-11-01 12:16:39 -050044logger = logging.getLogger('build_helpers')
45# Configure simple logging backend.
46formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
47handler = logging.StreamHandler()
48handler.setFormatter(formatter)
49logger.addHandler(handler)
Torsten Rasmussen8408af62021-11-22 10:29:56 +010050
51
52class Domains:
53
54 def __init__(self, data):
55 self._domains = []
56 self._domain_names = []
57 self._domain_default = []
58
59 self._build_dir = data.get('build_dir')
60 domain_list = data.get('domains')
61 if not domain_list:
Daniel DeGrassec303c6f2022-11-01 12:16:39 -050062 logger.warning("no domains defined; this probably won't work")
Torsten Rasmussen8408af62021-11-22 10:29:56 +010063
64 for d in domain_list:
65 domain = Domain(d['name'], d['build_dir'])
66 self._domains.append(domain)
67 self._domain_names.append(domain.name)
68 if domain.name == data['default']:
69 self._default_domain = domain
70
71 @staticmethod
72 def from_file(domains_file):
73 '''Load domains from domains.yaml.
74
75 Exception raised:
76 - ``FileNotFoundError`` if the domains file is not found.
77 '''
78 try:
79 with open(domains_file, 'r') as f:
80 domains = yaml.safe_load(f.read())
81 except FileNotFoundError:
Daniel DeGrassec303c6f2022-11-01 12:16:39 -050082 logger.critical(f'domains.yaml file not found: {domains_file}')
83 exit(1)
Torsten Rasmussen8408af62021-11-22 10:29:56 +010084
85 try:
86 pykwalify.core.Core(source_data=domains, schema_data=schema)\
87 .validate()
88 except pykwalify.errors.SchemaError:
Daniel DeGrassec303c6f2022-11-01 12:16:39 -050089 logger.critical(f'ERROR: Malformed yaml in file: {domains_file}')
90 exit(1)
Torsten Rasmussen8408af62021-11-22 10:29:56 +010091
92 return Domains(domains)
93
94 @staticmethod
95 def from_data(domains_data):
96 '''Load domains from domains dictionary.
97 '''
98 return Domains(domains_data)
99
100 def get_domains(self, names=None):
101 ret = []
102
103 if not names:
104 return self._domains
105
106 for n in names:
107 found = False
108 for d in self._domains:
109 if n == d.name:
110 ret.append(d)
111 found = True
112 break
113 # Getting here means the domain was not found.
114 # Todo: throw an error.
115 if not found:
Daniel DeGrassec303c6f2022-11-01 12:16:39 -0500116 logger.critical(f'domain {n} not found, '
Torsten Rasmussen8408af62021-11-22 10:29:56 +0100117 f'valid domains are:', *self._domain_names)
Daniel DeGrassec303c6f2022-11-01 12:16:39 -0500118 exit(1)
Torsten Rasmussen8408af62021-11-22 10:29:56 +0100119 return ret
120
121 def get_default_domain(self):
122 return self._default_domain
123
124 def get_top_build_dir(self):
125 return self._build_dir
126
127
128class Domain:
129
130 def __init__(self, name, build_dir):
131 self.name = name
132 self.build_dir = build_dir
133
134 @property
135 def name(self):
136 return self._name
137
138 @name.setter
139 def name(self, value):
140 self._name = value
141
142 @property
143 def build_dir(self):
144 return self._build_dir
145
146 @build_dir.setter
147 def build_dir(self, value):
148 self._build_dir = value