# Руководство разработчика Сборка, запуск без железа, тесты и соглашения проекта. **Аудитория:** разработчики. ## Содержание - [Окружение](#окружение) - [Порядок сборки](#порядок-сборки) - [Цели Makefile](#цели-makefile) - [Сборка deb-пакета](#сборка-deb-пакета) - [Запуск без железа (эмуляция)](#запуск-без-железа-эмуляция) - [Тесты](#тесты) - [Соглашения](#соглашения) ## Окружение - **Go 1.21+** — модуль `gpio-monitor`, **внешних Go-зависимостей нет** (только стандартная библиотека, см. [go.mod](../go.mod)); - **Node.js 20+ и npm** — только для компиляции TypeScript (единственная dev-зависимость — `typescript`); - `make`, `git`; для deb-пакета — `dpkg-deb`; опционально `golangci-lint` для `make lint`. Подготовка после клонирования: ```bash make init # проверит Node.js, скачает Go-модули и npm-пакеты ``` ## Порядок сборки **Критичный нюанс:** сервер встраивает веб-файлы через `go:embed web/dist ...` ([cmd/server/main.go:28](../cmd/server/main.go)). Каталог `dist/` генерируется компилятором TypeScript и в git не хранится, поэтому **на чистом checkout `go build` упадёт с ошибкой embed**. Всегда собирайте фронтенд первым: ```bash make build # = build-frontend (tsc) + build-backend (go build) ``` По умолчанию бинарник собирается кросс-компиляцией под **linux/arm64** (Raspberry Pi) в `build/gpio-monitor-server`. Для локальной платформы используйте `make build-amd64` / `build-mac` / `build-windows` или `make dev`. Есть также исторический скрипт [build.sh](../build.sh) — делает то же, что `make build`, но с захардкоженным путём проекта `~/temp/golang`; предпочитайте Makefile. ## Цели Makefile Справка встроена: `make help`. Основные цели ([Makefile](../Makefile)): | Цель | Что делает | |---|---| | `init` | Проверка Node.js/npm + установка всех зависимостей | | `build` | Полная сборка: фронтенд + бекенд (GOOS/GOARCH переопределяемы) | | `build-frontend` | `npm install` (при отсутствии node_modules) + `npm run build` (tsc) | | `build-backend` | `go build -ldflags="-s -w"` в `build/` | | `run` | Сборка + запуск бинарника | | `dev` | `go run ./cmd/server -port :8080` без оптимизаций (dist уже должен существовать) | | `test` | `go test -v ./...` | | `fmt` | `go fmt ./...` | | `lint` | `golangci-lint run ./...` (если установлен) | | `clean` | Удаляет `build/`, `web/dist`, `web/node_modules`, временные deb-файлы | | `build-arm64` / `build-amd64` / `build-mac` / `build-windows` / `build-all` | Кросс-сборки | | `install` / `uninstall` | Копирование бинарника в `/usr/local/bin` | | `deb` / `deb-info` / `deb-contents` / `deb-clean` / `version` | Работа с deb-пакетом (ниже) | > Цели `docker-build`/`docker-run` объявлены, но Dockerfile в репозитории отсутствует — они нерабочие ([tech-debt.md](tech-debt.md#сборка-и-инфраструктура)). ## Сборка deb-пакета ```bash make deb # от обычного пользователя, без sudo make version # показать вычисленную версию и имя файла make deb-info # информация о собранном пакете (dpkg-deb -I) make deb-contents # список файлов пакета (dpkg-deb -c) make deb-clean # очистка временных файлов сборки пакета ``` **Версионирование через git:** версия пакета = `<база>-build`, где база берётся из `Version:` в [debian/control](../debian/control) (сейчас `1.0.0`), а `N` = `git rev-list --count HEAD` (число коммитов). Итоговый файл: `build/gpio-monitor-server_1.0.0-build_arm64.deb`. Каждый коммит автоматически увеличивает номер сборки. `make deb` выполняет `clean → build-frontend → build-backend → prepare-debian → dpkg-deb --build`. В пакет попадают: бинарник, веб-файлы (копия для справки — сервер использует встроенные), unit systemd, конфиг, утилита `gpio-logs`, maintainer-скрипты из [debian/](../debian/). Что происходит при установке — в [operations.md](operations.md#установка-из-deb-пакета). ## Запуск без железа (эмуляция) FIFO и поток данных можно смоделировать на любой Linux-машине: ```bash mkfifo /tmp/gpio_pipe python3 scripts/emulator.py scripts/array.txt /tmp/gpio_pipe # генератор данных make dev # сервер (в другом терминале) ``` Вспомогательные скрипты [scripts/](../scripts/): | Скрипт | Назначение | |---|---| | `emulator.py` | Эмулятор капчера: читает массив байт из файла (формат `[0xE0, 0x01, ...]`) и пишет их в pipe/stdout с заданной задержкой, с переподключением и повтором | | `array.txt` | Пример массива данных для эмулятора | | `imi_wire.py` | Имитатор параллельной шины на **реальных GPIO** (gpiod, Raspberry Pi 4): выставляет байт на пины данных и дёргает строб WR — для теста настоящего `gpio-interrupt` | | `emulatohackrf.sh` | Связка эмулятора с передатчиком HackRF (`hackrf-frame64-tx`): передача байтов GPIO по радиоканалу | | `vu_meter.py` | Консольный VU-метр микрофона (sounddevice/numpy) — независимая проверка аудиотракта | | `view_logs.sh` | Сводная статистика dev-логов (`~/.local/share/gpio-monitoring/logs`) | Пути внутри `emulatohackrf.sh` и systemd-юнитов захардкожены под конкретное устройство (`/home/user/...`) — правьте под своё окружение. ## Тесты ```bash make test # go test -v ./... ``` Сейчас тестами покрыт только retention: [internal/logger/retention_test.go](../internal/logger/retention_test.go) (очистка по возрасту/размеру, minKeepFiles, устойчивость к скачку часов и битым именам). Остальные пакеты тестов не имеют — см. [tech-debt.md](tech-debt.md#тесты-и-ci). CI в репозитории нет — прогоняйте `make test` и `go vet ./...` перед коммитом вручную. ## Соглашения - **Язык** — русский: комментарии, логи, сообщения об ошибках, документация. - **Конфигурация** — только CLI-флаги (без env-переменных и конфиг-файлов); новые параметры добавляются флагом в `main()` и полем в `logger.Config`. - **Зависимости** — Go-код держится на стандартной библиотеке; прежде чем добавить стороннюю зависимость, убедитесь, что она действительно необходима. - **Структура**: `cmd/server` — точка входа и HTTP-слой; `internal/adapter` — буфер; `internal/pipe` — приём данных; `internal/logger` — хранение/события; `internal/audio` — микрофон. Фронтенд — [frontend.md](frontend.md). - **Целевая платформа** — linux/arm64; сборка и на других платформах должна оставаться рабочей (кросс-цели Makefile). - Форматы данных и API описаны в [data-formats.md](data-formats.md) и [api.md](api.md) — при изменении кода обновляйте эти документы.