Добавить пояснения к исходникам, заголовкам TI, настройкам CCS и существующим проверкам. Зафиксировать правила кодировки, обзор модулей и аудит комментариев.
91 lines
8.2 KiB
Python
91 lines
8.2 KiB
Python
# Настройки и интерфейс 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)))
|