Использовать общий итератор версии прошивки

Убрать повторное увеличение версии из проектной обёртки.
Проверять прямое подключение templates и вызов через обёртку в CCS.
Сохранить текущий номер прошивки 1.0.5 и уточнить документацию.
This commit is contained in:
2026-10-19 12:02:08 +03:00
parent 31f92e89d9
commit dce9dd41a4
4 changed files with 29 additions and 32 deletions
+6
View File
@@ -145,6 +145,12 @@ manifest, SHA-256, HEX и карту конверсии в `K:\git_project\28335
После 255.255.999 сценарий выдаёт ошибку. Clean номер не сбрасывает.
Одновременные сборки с одним JSON запускать нельзя.
Итератор реализован в общем `templates/c/firmware-info/tools/identity.py`.
Он работает и при прямом вызове `templates/tools/firmware-build/ccs/precompile.bat
--identity`, который настроен в Debug, и через `firmware_build.bat prepare`.
Проектная обёртка передаёт настройки в templates без повторного увеличения.
Без поля `increment_version` либо при `false` сохраняется ручная версия.
Build ID состоит из восьми символов: восемь символов ревизии либо семь
символов и `+` при изменениях исходников или templates. При недоступном Git
используется `NOGIT000`; ревизии `source` и `templates` проверяйте в manifest.
+3 -21
View File
@@ -7,7 +7,7 @@ from pathlib import Path # Разрешает относительные пут
import shutil # Переносит только прошедшие проверку файлы текущей сборки.
import struct # Читает загрузочные секции SCI8 как 16-битные слова C28x.
import subprocess # Запускает публичные BAT общей библиотеки и передаёт ошибки вызывающей сборке.
import tempfile # Изолирует конверсию и обеспечивает атомарную замену файла счётчика.
import tempfile # Изолирует результаты конверсии до проверки паспорта и контрольных файлов; счётчик теперь сохраняет общий генератор templates.
def read_settings(config): # Проверяет настройки до изменения счётчика и запуска общих шагов.
@@ -32,30 +32,12 @@ def config_path(config, value): # Делает размещение templates
return (config.parent / value).resolve() # Абсолютный путь остаётся абсолютным, относительный отсчитывается от JSON.
def next_version(version): # Вычисляет следующий номер по пределам общего контракта паспорта.
result = list(version) # Не меняет исходные настройки до успешной проверки переполнения.
for index, limit in ((2, 999), (1, 255), (0, 255)): # Переносит единицу из patch в minor, затем в major.
if result[index] < limit: # Увеличивает первое поле, ещё не достигшее своего предела.
result[index] += 1 # Резервирует один следующий номер для очередного запуска prebuild.
return result # Старшие поля сохраняются, младшие уже обнулены при переносе.
result[index] = 0 # Сбрасывает переполненное поле перед увеличением следующего.
raise ValueError("Firmware version exhausted at 255.255.999") # Запрещает повторное использование номеров после полного переполнения.
def prepare(config, build_dir): # Увеличивает сохраняемую версию и вызывает штатный precompile templates.
def prepare(config, build_dir): # Передаёт резервирование версии и генерацию паспорта штатному precompile templates без повторного увеличения номера.
settings = read_settings(config) # Сначала проверяет настройки, чтобы ошибочный JSON не занимал номер сборки.
script = config_path(config, settings["templates"]) / "tools/firmware-build/ccs/precompile.bat" # Выбирает публичную точку входа общей зависимости из JSON.
if not script.is_file(): raise FileNotFoundError(script) # Отсутствие templates останавливает шаг до изменения счётчика.
if settings.get("increment_version", False): # Проект включает автоматический итератор явным флагом в JSON.
settings["version"] = next_version(settings["version"]) # Получает следующий номер без отдельного C-заголовка.
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", newline="\n", dir=config.parent, prefix=".firmware-version-", delete=False) as stream: # Создаёт UTF-8 файл на том же диске для атомарной замены настроек.
temporary = Path(stream.name) # Запоминает только собственный временный файл для очистки при отказе.
try: stream.write(json.dumps(settings, ensure_ascii=False, indent=2) + "\n") # Сохраняет все поля проекта вместе с новым номером версии.
except BaseException: stream.close(); temporary.unlink(); raise # При ошибке записи сохраняет исходный JSON и удаляет незавершённый файл.
try: temporary.replace(config) # Фиксирует занятый номер до запуска генератора и компилятора.
finally: temporary.unlink(missing_ok=True) # Не оставляет временный файл при отказе замены конфигурации.
output = build_dir / "generated" # Каждая конфигурация CCS получает отдельные заголовок и метаданные.
subprocess.run(["cmd.exe", "/d", "/c", "call", str(script), "--identity", str(config.parent), str(config), str(output)], check=True) # Общий precompile создаёт заголовок, UTC и Git-метаданные; ошибка останавливает сборку.
subprocess.run(["cmd.exe", "/d", "/c", "call", str(script), "--identity", str(config.parent), str(config), str(output)], check=True) # Общий precompile сам увеличивает версию при increment_version=true и создаёт единый паспорт для компиляции; ошибка останавливает сборку.
return json.loads((output / "firmware_identity.json").read_text(encoding="utf-8")) # Возвращает фактический паспорт без повторного вычисления времени или Build ID.
+1 -1
View File
@@ -4,7 +4,7 @@
"version": [
1,
0,
4
5
],
"increment_version": true,
"templates": "../../newProject/templates",