1#!/usr/bin/env python3
2#
3# Copyright (c) 2024, Nordic Semiconductor ASA
4#
5# SPDX-License-Identifier: Apache-2.0
6
7"""
8This script generates a module.yml file for the Zephyr project. The module.yml file contains
9information about the blobs. The script computes the SHA-256 hash for each blob and renders
10the Jinja2 template with the blob information.
11"""
12
13import argparse
14import hashlib
15import requests
16import logging
17from jinja2 import Environment, FileSystemLoader
18from typing import Dict, Any, List
19from collections import namedtuple
20
21WIFI_FW_BIN_NAME: str = "nrf70.bin"
22
23# Paths are relative to the sdk-nrfxlib repository
24BlobInfo = namedtuple(
25    "BlobInfo", ["name", "description", "version", "rpath", "lpath", "docpath"]
26)
27
28
29def get_wifi_blob_info(name: str) -> BlobInfo:
30    return BlobInfo(
31        name,
32        f"nRF70 Wi-Fi firmware for {name} mode",
33        "1.0.0",
34        f"nrf_wifi/bin/zephyr/{name}/{WIFI_FW_BIN_NAME}",
35        f"wifi_fw_bins/{name}/{WIFI_FW_BIN_NAME}",
36        f"nrf_wifi/doc",
37    )
38
39
40nordic_blobs: List[BlobInfo] = [
41    get_wifi_blob_info("default"),
42    get_wifi_blob_info("scan_only"),
43    get_wifi_blob_info("radio_test"),
44    get_wifi_blob_info("system_with_raw"),
45    get_wifi_blob_info("offloaded_raw_tx"),
46]
47
48logger: logging.Logger = logging.getLogger(__name__)
49logging.basicConfig(level=logging.INFO)
50
51
52def compute_sha256(url: str) -> str:
53    response = requests.get(url)
54    response.raise_for_status()
55    sha256_hash: str = hashlib.sha256(response.content).hexdigest()
56    return sha256_hash
57
58
59def render_template(template_path: str, output_path: str, latest_sha: str) -> None:
60    # Load the Jinja2 template
61    env: Environment = Environment(loader=FileSystemLoader("."))
62    template = env.get_template(template_path)
63
64    # list of dictionaries containing blob information
65    blobs: Dict[str, Dict[str, Any]] = {}
66    # Compute SHA-256 for each blob based on the URL
67    for blob in nordic_blobs:
68        logger.debug(f"Processing blob: {blob.name}")
69        nrfxlib_url = f"https://github.com/nrfconnect/sdk-nrfxlib/raw/{latest_sha}"
70        blob_info: Dict[str, Any] = {}
71        blob_info["path"] = blob.lpath
72        blob_info["rpath"] = blob.rpath
73        blob_info["version"] = blob.version
74        blob_info["url"] = f"{nrfxlib_url}/{blob.rpath}"
75        blob_info["doc_url"] = f"{nrfxlib_url}/{blob.docpath}"
76        blob_info["sha256"] = compute_sha256(blob_info["url"])
77        blob_info["description"] = blob.description
78        blobs[blob] = blob_info
79
80    logger.debug(blobs)
81    # Render the template with the provided context
82    rendered_content: str = template.render(blobs=blobs, latest_sha=latest_sha)
83
84    # Write the rendered content to the output file
85    with open(output_path, "w") as output_file:
86        output_file.write(rendered_content)
87
88
89def main() -> None:
90    parser: argparse.ArgumentParser = argparse.ArgumentParser(
91        description="Generate a module.yml file for the Zephyr project."
92    )
93    parser.add_argument(
94        "-t",
95        "--template",
96        default="scripts/module.yml.j2",
97        help="Path to the Jinja2 template file.",
98    )
99    parser.add_argument(
100        "-o",
101        "--output",
102        default="zephyr/module.yml",
103        help="Path to the output YAML file.",
104    )
105    parser.add_argument(
106        "-c",
107        "--commit",
108        required=True,
109        help="The latest commit SHA for the nrfxlib repository.",
110    )
111    parser.add_argument(
112        "-d", "--debug", action="store_true", help="Enable debug logging."
113    )
114
115    args: argparse.Namespace = parser.parse_args()
116
117    if args.debug:
118        logger.setLevel(logging.DEBUG)
119
120    # Render the template
121    render_template(args.template, args.output, args.commit)
122
123
124if __name__ == "__main__":
125    main()
126