timetracker/Makefile
2026-08-03 21:51:48 +02:00

289 lines
12 KiB
Makefile

# Timetrack — Build & Run Commands
# Flutter cross-platform build automation
.PHONY: help install generate test test_coverage analyze format clean \
build_serve build_android build_aab build_linux build_web build_all \
install_android deploy_android serve_apk serve_web \
build_and_serve_apk build_and_serve_web \
db_schema
# ── Toolchain paths ────────────────────────────────────────────────────────────
FLUTTER := $(HOME)/flutter/3.41.7/bin/flutter
JAVA_HOME ?= $(HOME)/java/17.0.13+11
ANDROID_HOME ?= $(HOME)/Android/sdk
ADB := $(ANDROID_HOME)/platform-tools/adb
# ── Versionierung ──────────────────────────────────────────────────────────────
# Werte werden aus der VERSION-Datei gelesen und nach jedem Build automatisch
# hochgezählt. Manuell überschreibbar:
# make build_android BUILD_VERSION=0.2.0 BUILD_NUMBER=5
#
# TODO: Sobald das Projekt in Git liegt, BUILD_NUMBER durch git-Commits ersetzen:
# BUILD_NUMBER = $(shell git rev-list --count HEAD)
VERSION_FILE := VERSION
BUILD_VERSION ?= $(shell grep '^VERSION=' $(VERSION_FILE) | cut -d= -f2)
BUILD_NUMBER ?= $(shell grep '^BUILD_NUMBER=' $(VERSION_FILE) | cut -d= -f2)
# ── APK-Pfade ─────────────────────────────────────────────────────────────────
APK_NAME := timetrack-$(BUILD_VERSION)+$(BUILD_NUMBER).apk
APK_DIR := build/apk
APK := $(APK_DIR)/$(APK_NAME)
APK_LATEST := $(APK_DIR)/timetrack.apk
# ── Serve-Binary ──────────────────────────────────────────────────────────────
SERVE_BIN := scripts/serve/serve
PORT ?= 8888
WEB_PORT ?= 8080
# ── Default target ─────────────────────────────────────────────────────────────
help:
@echo "Timetrack — Build Commands"
@echo "=========================="
@echo ""
@echo "Dev-Targets:"
@echo " make install - flutter pub get"
@echo " make generate - build_runner (Codegenerierung)"
@echo " make test - Flutter Tests ausführen"
@echo " make test_coverage - Tests mit Coverage-Report"
@echo " make analyze - flutter analyze"
@echo " make format - Dart-Code formatieren"
@echo " make clean - Build-Artefakte löschen"
@echo ""
@echo "Build-Targets:"
@echo " make build_serve - Go APK-Server kompilieren"
@echo " make build_android - Android APK (release)"
@echo " make build_aab - Android App Bundle (Play Store)"
@echo " make build_linux - Linux Desktop-App"
@echo " make build_web - Web-App"
@echo " make build_all - APK + Linux + Web"
@echo ""
@echo "Deploy-Targets:"
@echo " make install_android - APK via ADB auf Gerät installieren"
@echo " make deploy_android - build_android + install_android"
@echo " make serve_apk - APK per WLAN bereitstellen + QR-Code"
@echo " make serve_web - Web-App per WLAN bereitstellen + QR-Code"
@echo " make build_and_serve_apk - build_android + serve_apk"
@echo " make build_and_serve_web - build_web + serve_web"
@echo ""
@echo "Info-Targets:"
@echo " make db_schema - Drift-Schema-Version und Tabellen anzeigen"
@echo ""
@echo "Variablen (Beispiel):"
@echo " BUILD_VERSION=0.2.0 BUILD_NUMBER=5 make build_android"
@echo " PORT=9090 make serve_apk"
@echo " WEB_PORT=9091 make serve_web"
@echo " DEVICE=emulator-5554 make install_android"
# ── Dev-Targets ───────────────────────────────────────────────────────────────
install:
@echo "Installing dependencies..."
$(FLUTTER) pub get
@echo "Done."
generate:
@echo "Running code generation..."
$(FLUTTER) pub run build_runner build --delete-conflicting-outputs
@echo "Code generation complete."
test:
@echo "Running tests..."
$(FLUTTER) test
@echo "Tests complete."
test_coverage:
@echo "Running tests with coverage..."
$(FLUTTER) test --coverage
@if command -v genhtml > /dev/null 2>&1; then \
genhtml coverage/lcov.info -o coverage/html --quiet; \
echo "Coverage report: coverage/html/index.html"; \
else \
echo "Hinweis: genhtml nicht gefunden. lcov installieren für HTML-Report:"; \
echo " sudo apt install lcov"; \
echo "Rohes lcov-Ergebnis: coverage/lcov.info"; \
fi
analyze:
@echo "Running static analysis..."
$(FLUTTER) analyze
@echo "Analysis complete."
format:
@echo "Formatting code..."
$(FLUTTER) pub run dart_style:format --fix lib/ test/
@echo "Format complete."
clean:
@echo "Cleaning build artifacts..."
$(FLUTTER) clean
rm -rf coverage/
@echo "Clean complete."
# ── Build: Go Server ──────────────────────────────────────────────────────────
build_serve: $(SERVE_BIN)
# Auto-Build: Binary wird nur neu gebaut wenn main.go neuer als Binary ist
$(SERVE_BIN): scripts/serve/main.go
@echo "Building serve binary..."
@command -v go > /dev/null 2>&1 || \
(echo "FEHLER: go nicht gefunden. Bitte installieren: https://go.dev/dl/" && exit 1)
cd scripts/serve && go build -o serve .
@echo "Server binary: scripts/serve/serve"
# ── Build: Android APK ────────────────────────────────────────────────────────
build_android:
@echo "Building Timetrack Android APK..."
@echo " Version : $(BUILD_VERSION)+$(BUILD_NUMBER)"
@echo ""
@# Voraussetzungen prüfen
@test -d "$(JAVA_HOME)" || \
(echo "FEHLER: JAVA_HOME='$(JAVA_HOME)' nicht gefunden." && \
echo " Überschreiben: JAVA_HOME=/pfad/zu/jdk make build_android" && exit 1)
@test -d "$(ANDROID_HOME)" || \
(echo "FEHLER: ANDROID_HOME='$(ANDROID_HOME)' nicht gefunden." && \
echo " Überschreiben: ANDROID_HOME=/pfad/zum/sdk make build_android" && exit 1)
@# Flutter APK bauen
JAVA_HOME="$(JAVA_HOME)" ANDROID_HOME="$(ANDROID_HOME)" \
$(FLUTTER) build apk --release \
--build-name=$(BUILD_VERSION) \
--build-number=$(BUILD_NUMBER)
@# APK in build/apk/ ablegen
@mkdir -p $(APK_DIR)
cp build/app/outputs/flutter-apk/app-release.apk $(APK)
@# SHA256-Prüfsumme
sha256sum $(APK) | tee $(APK).sha256
@# Symlink auf neueste Version aktualisieren
@cd $(APK_DIR) && ln -sf $(APK_NAME) timetrack.apk
@# Build-Number in VERSION-Datei hochzählen
@next=$$(( $(BUILD_NUMBER) + 1 )); \
sed -i "s/^BUILD_NUMBER=.*/BUILD_NUMBER=$$next/" $(VERSION_FILE); \
echo " Nächste Build-Number: $$next (in $(VERSION_FILE) gespeichert)"
@# Retention-Bereinigung
@bash scripts/apk_retention.sh --dir $(APK_DIR) --keep 15
@echo ""
@echo "APK fertig:"
@find $(APK_DIR) -name "$(APK_NAME)" -type f
@echo ""
@echo "Auf Gerät installieren: make install_android"
@echo "WLAN-Download starten: make serve_apk"
# ── Build: Android App Bundle (Play Store) ───────────────────────────────────
build_aab:
@echo "Building Timetrack Android App Bundle (AAB)..."
@echo " Version : $(BUILD_VERSION)+$(BUILD_NUMBER)"
@test -d "$(JAVA_HOME)" || \
(echo "FEHLER: JAVA_HOME='$(JAVA_HOME)' nicht gefunden." && exit 1)
@test -d "$(ANDROID_HOME)" || \
(echo "FEHLER: ANDROID_HOME='$(ANDROID_HOME)' nicht gefunden." && exit 1)
JAVA_HOME="$(JAVA_HOME)" ANDROID_HOME="$(ANDROID_HOME)" \
$(FLUTTER) build appbundle --release \
--build-name=$(BUILD_VERSION) \
--build-number=$(BUILD_NUMBER)
@echo ""
@echo "AAB fertig:"
@find build/app/outputs/bundle -name "*.aab" -type f
@echo ""
@echo "Nächste Schritte:"
@echo " 1. AAB signieren (Keystore konfigurieren)"
@echo " 2. In Play Console hochladen: Testen → Internes Testen → Upload"
# ── Build: Linux Desktop ──────────────────────────────────────────────────────
build_linux:
@which ld.lld > /dev/null 2>&1 || \
(echo "" && \
echo "FEHLER: ld.lld (LLVM-Linker) nicht gefunden." && \
echo "Bitte installieren mit:" && \
echo " sudo apt install lld" && \
echo "" && exit 1)
@echo "Building Timetrack Linux app..."
$(FLUTTER) build linux --release \
--build-name=$(BUILD_VERSION) \
--build-number=$(BUILD_NUMBER)
@echo ""
@echo "Linux build fertig:"
@find build/linux -maxdepth 4 -name "timetrack" -type f 2>/dev/null || \
find build/linux -maxdepth 4 -name "*.elf" -type f 2>/dev/null || true
@echo ""
@echo "Starten: ./build/linux/x64/release/bundle/timetrack"
# ── Build: Web ────────────────────────────────────────────────────────────────
build_web:
@echo "Building Timetrack Web app..."
$(FLUTTER) build web --release
@echo ""
@echo "Web build fertig: build/web/"
@echo "WLAN-Zugriff starten: make serve_web"
# ── Build: Alle Plattformen ───────────────────────────────────────────────────
build_all: build_android build_linux build_web
@echo ""
@echo "Alle Builds abgeschlossen:"
@echo " APK : $(APK)"
@echo " Linux : build/linux/x64/release/bundle/timetrack"
@echo " Web : build/web/"
# ── Deploy: Android ───────────────────────────────────────────────────────────
install_android:
@echo "Suche verbundene Android-Geräte..."
@$(ADB) devices | grep -v "List of" | grep "device$$" > /dev/null || \
(echo "FEHLER: Kein Gerät gefunden. USB-Kabel und USB-Debugging prüfen." && exit 1)
@test -f "$(APK_LATEST)" || test -f "$(APK)" || \
(echo "FEHLER: APK nicht gefunden. Zuerst 'make build_android' ausführen." && exit 1)
@APK_TO_INSTALL="$(APK_LATEST)"; \
test -f "$$APK_TO_INSTALL" || APK_TO_INSTALL="$(APK)"; \
echo "Installiere $$APK_TO_INSTALL..."; \
if [ -n "$(DEVICE)" ]; then \
$(ADB) -s $(DEVICE) install -r "$$APK_TO_INSTALL"; \
else \
$(ADB) install -r "$$APK_TO_INSTALL"; \
fi
@echo ""
@echo "Installation abgeschlossen."
deploy_android: build_android install_android
# ── Serve + Build: Kombinierte Targets ───────────────────────────────────────
build_and_serve_apk: build_android serve_apk
build_and_serve_web: build_web serve_web
# ── Serve: WLAN APK-Download ──────────────────────────────────────────────────
serve_apk: $(SERVE_BIN)
@test -d "$(APK_DIR)" || \
(echo "FEHLER: $(APK_DIR)/ nicht gefunden. Zuerst 'make build_android' ausführen." && exit 1)
$(SERVE_BIN) --dir $(APK_DIR) --port $(PORT)
# ── Serve: WLAN Web ───────────────────────────────────────────────────────────
serve_web: $(SERVE_BIN)
@test -d "build/web" || \
(echo "FEHLER: build/web/ nicht gefunden. Zuerst 'make build_web' ausführen." && exit 1)
$(SERVE_BIN) --web --dir build/web --port $(WEB_PORT)
# ── Info: Drift-Schema ────────────────────────────────────────────────────────
db_schema:
@echo "Timetrack — Drift Schema"
@echo "========================"
@echo ""
@echo "Schema-Version:"
@grep -h "schemaVersion" lib/core/database/app_database.dart 2>/dev/null | \
grep -v "//" | sed 's/^[[:space:]]*/ /'
@echo ""
@echo "Tabellen:"
@grep -h "class.*extends Table" lib/core/database/tables/*.dart 2>/dev/null | \
sed 's/class \([A-Za-z]*\) extends Table.*/ \1/' | sort
@echo ""
@echo "DAOs:"
@grep -h "class.*Dao" lib/core/database/daos/*.dart 2>/dev/null | \
grep "class.*DatabaseAccessor" | \
sed 's/class \([A-Za-z]*\) extends.*/ \1/' | sort