zephyr/doc/_scripts/gen_boards_catalog.py
Benjamin Cabé 04e6406edb doc: boards: extensions: store "raw" image path
Small change to the way image are stored in the catalog so that we know
where the source image is rather than anticipating on the final path
after build has happened. This allows to potentially reference the
source image from e.g. directives.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2024-10-22 14:11:27 +02:00

124 lines
3.9 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 pykwalify
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():
pykwalify.init_logging(1)
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
for folder in board.dir.parents:
if 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] = {
"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, "socs": socs_hierarchy}