Boards under a folder that doesn't directly match a vendor prefix incorrectly end up being categorized as "zephyr" since that's the only prefix that is eventually found when navigating up the folder hierarchy. This commits treats boards in the "others" and "native" folders as special cases and associates them to an "Unknown/Other" category. Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
130 lines
4.2 KiB
Python
130 lines
4.2 KiB
Python
# Copyright (c) 2024 The Linux Foundation
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
import logging
|
|
from collections import namedtuple
|
|
from pathlib import Path
|
|
|
|
import list_boards, list_hardware
|
|
import yaml
|
|
import zephyr_module
|
|
from gen_devicetree_rest import VndLookup
|
|
|
|
ZEPHYR_BASE = Path(__file__).parents[2]
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def guess_file_from_patterns(directory, patterns, name, extensions):
|
|
for pattern in patterns:
|
|
for ext in extensions:
|
|
matching_file = next(directory.glob(pattern.format(name=name, ext=ext)), None)
|
|
if matching_file:
|
|
return matching_file
|
|
return None
|
|
|
|
|
|
def guess_image(board_or_shield):
|
|
img_exts = ["jpg", "jpeg", "webp", "png"]
|
|
patterns = [
|
|
"**/{name}.{ext}",
|
|
"**/*{name}*.{ext}",
|
|
"**/*.{ext}",
|
|
]
|
|
img_file = guess_file_from_patterns(
|
|
board_or_shield.dir, patterns, board_or_shield.name, img_exts
|
|
)
|
|
|
|
return (img_file.relative_to(ZEPHYR_BASE)).as_posix() if img_file else None
|
|
|
|
def guess_doc_page(board_or_shield):
|
|
patterns = [
|
|
"doc/index.{ext}",
|
|
"**/{name}.{ext}",
|
|
"**/*{name}*.{ext}",
|
|
"**/*.{ext}",
|
|
]
|
|
doc_file = guess_file_from_patterns(
|
|
board_or_shield.dir, patterns, board_or_shield.name, ["rst"]
|
|
)
|
|
return doc_file
|
|
|
|
|
|
def get_catalog():
|
|
vnd_lookup = VndLookup(ZEPHYR_BASE / "dts/bindings/vendor-prefixes.txt", [])
|
|
|
|
module_settings = {
|
|
"arch_root": [ZEPHYR_BASE],
|
|
"board_root": [ZEPHYR_BASE],
|
|
"soc_root": [ZEPHYR_BASE],
|
|
}
|
|
|
|
for module in zephyr_module.parse_modules(ZEPHYR_BASE):
|
|
for key in module_settings:
|
|
root = module.meta.get("build", {}).get("settings", {}).get(key)
|
|
if root is not None:
|
|
module_settings[key].append(Path(module.project) / root)
|
|
|
|
Args = namedtuple("args", ["arch_roots", "board_roots", "soc_roots", "board_dir", "board"])
|
|
args_find_boards = Args(
|
|
arch_roots=module_settings["arch_root"],
|
|
board_roots=module_settings["board_root"],
|
|
soc_roots=module_settings["soc_root"],
|
|
board_dir=ZEPHYR_BASE / "boards",
|
|
board=None,
|
|
)
|
|
|
|
boards = list_boards.find_v2_boards(args_find_boards)
|
|
systems = list_hardware.find_v2_systems(args_find_boards)
|
|
board_catalog = {}
|
|
|
|
for board in boards:
|
|
# We could use board.vendor but it is often incorrect. Instead, deduce vendor from
|
|
# containing folder. There are a few exceptions, like the "native" and "others" folders
|
|
# which we know are not actual vendors so treat them as such.
|
|
for folder in board.dir.parents:
|
|
if folder.name in ["native", "others"]:
|
|
vendor = "others"
|
|
break
|
|
elif vnd_lookup.vnd2vendor.get(folder.name):
|
|
vendor = folder.name
|
|
break
|
|
|
|
# Grab all the twister files for this board and use them to figure out all the archs it
|
|
# supports.
|
|
archs = set()
|
|
pattern = f"{board.name}*.yaml"
|
|
for twister_file in board.dir.glob(pattern):
|
|
try:
|
|
with open(twister_file, "r") as f:
|
|
board_data = yaml.safe_load(f)
|
|
archs.add(board_data.get("arch"))
|
|
except Exception as e:
|
|
logger.error(f"Error parsing twister file {twister_file}: {e}")
|
|
|
|
socs = {soc.name for soc in board.socs}
|
|
full_name = board.full_name or board.name
|
|
doc_page = guess_doc_page(board)
|
|
|
|
board_catalog[board.name] = {
|
|
"name": board.name,
|
|
"full_name": full_name,
|
|
"doc_page": doc_page.relative_to(ZEPHYR_BASE).as_posix() if doc_page else None,
|
|
"vendor": vendor,
|
|
"archs": list(archs),
|
|
"socs": list(socs),
|
|
"image": guess_image(board),
|
|
}
|
|
|
|
socs_hierarchy = {}
|
|
for soc in systems.get_socs():
|
|
family = soc.family or "<no family>"
|
|
series = soc.series or "<no series>"
|
|
socs_hierarchy.setdefault(family, {}).setdefault(series, []).append(soc.name)
|
|
|
|
return {
|
|
"boards": board_catalog,
|
|
"vendors": {**vnd_lookup.vnd2vendor, "others": "Other/Unknown"},
|
|
"socs": socs_hierarchy,
|
|
}
|