|
42 | 42 | # Don't change this, or output from argparse won't match up. |
43 | 43 | INDENT = ' ' * 2 |
44 | 44 |
|
| 45 | +IGNORED_RUN_ONCE_PRIORITY = -1 |
| 46 | +SOC_FILE_RUN_ONCE_DEFAULT_PRIORITY = 0 |
| 47 | +BOARD_FILE_RUN_ONCE_DEFAULT_PRIORITY = 10 |
| 48 | + |
45 | 49 | if log.VERBOSE >= log.VERBOSE_NORMAL: |
46 | 50 | # Using level 1 allows sub-DEBUG levels of verbosity. The |
47 | 51 | # west.log module decides whether or not to actually print the |
@@ -96,6 +100,13 @@ class ImagesFlashed: |
96 | 100 | flashed: int = 0 |
97 | 101 | total: int = 0 |
98 | 102 |
|
| 103 | +@dataclass |
| 104 | +class SocBoardFilesProcessing: |
| 105 | + filename: str |
| 106 | + board: bool = False |
| 107 | + priority: int = IGNORED_RUN_ONCE_PRIORITY |
| 108 | + yaml: object = None |
| 109 | + |
99 | 110 | def command_verb(command): |
100 | 111 | return "flash" if command.name == "flash" else "debug" |
101 | 112 |
|
@@ -178,6 +189,10 @@ def do_run_common(command, user_args, user_runner_args, domain_file=None): |
178 | 189 | # images for a given board. |
179 | 190 | board_image_count = defaultdict(ImagesFlashed) |
180 | 191 |
|
| 192 | + highest_priority = IGNORED_RUN_ONCE_PRIORITY |
| 193 | + highest_entry = None |
| 194 | + check_files = [] |
| 195 | + |
181 | 196 | if user_args.context: |
182 | 197 | dump_context(command, user_args, user_runner_args) |
183 | 198 | return |
@@ -223,48 +238,58 @@ def do_run_common(command, user_args, user_runner_args, domain_file=None): |
223 | 238 | # Load board flash runner configuration (if it exists) and store |
224 | 239 | # single-use commands in a dictionary so that they get executed |
225 | 240 | # once per unique board name. |
226 | | - if cache['BOARD_DIR'] not in processed_boards and 'SOC_FULL_DIR' in cache: |
227 | | - soc_yaml_file = Path(cache['SOC_FULL_DIR']) / 'soc.yml' |
228 | | - board_yaml_file = Path(cache['BOARD_DIR']) / 'board.yml' |
229 | | - group_type = 'boards' |
230 | | - |
231 | | - # Search for flash runner configuration, board takes priority over SoC |
232 | | - try: |
233 | | - with open(board_yaml_file, 'r') as f: |
234 | | - data_yaml = yaml.safe_load(f.read()) |
235 | | - |
236 | | - except FileNotFoundError: |
237 | | - continue |
238 | | - |
239 | | - if 'runners' not in data_yaml: |
240 | | - # Check SoC file |
241 | | - group_type = 'qualifiers' |
242 | | - try: |
243 | | - with open(soc_yaml_file, 'r') as f: |
244 | | - data_yaml = yaml.safe_load(f.read()) |
245 | | - |
246 | | - except FileNotFoundError: |
| 241 | + for directory in cache.get_list('SOC_DIRECTORIES'): |
| 242 | + if directory not in processed_boards: |
| 243 | + check_files.append(SocBoardFilesProcessing(Path(directory) / 'soc.yml')) |
| 244 | + processed_boards.add(directory) |
| 245 | + |
| 246 | + for directory in cache.get_list('BOARD_DIRECTORIES'): |
| 247 | + if directory not in processed_boards: |
| 248 | + check_files.append(SocBoardFilesProcessing(Path(directory) / 'board.yml', True)) |
| 249 | + processed_boards.add(directory) |
| 250 | + |
| 251 | + for check in check_files: |
| 252 | + try: |
| 253 | + with open(check.filename, 'r') as f: |
| 254 | + check.yaml = yaml.safe_load(f.read()) |
| 255 | + |
| 256 | + if 'runners' not in check.yaml: |
| 257 | + continue |
| 258 | + elif check.board is False and 'run_once' not in check.yaml['runners']: |
247 | 259 | continue |
248 | 260 |
|
249 | | - processed_boards.add(cache['BOARD_DIR']) |
250 | | - |
251 | | - if 'runners' not in data_yaml or 'run_once' not in data_yaml['runners']: |
252 | | - continue |
253 | | - |
254 | | - for cmd in data_yaml['runners']['run_once']: |
255 | | - for data in data_yaml['runners']['run_once'][cmd]: |
256 | | - for group in data['groups']: |
257 | | - run_first = bool(data['run'] == 'first') |
258 | | - if group_type == 'qualifiers': |
259 | | - targets = [] |
260 | | - for target in group[group_type]: |
261 | | - # For SoC-based qualifiers, prepend to the beginning of the |
262 | | - # match to allow for matching any board name |
263 | | - targets.append('([^/]+)/' + target) |
264 | | - else: |
265 | | - targets = group[group_type] |
266 | | - |
267 | | - used_cmds.append(UsedFlashCommand(cmd, targets, data['runners'], run_first)) |
| 261 | + if 'priority' in check.yaml['runners']: |
| 262 | + check.priority = check.yaml['runners']['priority'] |
| 263 | + else: |
| 264 | + check.priority = BOARD_FILE_RUN_ONCE_DEFAULT_PRIORITY if check.board is True else SOC_FILE_RUN_ONCE_DEFAULT_PRIORITY |
| 265 | + |
| 266 | + if check.priority == highest_priority: |
| 267 | + log.die("Duplicate flash run once configuration found with equal priorities") |
| 268 | + |
| 269 | + elif check.priority > highest_priority: |
| 270 | + highest_priority = check.priority |
| 271 | + highest_entry = check |
| 272 | + |
| 273 | + except FileNotFoundError: |
| 274 | + continue |
| 275 | + |
| 276 | + if highest_entry is not None: |
| 277 | + group_type = 'boards' if highest_entry.board is True else 'qualifiers' |
| 278 | + |
| 279 | + for cmd in highest_entry.yaml['runners']['run_once']: |
| 280 | + for data in highest_entry.yaml['runners']['run_once'][cmd]: |
| 281 | + for group in data['groups']: |
| 282 | + run_first = bool(data['run'] == 'first') |
| 283 | + if group_type == 'qualifiers': |
| 284 | + targets = [] |
| 285 | + for target in group[group_type]: |
| 286 | + # For SoC-based qualifiers, prepend to the beginning of the |
| 287 | + # match to allow for matching any board name |
| 288 | + targets.append('([^/]+)/' + target) |
| 289 | + else: |
| 290 | + targets = group[group_type] |
| 291 | + |
| 292 | + used_cmds.append(UsedFlashCommand(cmd, targets, data['runners'], run_first)) |
268 | 293 |
|
269 | 294 | # Reduce entries to only those having matching board names (either exact or with regex) and |
270 | 295 | # remove any entries with empty board lists |
|
0 commit comments