Files
Balsam_167/UKSSTMS320F28335/prepare_identity.py
Andrey f741741cf8 Сохранить русские комментарии и настройки проекта в UTF-8
Добавить пояснения к исходникам, заголовкам TI, настройкам CCS и существующим проверкам. Зафиксировать правила кодировки, обзор модулей и аудит комментариев.
2026-10-12 12:24:48 +03:00

91 lines
8.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Настройки и интерфейс prepare_identity. Комментарии и исходный текст в UTF-8.
# Продолжает текущий вызов, список или выражение: """Generate build identity using the release version from firmware_version.h."""; порядок аргументов сохраняется.
"""Generate build identity using the release version from firmware_version.h."""
# Подключает модуль argparse для этой проверки или подготовки сборки.
import argparse
# Подключает модуль importlib.util для этой проверки или подготовки сборки.
import importlib.util
# Подключает модуль json для этой проверки или подготовки сборки.
import json
# Импортирует необходимые имена: from pathlib import Path.
from pathlib import Path
# Подключает модуль re для этой проверки или подготовки сборки.
import re
# Подключает модуль tempfile для этой проверки или подготовки сборки.
import tempfile
# Объявляет функцию read_version и её входные параметры.
def read_version(header):
# Читает исходный файл или образ для последующей проверки и разбора.
text = header.read_text(encoding="utf-8-sig")
# Задаёт text по выражению справа; значение используется последующими операциями.
text = re.sub(r"/\*.*?\*/|//[^\n]*", "", text, flags=re.S)
# Задаёт version по выражению справа; значение используется последующими операциями.
version = []
# Перебирает part, limit in (("MAJOR", 255), ("MINOR", 255), ("PATCH", 999)) в указанном порядке.
for part, limit in (("MAJOR", 255), ("MINOR", 255), ("PATCH", 999)):
# Задаёт name по выражению справа; значение используется последующими операциями.
name = "FIRMWARE_VERSION_" + part
# Задаёт definitions по выражению справа; значение используется последующими операциями.
definitions = re.findall(r"^\s*#\s*define\s+" + name + r"\b([^\n]*)", text, re.M)
# Проверяет условие if len(definitions) != 1 перед выполнением следующего блока.
if len(definitions) != 1:
# Останавливает текущую операцию с исключением ValueError(f"{header}: define {name} exactly once").
raise ValueError(f"{header}: define {name} exactly once")
# Задаёт value по выражению справа; значение используется последующими операциями.
value = definitions[0].strip()
# Проверяет условие if not re.fullmatch(r"(?:0|[1-9][0-9]*)[uU]?", value) перед выполнением следующего блока.
if not re.fullmatch(r"(?:0|[1-9][0-9]*)[uU]?", value):
# Останавливает текущую операцию с исключением ValueError(f"{header}: {name} must be a decimal integer").
raise ValueError(f"{header}: {name} must be a decimal integer")
# Задаёт number по выражению справа; значение используется последующими операциями.
number = int(value.rstrip("uU"))
# Проверяет условие if not 0 <= number <= limit перед выполнением следующего блока.
if not 0 <= number <= limit:
# Останавливает текущую операцию с исключением ValueError(f"{header}: {name} must be in 0..{limit}").
raise ValueError(f"{header}: {name} must be in 0..{limit}")
# Продолжает текущий вызов, список или выражение: version.append(number); порядок аргументов сохраняется.
version.append(number)
# Возвращает version вызывающему коду и завершает функцию.
return version
# Объявляет функцию prepare и её входные параметры.
def prepare(project, templates, output):
# Читает исходный файл или образ для последующей проверки и разбора.
settings = json.loads((project / "firmware_identity.json").read_text(encoding="utf-8-sig"))
# Задаёт settings["version"] по выражению справа; значение используется последующими операциями.
settings["version"] = read_version(project / "firmware_version.h")
# Задаёт spec по выражению справа; значение используется последующими операциями.
spec = importlib.util.spec_from_file_location("shared_firmware_identity", templates / "c/firmware-info/tools/identity.py")
# Задаёт identity по выражению справа; значение используется последующими операциями.
identity = importlib.util.module_from_spec(spec)
# Продолжает текущий вызов, список или выражение: spec.loader.exec_module(identity); порядок аргументов сохраняется.
spec.loader.exec_module(identity)
# The source header owns SemVer; retain the shared generator and manifest format.
# Открывает управляемый ресурс tempfile.TemporaryDirectory(prefix="balsam-identity-") as directory с автоматическим освобождением.
with tempfile.TemporaryDirectory(prefix="balsam-identity-") as directory:
# Задаёт config по выражению справа; значение используется последующими операциями.
config = Path(directory) / "config.json"
# Сохраняет подготовленный файл в указанном формате для следующего шага.
config.write_text(json.dumps(settings), encoding="utf-8")
# Возвращает identity.prepare(project, templates, config, output) вызывающему коду и завершает функцию.
return identity.prepare(project, templates, config, output)
# Проверяет условие if __name__ == "__main__" перед выполнением следующего блока.
if __name__ == "__main__":
# Задаёт parser по выражению справа; значение используется последующими операциями.
parser = argparse.ArgumentParser(description=__doc__)
# Задаёт parser.add_argument("--project", type по выражению справа; значение используется последующими операциями.
parser.add_argument("--project", type=Path, required=True)
# Задаёт parser.add_argument("--templates", type по выражению справа; значение используется последующими операциями.
parser.add_argument("--templates", type=Path, required=True)
# Задаёт parser.add_argument("--output", type по выражению справа; значение используется последующими операциями.
parser.add_argument("--output", type=Path, required=True)
# Задаёт args по выражению справа; значение используется последующими операциями.
args = parser.parse_args()
# Продолжает текущий вызов, список или выражение: print(json.dumps(prepare(args.project, args.templates, args.output))); порядок аргументов сохраняется.
print(json.dumps(prepare(args.project, args.templates, args.output)))