# 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