# Refactoring: service-tui directory changed

This commit is contained in:
Dmitry Akimov 2026-07-07 18:37:26 +03:00
parent 8869b3cb6d
commit 6aaea215e1
47 changed files with 60 additions and 60 deletions

2
.gitignore vendored
View file

@ -77,4 +77,4 @@ tools/host/.venv-host/
tools/host/.venv-host-win/
.zed/
project_tree.txt
tools/production/dist/
tools/service_tui/dist/

View file

@ -9,12 +9,12 @@
`firmware_test` (C, i.MX RT1052, версия `0.1.2` из
`firmware/test/CMakeLists.txt`) и `service-tui` (Python/Textual, версия
`0.2.0` из `tools/production/pyproject.toml`) — независимо версионируемые
`0.2.0` из `tools/service_tui/pyproject.toml`) — независимо версионируемые
проекты, но релиз одного без другого бесполезен сервисному инженеру:
`service-tui` — это инструмент, которым он *прошивает* плату диагностической
прошивкой, и HAB-образ `firmware_test` кладётся внутрь бандла TUI как
`firmware/<Type>/firmware_test_hab.bin` (см. `just host::package-tui`,
`tools/production/docs/DEV_ARCH.md` §14). Поэтому релиз собирается как один
`tools/service_tui/docs/DEV_ARCH.md` §14). Поэтому релиз собирается как один
комплект, даже если версии независимые.
Известное ограничение (задокументировано в `README.md`/`DEV_ARCH.md`):
@ -34,7 +34,7 @@ GitHub имеет смысл положить оба HAB-образа отдел
| `firmware_test` | Собирается, HAB-образ генерируется (`just build::hab-firmware-test-{debug,release}`), Release нестабилен |
| `service-tui` | v0.2.0, PyInstaller onedir, alpha-бандлы уже вручную собраны и прогнаны на живом железе macOS+Windows (коммиты `c694258`/`bfe4dd6`) |
| `service_tui.spec` | **Устарел относительно того, чем реально собраны протестированные alpha-бандлы** — не содержит `datas` для `spsdk`, `dcd/*.bin`, `pyproject.toml` (задокументировано в `DEV_ARCH.md` §14 и `CHANGELOG.md`「Известные ограничения」) |
| `tools/production/dist/service-tui-v0.2.0-{macos,windows}/` | Закоммичены в git (906 файлов, ~96 МБ суммарно) и **устарели относительно HEAD** — собраны до коммитов `2dbe3e6`/`22c4077`/`31e3237` (фиксы моков тестов, рефакторинг докстрингов) |
| `tools/service_tui/dist/service-tui-v0.2.0-{macos,windows}/` | Закоммичены в git (906 файлов, ~96 МБ суммарно) и **устарели относительно HEAD** — собраны до коммитов `2dbe3e6`/`22c4077`/`31e3237` (фиксы моков тестов, рефакторинг докстрингов) |
| CI (`.github/workflows/ci.yml`) | Только `build`+`test` в devcontainer на `ubuntu-latest`; не собирает `service-tui`, нет macOS/Windows раннеров, нет release-пайплайна, нет тегов в репозитории |
| `just/ci.just` | Есть рецепт `release` (→ `just build::hab-all-release`) — только firmware, ничего про упаковку TUI или публикацию на GitHub |
| Ветки | `feature-tui-monolith` на 15 коммитов впереди `dev`, ещё не смёржена; в репозитории также есть `main` — политика, какая ветка режет релизы, явно не зафиксирована |
@ -47,19 +47,19 @@ GitHub имеет смысл положить оба HAB-образа отдел
провалидировано на железе, — а «релиз, который не воспроизводим из
исходников» хуже отсутствия релиза.
1. **Актуализировать `tools/production/service_tui.spec`** — добавить
1. **Актуализировать `tools/service_tui/service_tui.spec`** — добавить
`collect_data_files("spsdk")` (+ `SPSDK_DATA_FOLDER` если понадобится),
`collect_dynamic_libs("libusbsio")`, `datas` для
`tools/host/dcd/{dcd.bin,w25q128_fdcb.bin,w25q512_fdcb.bin,ivt_flashloader.bin}`
и `pyproject.toml`. Ориентир — реальное содержимое уже собранных
alpha-бандлов в `dist/` (их можно инспектировать перед удалением из git,
см. следующий пункт).
2. **Убрать `tools/production/dist/` из git**: `git rm -r --cached
tools/production/dist` + добавить `tools/production/dist/` в
2. **Убрать `tools/service_tui/dist/` из git**: `git rm -r --cached
tools/service_tui/dist` + добавить `tools/service_tui/dist/` в
`.gitignore`. Собранные бандлы — это build-артефакты, их место в GitHub
Release assets или CI-артефактах, не в истории репозитория.
3. **(Дёшево, но не блокирует)** Убрать мёртвую зависимость `pyusb` из
`tools/production/pyproject.toml` — детект давно переведён на
`tools/service_tui/pyproject.toml` — детект давно переведён на
`spsdk`/`serial.tools.list_ports` (Р7), ни один модуль `app/` её не
импортирует.
4. **Пересобрать бандлы локально** с исправленным spec из актуального HEAD
@ -88,10 +88,10 @@ GitHub имеет смысл положить оба HAB-образа отдел
`flasher._resolve_custom_binaries_dir()` смотрит именно внутрь (рядом с
исполняемым файлом); теперь `custom_binaries/` создаётся в правильном
месте и сразу наполняется `TFT_BOOTLOADER_NEW.bin`/`TFT_BOOTLOADER_OLD.bin`
из `tools/production/custom_binaries/`.
из `tools/service_tui/custom_binaries/`.
**TODO (отложено, не забыть перед шагом 2):** актуализировать
`tools/production/README.md` и `tools/production/docs/DEV_ARCH.md` §14 —
`tools/service_tui/README.md` и `tools/service_tui/docs/DEV_ARCH.md` §14 —
они всё ещё описывают старое поведение (в частности, блок «Расхождение
spec/факт» в DEV_ARCH.md §14 уже неактуален, spec восстановлен и
ужесточён). Сознательно отложено до ручной валидации сборки на
@ -137,7 +137,7 @@ GitHub имеет смысл положить оба HAB-образа отдел
| Job | Раннер | Что делает |
| --- | --- | --- |
| `firmware` | `ubuntu-latest` (тот же devcontainer-подход, что в `ci.yml`) | `just ci::release``hab-all-release` (по факту нужен только `firmware_test`, Debug+Release); выгрузить `firmware_test_hab.bin` (оба типа) как артефакт |
| `service-tui-macos` | `macos-latest` | скачать firmware-артефакт из job `firmware`; `uv sync` в `tools/production`; `just host::package-tui`; заархивировать `dist/service-tui-vX.Y.Z-macos/` |
| `service-tui-macos` | `macos-latest` | скачать firmware-артефакт из job `firmware`; `uv sync` в `tools/service_tui`; `just host::package-tui`; заархивировать `dist/service-tui-vX.Y.Z-macos/` |
| `service-tui-windows` | `windows-latest` | то же самое, PowerShell-совместимые команды (`just`/`uv` доступны на Windows) |
| `publish-release` | `ubuntu-latest`, `needs: [firmware, service-tui-macos, service-tui-windows]` | скачать все артефакты, создать GitHub Release через `gh release create` / `softprops/action-gh-release@v2`, прикрепить `firmware_test_hab.bin` (Debug, + Release с пометкой experimental, если решение по шагу 1.5 — «класть оба»), `service-tui-vX.Y.Z-macos.zip`, `service-tui-vX.Y.Z-windows.zip` |
@ -165,7 +165,7 @@ GitHub имеет смысл положить оба HAB-образа отдел
5: детект SDP → прошивка `firmware_test` → диагностика на обеих ОС.
Цель — убедиться, что CI-сборка не разошлась с уже провалидированной
локальной.
2. Обновить `tools/production/README.md`/корневой `README.md` — ссылка на
2. Обновить `tools/service_tui/README.md`/корневой `README.md` — ссылка на
релиз/инструкция «откуда скачать сервисному инженеру».
## Шаг 5 — Публикация

View file

@ -21,7 +21,7 @@
| Инструмент | Путь | Назначение |
| ------------------ | ------------------- | -------------------------------------------------------------------------------------------------------------- |
| Сервисный TUI | `tools/production/` | Диагностика и прошивка готовых плат сервисным инженером (Textual, standalone-бинарь). [README](tools/production/README.md) |
| Сервисный TUI | `tools/service_tui/` | Диагностика и прошивка готовых плат сервисным инженером (Textual, standalone-бинарь). [README](tools/service_tui/README.md) |
| Прошивка (dev-CLI) | `tools/host/` | USB SDP / SWD прошивка при разработке (`sdphost`/`blhost`/`nxpimage`/`pyOCD`). [README](tools/host/README.md) |
| HIL-тесты | `tools/hil/` | pytest-окружение аппаратных тестов (pyOCD + M5StampPLC). [README](tools/hil/README.md) |
@ -76,7 +76,7 @@ just host::debug-server # GDB-сервер для отладки
| Unity, fff, SEGGER RTT | vendored |
| pyOCD, pyserial, pytest, mpremote | `tools/hil/uv.lock` |
| spsdk (nxpimage, blhost, sdphost — dev-CLI) | `tools/host/uv.lock` |
| spsdk (McuBoot/SDP/HabImage — прямой Python API), Textual | `tools/production/uv.lock` |
| spsdk (McuBoot/SDP/HabImage — прямой Python API), Textual | `tools/service_tui/uv.lock` |
Всё что не меняется — vendored. Сборка работает после `git clone` без интернета
(кроме Python-зависимостей).

View file

@ -20,7 +20,7 @@ COM-порт (`/dev/ttyACM*` на Linux/macOS, `COMx` на Windows). Испол
PHY калибровка: `D_CAL=0x0C`, `TXCAL45DP=0x06`, `TXCAL45DM=0x06`.
**VID/PID**: `0x1996` / `0x00AD` (`usb_device_descriptor.h`) — тот же
идентификатор, что `tools/production/` (service-tui) использует для
идентификатор, что `tools/service_tui/` (service-tui) использует для
детекта CDC-порта firmware_test (`SERVICE_CDC_VID`/`SERVICE_CDC_PID`).
---

View file

@ -200,7 +200,7 @@ flowchart LR
│ │
│ ├── production/ ← service-tui: TUI сервисного инженера (Textual)
│ │ прошивка/диагностика готовых плат, см.
│ │ tools/production/README.md + DEV_ARCH.md
│ │ tools/service_tui/README.md + DEV_ARCH.md
│ │
│ └── hil/ ← HIL pytest-окружение
│ ├── conftest.py ← фикстуры: m5, loaded_<n>, uart_<n>

View file

@ -79,7 +79,7 @@ auto-config не подтверждена — см. 1.5.
### 1.5 Нестандартная память (W25Q256/512) и сторонние бинарники
`service-tui` (`tools/production/`) умеет прошивать бинарники, собранные не
`service-tui` (`tools/service_tui/`) умеет прошивать бинарники, собранные не
в этом репозитории (например, старые платы с W25Q512), тем же способом
(USB SDP), но с двумя отличиями от штатного пути. Это **отдельная
реализация**, не связанная с `flash_usb.py`/`nxpimage` CLI — TUI прошивает
@ -93,7 +93,7 @@ in-process через Python API `spsdk` (`app/flash_backend.py`: `HabImage`,
`configure-memory 0xF000000F`) — auto-config для 4-байтной адресации не
проверялся, решили на него не полагаться
Подробности конвейера — в [tools/production/docs/DEV_ARCH.md](../tools/production/docs/DEV_ARCH.md),
Подробности конвейера — в [tools/service_tui/docs/DEV_ARCH.md](../tools/service_tui/docs/DEV_ARCH.md),
§8. Штатный путь (`--firmware`, три сборки этого репозитория, что через
`just host::flash`, что через `service-tui`) не меняется и по-прежнему
использует auto-config Flashloader, как описано в 1.4.

View file

@ -538,21 +538,21 @@ production: flash-production
# ГРУППА: service — TUI сервисного инженера
# =============================================================================
PRODUCTION_DIR := justfile_directory() / 'tools/production'
SERVICE_TUI_DIR := justfile_directory() / 'tools/service_tui'
[doc('Установить/обновить зависимости TUI сервисного инженера')]
[group('service')]
service-setup:
#!/usr/bin/env bash
set -euo pipefail
echo " 📦 Syncing tools/production deps..."
cd "{{ PRODUCTION_DIR }}" && uv sync
echo " ✅ tools/production deps installed"
echo " 📦 Syncing tools/service_tui deps..."
cd "{{ SERVICE_TUI_DIR }}" && uv sync
echo " ✅ tools/service_tui deps installed"
[doc('Запустить TUI сервисного инженера')]
[group('service')]
service-tui:
uv run --directory {{ PRODUCTION_DIR }} python main.py
uv run --directory {{ SERVICE_TUI_DIR }} python main.py
[doc('Собрать standalone-бинарь TUI (PyInstaller → dist/service_tui)')]
[group('service')]
@ -560,7 +560,7 @@ service-build:
#!/usr/bin/env bash
set -euo pipefail
echo " 🔨 Building standalone service-tui..."
cd "{{ PRODUCTION_DIR }}" && uv run pyinstaller \
cd "{{ SERVICE_TUI_DIR }}" && uv run pyinstaller \
--onefile \
--name service_tui \
--add-data "../shared:shared" \
@ -571,7 +571,7 @@ service-build:
# ГРУППА: package — сборка service-tui в исполняемый бандл (PyInstaller)
# =============================================================================
_prod_dir := justfile_directory() / 'tools/production'
_service_dir := justfile_directory() / 'tools/service_tui'
_prod_build_dir := env('BUILD_DIR', justfile_directory() / 'build')
[doc('Собрать service-tui в PyInstaller-бандл + скопировать firmware/*_hab.bin')]
@ -580,7 +580,7 @@ package-tui:
#!/usr/bin/env bash
set -euo pipefail
cd "{{ _prod_dir }}"
cd "{{ _service_dir }}"
echo " 📦 Running PyInstaller..."
uv run pyinstaller service_tui.spec --noconfirm
@ -618,8 +618,8 @@ package-tui:
mkdir -p "dist/${RELEASE_NAME}"
mv "$DIST" "dist/${RELEASE_NAME}/"
echo " 📦 Seeding custom_binaries/ from tools/production/custom_binaries/..."
echo " 📦 Seeding custom_binaries/ from tools/service_tui/custom_binaries/..."
mkdir -p "dist/${RELEASE_NAME}/service_tui/custom_binaries"
cp "{{ _prod_dir }}/custom_binaries/"*.bin "dist/${RELEASE_NAME}/service_tui/custom_binaries/"
cp "{{ _service_dir }}/custom_binaries/"*.bin "dist/${RELEASE_NAME}/service_tui/custom_binaries/"
echo " ✅ dist/${RELEASE_NAME}"

View file

@ -13,11 +13,11 @@ Python-окружение на базе [uv](https://docs.astral.sh/uv/) для
tools/host/
├── flash_usb.py — прошивка через USB ROM: sdphost → Flashloader → Flash
│ (+ --bin-path/--fcb-path — сторонние образы с явным
│ FCB, вызывается из service-tui, см. tools/production/)
│ FCB, вызывается из service-tui, см. tools/service_tui/)
├── flash_swd.py — прошивка через SWD: FCB + HAB → pyOCD → Flash
├── hab/ — HAB yaml-конфиги для nxpimage (по одному на проект × тип;
│ service-tui генерирует такие же временно, на лету —
│ см. tools/production/DEV_ARCH.md, §8)
│ см. tools/service_tui/DEV_ARCH.md, §8)
├── dcd/
│ ├── ivt_flashloader.bin — NXP Flashloader (загружается в RAM через SDP)
│ ├── dcd.bin — DCD: инициализация SDRAM (SEMC + MT48LC16M16A2P)
@ -32,7 +32,7 @@ tools/host/
> Все бинарники в `dcd/` получены из NXP SecureProvisioningTool и хранятся
> в репозитории — пересоздавать не нужно. `w25q128`/`w25q512` — единственные
> два варианта в реальном использовании (64 и 256 сведены к ним же, см.
> `tools/production/DEV_ARCH.md`, §8.2); `w25q64_fdcb.bin` пока не подключён
> `tools/service_tui/DEV_ARCH.md`, §8.2); `w25q64_fdcb.bin` пока не подключён
> нигде — оставлен про запас.
---
@ -43,8 +43,8 @@ tools/host/
Сравнительная таблица, карта Flash, диагностика — там же.
Прошивка сторонних/легаси бинарников с нестандартной памятью (явный FCB,
без auto-config) — через `service-tui` (`tools/production/`), не напрямую
через `flash_usb.py` из терминала. Детали конвейера — `tools/production/DEV_ARCH.md`, §8.
без auto-config) — через `service-tui` (`tools/service_tui/`), не напрямую
через `flash_usb.py` из терминала. Детали конвейера — `tools/service_tui/DEV_ARCH.md`, §8.
---

View file

@ -255,7 +255,7 @@ FIRMWARE_BUILD_TYPE=Debug
### Из монорепозитория (разработчик)
```bash
just host::service-setup # установить зависимости tools/production/
just host::service-setup # установить зависимости tools/service_tui/
just host::service-tui # запустить TUI
```
@ -263,7 +263,7 @@ just host::service-tui # запустить TUI
```bash
just host::package-tui
# → tools/production/dist/service-tui-vX.Y.Z-<os>/
# → tools/service_tui/dist/service-tui-vX.Y.Z-<os>/
```
Бандл (PyInstaller, onedir) самодостаточен — прошивка идёт напрямую через
@ -298,7 +298,7 @@ flash_usb.py` — независимый dev-CLI для `just host::flash*`, TUI
## Логирование
```bash
tools/production/service_tui.log ← по умолчанию (dev) / рядом с exe (frozen)
tools/service_tui/service_tui.log ← по умолчанию (dev) / рядом с exe (frozen)
$SERVICE_LOG_DIR/service_tui.log ← если задан в .env
```

View file

@ -49,7 +49,7 @@ logger = logging.getLogger(__name__)
ProgressCallback = Callable[[FlashProgress], None]
# ─── Пути ────────────────────────────────────────────────────────────────
# tools/production/app/flash_backend.py → корень репозитория
# tools/service_tui/app/flash_backend.py → корень репозитория
REPO_ROOT = Path(__file__).resolve().parents[3]

View file

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View file

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View file

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View file

@ -1,6 +1,6 @@
# service-tui — техническая архитектура
> Компонент: `tools/production/` — TUI сервисного инженера (диагностика и
> Компонент: `tools/service_tui/` — TUI сервисного инженера (диагностика и
> прошивка платы MIMXRT1052CVJ5B).
> Документ описывает внутреннее устройство: структуру модулей, протокол
> взаимодействия с firmware/M5, экранную архитектуру Textual, известные
@ -13,7 +13,7 @@
## 1. Структура проекта
```bash
tools/production/
tools/service_tui/
├── main.py ← точка входа: логирование (Р12) + ServiceApp().run()
├── pyproject.toml ← зависимости uv (включая spsdk==3.7.0)
├── uv.lock
@ -676,8 +676,8 @@ service-tui-vX.Y.Z-<os>/
| --- | --- | --- |
| `flash_backend._host_dcd_dir()` | `tools/host/dcd/` | `sys._MEIPASS/data` |
| `flash_backend.firmware_hab_path()` | `$BUILD_DIR/<Type>/*_hab.bin` (репо `build/`) | `<exe_dir>/firmware/<Type>/*_hab.bin` |
| `flasher._resolve_custom_binaries_dir()` | `tools/production/custom_binaries/` | `<exe_dir>/custom_binaries/` (override — `SERVICE_CUSTOM_BINARIES_DIR`) |
| `waiting._read_app_version()` | `tools/production/pyproject.toml` | тот же путь — `pyproject.toml` кладётся в `datas` спека (нужен для парсинга версии во frozen) |
| `flasher._resolve_custom_binaries_dir()` | `tools/service_tui/custom_binaries/` | `<exe_dir>/custom_binaries/` (override — `SERVICE_CUSTOM_BINARIES_DIR`) |
| `waiting._read_app_version()` | `tools/service_tui/pyproject.toml` | тот же путь — `pyproject.toml` кладётся в `datas` спека (нужен для парсинга версии во frozen) |
| `main._setup_logging()` | рядом с `main.py` | рядом с исполняемым файлом (`sys.executable.parent`) |
`sys.executable` (не `sys._MEIPASS`) — единственный путь, одинаково
@ -691,7 +691,7 @@ service-tui-vX.Y.Z-<os>/
> **Расхождение spec/факт:** закоммиченный `service_tui.spec` объявляет в
> `datas` только `('../shared', 'shared')` — без `dcd/*.bin`,
> `pyproject.toml` или `spsdk`-данных. Тем не менее уже собранные релизные
> бандлы в `tools/production/dist/service-tui-v0.2.0-{macos,windows}/`
> бандлы в `tools/service_tui/dist/service-tui-v0.2.0-{macos,windows}/`
> фактически содержат `_internal/data/{dcd.bin,*_fdcb.bin,ivt_flashloader.bin}`,
> `_internal/pyproject.toml` и `_internal/spsdk/` — то есть сборки, тестировавшиеся
> на железе (Фаза 5, гейт по macOS/Windows), были собраны с более полным

View file

@ -161,7 +161,7 @@
| Файл | Тип правки |
| --- | --- |
| `tools/production/service_tui.spec` | новый — PyInstaller spec |
| `tools/service_tui/service_tui.spec` | новый — PyInstaller spec |
| `app/screens/waiting.py` | правки: кнопка «Выйти из приложения» (Предложение 2) |
| just-рецепт | новый — имя задачи согласовать, **не изобретаю** |
| `app/app.tcss` | правки при необходимости — стиль кнопки Quit на Waiting |
@ -228,7 +228,7 @@ service-tui-vX.Y.Z-<os>/
| `RELEASE_PLAN.md` | правки: закрыть шаг 3 ссылкой на V4/этот roadmap |
| `docs/DEV_ARCH.md` | правки: §2 (убрать subprocess из диаграммы), §8.3 (новый конвейер) |
| `HOW_TO_FLASH.md` | правки |
| `tools/production/README.md` | правки |
| `tools/service_tui/README.md` | правки |
| `.env.example` | правки: по Р9 (+`SERVICE_M5_VID/PID`, `FIRMWARE_BUILD_TYPE`, `SERVICE_LOG_LEVEL`) |
### Содержание
@ -315,7 +315,7 @@ RT1052, LVGL, SDK HAL, C11, Doxygen, `.clang-tidy`/`.clang-format`,
CMake) написаны под **C/прошивочную** часть монорепо (`firmware_test`).
**Вся работа этого roadmap (4a→4b→5→6) — Python/spsdk/Textual** в
`tools/production`. Поэтому:
`tools/service_tui`. Поэтому:
| Правило | Применимо к Python-работе roadmap? |
| --- | --- |
@ -345,7 +345,7 @@ CMake) написаны под **C/прошивочную** часть моно
## C. Файлы, которые нужно предоставить — по фазам
Пути относительно `tools/production/`, если не указано иное. Пометка
Пути относительно `tools/service_tui/`, если не указано иное. Пометка
**[есть в этом треде]** — файл уже фигурировал и его актуальная версия
известна; в новом треде его всё равно нужно приложить заново.
@ -364,13 +364,13 @@ CMake) написаны под **C/прошивочную** часть моно
| --- | --- |
| `app/main.py` **[правится]** | уровни логгеров + env-переключатель DEBUG (Р12) |
| `app/screens/flash.py` **[правится]** | троттлинг `#flash-log` в `_on_progress` (Р11) |
| `.env` / `.env.example` (`tools/production/`) | согласовать имя `SERVICE_LOG_LEVEL` с существующими переменными |
| `.env` / `.env.example` (`tools/service_tui/`) | согласовать имя `SERVICE_LOG_LEVEL` с существующими переменными |
### Фаза 5 — упаковка PyInstaller + UI
| Файл | Зачем |
| --- | --- |
| `pyproject.toml` (`tools/production/`) | зависимости, версия, `requires-python` — база для spec |
| `pyproject.toml` (`tools/service_tui/`) | зависимости, версия, `requires-python` — база для spec |
| `Justfile` + все `*.just` (корневой и подключаемые: `build.just`, `ci.just`, `host.just`) | **согласовать имя задачи упаковки, НЕ изобретать** — критично по правилу проекта |
| `app/main.py` | entry point для PyInstaller |
| `app/app.py` | `CSS_PATH="app.tcss"` — как резолвится во frozen |
@ -378,7 +378,7 @@ CMake) написаны под **C/прошивочную** часть моно
| `app/screens/waiting.py` **[правится]** | кнопка «Выйти» (Предложение 2) |
| `app/flasher.py`, `app/flash_backend.py` | frozen-резолв путей (`firmware_hab_path`, `_resolve_custom_binaries_dir`) — проверить против структуры бандла |
| дерево `tools/host/dcd/` (список файлов) | что кладём в `datas` (`dcd.bin`, `*_fdcb.bin`, `ivt_flashloader.bin`) |
| `project_tree.txt` или `ls -R tools/production` | реальная структура пакета `app/` для spec |
| `project_tree.txt` или `ls -R tools/service_tui` | реальная структура пакета `app/` для spec |
| существующий `.spec`, если уже есть | не изобретать заново |
### Фаза 6 — документация и релиз
@ -389,7 +389,7 @@ CMake) написаны под **C/прошивочную** часть моно
| `RELEASE_PLAN.md` | закрыть шаг 3 ссылкой на этот roadmap |
| `docs/DEV_ARCH.md` | §2 (диаграмма без subprocess), §8.3 (новый конвейер) |
| `HOW_TO_FLASH.md` | актуализировать под TUI-backend |
| `tools/production/README.md` | ограничение О3, POST-1, разделение dev-CLI / production-TUI |
| `tools/service_tui/README.md` | ограничение О3, POST-1, разделение dev-CLI / production-TUI |
| `.env.example` | по Р9 (+`SERVICE_M5_VID/PID`, `FIRMWARE_BUILD_TYPE`, `SERVICE_LOG_LEVEL`) |
| `app/flash_backend.py`, `app/flasher.py`, `app/screens/flash.py`, `app/models.py` | финальная зачистка комментариев (grep-cleanup Гейта 4) |
| `tools/host/flash_usb.py` | сверка при зачистке — что dev-CLI и правда не тронут (Р2) |
@ -400,13 +400,13 @@ CMake) написаны под **C/прошивочную** часть моно
дробить по фазам. Актуальные (пост-Фаза-4) версии:
```
tools/production/
tools/service_tui/
├── pyproject.toml
├── app/
│ ├── __init__.py
│ ├── app.py
│ ├── app.tcss
│ ├── main.py (точка входа — фактически в tools/production/main.py, см. pyproject scripts)
│ ├── main.py (точка входа — фактически в tools/service_tui/main.py, см. pyproject scripts)
│ ├── models.py
│ ├── flasher.py ← Фаза 2/4, актуальная версия
│ ├── flash_backend.py ← Фаза 1/4, актуальная версия (41 тест)
@ -447,7 +447,7 @@ tools/host/ (dev-CLI, Р2 — НЕ трогается)
> Примечание: `main.py` в `pyproject.toml` прописан как
> `service-tui = "main:main"` — точка входа лежит в
> `tools/production/main.py` (не в `app/`), а `app/app.py` содержит
> `tools/service_tui/main.py` (не в `app/`), а `app/app.py` содержит
> `ServiceApp`. Уточнить фактическое расположение при старте Фазы 4b/5.
## E. Что уже решено и не пересматривается (сводка для нового треда)

View file

@ -17,7 +17,7 @@ service_tui.spec — PyInstaller spec для service-tui (Фаза 5, RELEASE_RO
└── custom_binaries/ создаётся приложением само при первом запуске
(flasher.py::_resolve_custom_binaries_dir), не этим spec
Запуск: uv run --directory tools/production pyinstaller service_tui.spec
Запуск: uv run --directory tools/service_tui pyinstaller service_tui.spec
(все относительные пути ниже считаются от расположения этого файла SPECPATH).
"""
@ -26,8 +26,8 @@ from pathlib import Path
from PyInstaller.utils.hooks import collect_data_files, collect_dynamic_libs
_SPEC_DIR = Path(SPECPATH) # tools/production/ — переменная предоставлена PyInstaller
_REPO_ROOT = _SPEC_DIR.parents[1] # tools/production -> tools -> корень репозитория
_SPEC_DIR = Path(SPECPATH) # tools/service_tui/ — переменная предоставлена PyInstaller
_REPO_ROOT = _SPEC_DIR.parents[1] # tools/service_tui -> tools -> корень репозитория
_DCD_DIR = _REPO_ROOT / "tools" / "host" / "dcd"
# Иконка .exe — только Windows: на macOS без обёртки в BUNDLE() (.app) icon=

View file

@ -40,7 +40,7 @@ from spsdk.mboot import McuBoot, MbootUSBInterface
from spsdk.mboot.properties import PropertyTag
from spsdk.sdp import SDP, SdpUSBInterface
# tools/production/spike/spike_flash.py → корень репозитория
# tools/service_tui/spike/spike_flash.py → корень репозитория
REPO_ROOT = Path(__file__).resolve().parents[3]
FLASHLOADER_BIN = REPO_ROOT / "tools" / "host" / "dcd" / "ivt_flashloader.bin"

View file

@ -55,7 +55,7 @@ import pytest
from spsdk.image.hab.hab_image import HabImage
from spsdk.utils.config import Config
# tools/production/spike/spike_hab.py → корень репозитория
# tools/service_tui/spike/spike_hab.py → корень репозитория
REPO_ROOT = Path(__file__).resolve().parents[3]
REAL_DCD_BIN = REPO_ROOT / "tools" / "host" / "dcd" / "dcd.bin"
@ -108,7 +108,7 @@ def _require_nxpimage() -> str:
path = shutil.which("nxpimage")
if path is None:
raise RuntimeError(
"nxpimage не найден в PATH — активирован ли venv tools/production "
"nxpimage не найден в PATH — активирован ли venv tools/service_tui "
"(spsdk кладёт nxpimage как console_script)?"
)
return path
@ -146,7 +146,7 @@ def _run_golden(work_dir: Path, dcd_bin: Optional[Path]) -> tuple[bytes, bytes]:
# ── pytest: остаётся навсегда как регрессия на апгрейды spsdk (Гейт 0) ──
# Примечание: сейчас лежит в spike/ (временная директория по плану Фазы 0);
# в Фазе 1 у tools/production/ появляется tests/ — тогда этот файл стоит
# в Фазе 1 у tools/service_tui/ появляется tests/ — тогда этот файл стоит
# туда перенести (или вынести тесты в отдельный test_hab_golden.py).