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
21# Paths are relative to the sdk-nrfxlib repository
22BlobInfo = namedtuple(
23    "BlobInfo", ["name", "description", "version", "rpath", "lpath", "docpath"]
24)
25
26nordic_blobs: List[BlobInfo] = [
27    BlobInfo(
28        "suit_manifest_starter",
29        "nRF54H20 series SUIT manifest starter",
30        "5.0.0",
31        "suit/bin/suit_manifest_starter.hex",
32        "suit/bin/suit_manifest_starter.hex",
33        "suit/doc"
34        )
35]
36
37logger: logging.Logger = logging.getLogger(__name__)
38logging.basicConfig(level=logging.INFO)
39
40
41def compute_sha256(url: str) -> str:
42    response = requests.get(url)
43    response.raise_for_status()
44    sha256_hash: str = hashlib.sha256(response.content).hexdigest()
45    return sha256_hash
46
47
48def render_template(template_path: str, output_path: str, latest_sha: str) -> None:
49    # Load the Jinja2 template
50    env: Environment = Environment(loader=FileSystemLoader("."))
51    template = env.get_template(template_path)
52
53    # list of dictionaries containing blob information
54    blobs: Dict[str, Dict[str, Any]] = {}
55    # Compute SHA-256 for each blob based on the URL
56    for blob in nordic_blobs:
57        logger.debug(f"Processing blob: {blob.name}")
58        nrfxlib_url = f"https://github.com/nrfconnect/sdk-nrfxlib/raw/{latest_sha}"
59        blob_info: Dict[str, Any] = {}
60        blob_info["path"] = blob.lpath
61        blob_info["rpath"] = blob.rpath
62        blob_info["version"] = blob.version
63        blob_info["url"] = f"{nrfxlib_url}/{blob.rpath}"
64        blob_info["doc_url"] = f"{nrfxlib_url}/{blob.docpath}"
65        blob_info["sha256"] = compute_sha256(blob_info["url"])
66        blob_info["description"] = blob.description
67        blobs[blob] = blob_info
68
69    logger.debug(blobs)
70    # Render the template with the provided context
71    rendered_content: str = template.render(blobs=blobs, latest_sha=latest_sha)
72
73    # Write the rendered content to the output file
74    with open(output_path, "w") as output_file:
75        output_file.write(rendered_content)
76
77
78def main() -> None:
79    parser: argparse.ArgumentParser = argparse.ArgumentParser(
80        description="Generate a module.yml file for the Zephyr project."
81    )
82    parser.add_argument(
83        "-t",
84        "--template",
85        default="utils/module.yml.j2",
86        help="Path to the Jinja2 template file.",
87    )
88    parser.add_argument(
89        "-o",
90        "--output",
91        default="zephyr/module.yml",
92        help="Path to the output YAML file.",
93    )
94    parser.add_argument(
95        "-c",
96        "--commit",
97        required=True,
98        help="The latest commit SHA for the nrfxlib repository.",
99    )
100    parser.add_argument(
101        "-d", "--debug", action="store_true", help="Enable debug logging."
102    )
103
104    args: argparse.Namespace = parser.parse_args()
105
106    if args.debug:
107        logger.setLevel(logging.DEBUG)
108
109    # Render the template
110    render_template(args.template, args.output, args.commit)
111
112
113if __name__ == "__main__":
114    main()
115