task run show a window. Empty, but at least a window.

This commit is contained in:
Thomas Güttler
2026-04-17 22:20:10 +02:00
parent 6621f434fa
commit f0d3d9e6a2
11 changed files with 41 additions and 204 deletions
+7 -3
View File
@@ -19,15 +19,19 @@
## Running
Flutter build dependencies (libgtk-3-dev, libepoxy-dev, libsecret-1-dev, etc.) are installed via apt — see the Flutter Linux docs. The nix dev shell provides only tools: `task`, `fvm`, `stalwart-mail`.
Enter the nix dev shell first: `nix develop`
```bash
# Code generation (must run after schema changes)
dart run build_runner build --delete-conflicting-outputs
task codegen
# Desktop
flutter run -d linux
task run
# Tests
flutter test
task test
```
## Adding a screen
+19 -35
View File
@@ -18,14 +18,23 @@ tasks:
run: once
deps: [_nix-check]
cmds:
- cmd: command -v flutter >/dev/null 2>&1 || fvm install
- cmd: fvm install --skip-pub-get
_pub-get:
internal: true
run: once
deps: [_flutter-check]
cmds:
- flutter pub get --suppress-analytics 2>/dev/null
- fvm flutter pub get --suppress-analytics
_linux-deps-check:
internal: true
run: once
preconditions:
- sh: command -v clang >/dev/null 2>&1
msg: "Linux desktop deps missing. Run: sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev libstdc++-12-dev"
- sh: pkg-config --exists gtk+-3.0 2>/dev/null
msg: "Linux desktop deps missing. Run: sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev libstdc++-12-dev"
install-hooks:
desc: Install pre-commit hooks (requires pre-commit; see .pre-commit-config.yaml)
@@ -36,7 +45,7 @@ tasks:
desc: Generate Drift DB code (run after any schema change)
deps: [_nix-check, _pub-get]
cmds:
- flutter pub run build_runner build --delete-conflicting-outputs
- fvm flutter pub run build_runner build --delete-conflicting-outputs
analyze:
desc: Static analysis (flutter analyze)
@@ -48,7 +57,7 @@ tasks:
desc: Auto-fix lint issues with dart fix --apply
deps: [_nix-check]
cmds:
- dart fix --apply
- fvm dart fix --apply
test:
desc: Unit tests + coverage gate (fails if any non-excluded lib/ file is missing)
@@ -66,7 +75,7 @@ tasks:
desc: Full Flutter test suite (unit + widget + integration)
deps: [_nix-check]
cmds:
- flutter test
- fvm flutter test
integration:
desc: Integration tests against a local Stalwart mail server
@@ -74,48 +83,23 @@ tasks:
cmds:
- stalwart-dev/test.sh
_check-libsecret:
internal: true
cmds:
- |
if pkg-config --exists libsecret-1; then
exit 0
elif dpkg -s libsecret-1-dev >/dev/null 2>&1; then
echo "Error: libsecret-1-dev is installed but pkg-config cannot find it."
echo "Your nix shell was opened before the package was installed."
echo "Fix: exit the nix shell and re-enter with: nix develop"
else
echo "Error: libsecret-1-dev is not installed."
echo "Fix: sudo apt install libsecret-1-dev"
fi
exit 1
build-linux:
desc: Build the Linux desktop app (debug)
deps: [_nix-check, _pub-get, _check-libsecret]
deps: [_nix-check, _linux-deps-check, _pub-get]
cmds:
- flutter build linux --debug --no-pub
- |
binary=build/linux/x64/debug/bundle/sharedinbox
missing=$(LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/lib/x86_64-linux-gnu ldd "$binary" 2>/dev/null | grep 'not found' || true)
if [ -n "$missing" ]; then
echo "Error: built binary has unresolvable runtime dependencies:"
echo "$missing"
echo "Fix: sudo apt install libsecret-1-0"
exit 1
fi
- fvm flutter build linux --debug --no-pub
build-android:
desc: Build a release APK (output in build/app/outputs/flutter-apk/)
deps: [_nix-check, _pub-get]
cmds:
- flutter build apk --release --no-pub
- fvm flutter build apk --release --no-pub
run:
desc: Run the app on Linux desktop
deps: [_nix-check, _pub-get]
deps: [_nix-check, _linux-deps-check, _pub-get]
cmds:
- flutter run -d linux --no-pub
- fvm flutter run -d linux --no-pub
check:
desc: All fast checks — analyze + unit tests + widget tests + build-linux + integration in parallel
Generated
+1 -79
View File
@@ -1,49 +1,5 @@
{
"nodes": {
"android-nixpkgs": {
"inputs": {
"devshell": "devshell",
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1776286015,
"narHash": "sha256-Is4Efj9Jzdy+vo0xoS7ak5i6yYPhviYsRG9ZijzkAXE=",
"owner": "tadfisher",
"repo": "android-nixpkgs",
"rev": "d2793eb50d8fd8e9ad2937cfeafa8e87f08480d8",
"type": "github"
},
"original": {
"owner": "tadfisher",
"ref": "stable",
"repo": "android-nixpkgs",
"type": "github"
}
},
"devshell": {
"inputs": {
"nixpkgs": [
"android-nixpkgs",
"nixpkgs"
]
},
"locked": {
"lastModified": 1768818222,
"narHash": "sha256-460jc0+CZfyaO8+w8JNtlClB2n4ui1RbHfPTLkpwhU8=",
"owner": "numtide",
"repo": "devshell",
"rev": "255a2b1725a20d060f566e4755dbf571bbbb5f76",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
@@ -62,24 +18,6 @@
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1776221942,
@@ -98,8 +36,7 @@
},
"root": {
"inputs": {
"android-nixpkgs": "android-nixpkgs",
"flake-utils": "flake-utils_2",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
@@ -117,21 +54,6 @@
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
+6 -61
View File
@@ -3,63 +3,25 @@
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
android-nixpkgs = {
url = "github:tadfisher/android-nixpkgs/stable";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, android-nixpkgs, flake-utils }:
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
config.android_sdk.accept_license = true;
};
androidSdk = android-nixpkgs.sdk.${system} (s: with s; [
cmdline-tools-latest
build-tools-35-0-0
platform-tools
platforms-android-36
platforms-android-35
emulator
]);
pkgs = import nixpkgs { inherit system; };
in {
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
# Android
androidSdk
# Linux desktop build deps (Flutter GTK backend)
pkg-config
cmake
ninja
clang
gtk3
glib
pcre2
libepoxy
at-spi2-atk
at-spi2-core
# libsecret intentionally omitted from Nix inputs: the binary-cache
# build of libgpg-error (a transitive dep) requires GLIBC_2.42 which
# is absent on non-NixOS hosts (nixpkgs issue, glibc 2.40 vs 2.42).
# Use the system package instead:
# sudo apt install libsecret-1-dev
# Local IMAP/SMTP dev server for integration tests
stalwart-mail
# Task runner
go-task
# Flutter version manager (fvm install downloads the pinned Flutter SDK)
# Flutter version manager — needed for host builds (task build-linux, task run)
fvm
# Local IMAP/SMTP dev server for integration tests
stalwart-mail
# Utilities
git
curl
@@ -69,23 +31,6 @@
];
shellHook = ''
export ANDROID_HOME="${androidSdk}/share/android-sdk"
export ANDROID_SDK_ROOT="$ANDROID_HOME"
export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/cmdline-tools/latest/bin:$PATH"
# flutter_secure_storage_linux needs libsecret-1 via pkg-config.
# We use the system package (sudo apt install libsecret-1-dev) because
# the Nix binary-cache build of libgpg-error (a transitive dep) requires
# GLIBC_2.42 which is absent in this closure's glibc 2.40.
export PKG_CONFIG_PATH="/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:''${PKG_CONFIG_PATH:-}"
# Nix sets TMPDIR/TMP/TEMP to a per-shell dir that is removed when the
# shell exits. Flutter refuses to start if that dir no longer exists
# (https://github.com/flutter/flutter/issues/74042). Reset to /tmp.
export TMPDIR=/tmp
export TMP=/tmp
export TEMP=/tmp
# Disable Flutter telemetry inside dev shell
export FLUTTER_SUPPRESS_ANALYTICS=true
-9
View File
@@ -6,7 +6,6 @@ set(APPLICATION_ID "de.sharedinbox.sharedinbox")
cmake_policy(SET CMP0063 NEW)
# Load bundled libraries from the lib/ directory relative to the binary.
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
# Build mode defaults.
@@ -50,14 +49,6 @@ target_compile_definitions(${BINARY_NAME} PRIVATE FLUTTER_VERSION_PATCH=${FLUTTE
target_compile_definitions(${BINARY_NAME} PRIVATE FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD})
target_link_libraries(${BINARY_NAME} PRIVATE flutter PkgConfig::GTK)
# nixos-25.11 packages are compiled against glibc 2.42 from the Nix toolchain.
# On non-NixOS hosts with an older glibc (e.g. 2.40) the static linker cannot
# resolve versioned symbols such as __inet_pton_chk@GLIBC_2.42 that live in
# Nix-built transitive dependencies (libgpg-error → libsecret →
# flutter_secure_storage_linux). Those .so files carry their own RPATH to the
# Nix glibc, so the symbols ARE present at runtime — the link-time check is a
# false alarm. --allow-shlib-undefined suppresses it.
target_link_options(${BINARY_NAME} PRIVATE -Wl,--allow-shlib-undefined)
add_dependencies(${BINARY_NAME} flutter_assemble)
+1 -1
View File
@@ -26,7 +26,7 @@ dependencies:
go_router: ^14.8.1
# Secure credential storage (passwords)
flutter_secure_storage: ^9.2.4
flutter_secure_storage: ^10.0.0
# Date formatting
intl: any
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
START=$(date +%s)
flutter analyze --no-pub
fvm flutter analyze --no-pub
END=$(date +%s)
echo "analyze: $((END - START))s"
+2 -2
View File
@@ -3,7 +3,7 @@ set -euo pipefail
START=$(date +%s)
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
if flutter test test/unit/ test/widget/ --coverage --no-pub --reporter expanded >"$tmp" 2>&1; then
if fvm flutter test test/unit/ test/widget/ --coverage --no-pub --reporter expanded >"$tmp" 2>&1; then
# Success: show only the summary line
grep -E "^All [0-9]+ tests passed" "$tmp" || tail -1 "$tmp"
else
@@ -11,6 +11,6 @@ else
cat "$tmp"
exit 1
fi
dart run scripts/check_coverage.dart
fvm dart run scripts/check_coverage.dart
END=$(date +%s)
echo "test: $((END - START))s"
+1 -1
View File
@@ -3,7 +3,7 @@ set -euo pipefail
START=$(date +%s)
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
if flutter test test/widget/ --no-pub --reporter expanded >"$tmp" 2>&1; then
if fvm flutter test test/widget/ --no-pub --reporter expanded >"$tmp" 2>&1; then
grep -E "^All [0-9]+ tests passed" "$tmp" || tail -1 "$tmp"
else
cat "$tmp"
+3 -2
View File
@@ -9,7 +9,8 @@ export STALWART_PASS_B="${STALWART_PASS_B:-secret}"
export STALWART_USER_C="${STALWART_USER_C:-bob}"
export STALWART_PASS_C="${STALWART_PASS_C:-secret}"
export STALWART_RANDOM_PORTS=1
export STALWART_TMPDIR="$(mktemp -d /tmp/stalwart-dev-XXXXXX)"
STALWART_TMPDIR="$(mktemp -d /tmp/stalwart-dev-XXXXXX)"
export STALWART_TMPDIR
command -v stalwart >/dev/null || {
echo "stalwart not in PATH — run inside nix develop"
@@ -60,6 +61,6 @@ export STALWART_IMAP_HOST="127.0.0.1"
export STALWART_SMTP_HOST="127.0.0.1"
START=$(date +%s)
flutter test test/integration/
fvm flutter test test/integration/
END=$(date +%s)
echo "integration: $((END - START))s"
-10
View File
@@ -1,21 +1,11 @@
import 'dart:ffi';
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:sqlite3/open.dart';
import 'package:sharedinbox/data/db/database.dart';
/// Call once per test file (e.g. in setUpAll) before creating any AppDatabase.
void configureSqliteForTests() {
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
if (Platform.isLinux) {
open.overrideFor(
OperatingSystem.linux,
() => DynamicLibrary.open('/usr/lib/x86_64-linux-gnu/libsqlite3.so.0'),
);
}
}
AppDatabase openTestDatabase() => AppDatabase(NativeDatabase.memory());