Добавить пояснения к исходникам, заголовкам 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)))
|