From d7c8ed2a4305ef909e7ba4a334562a057305fb5b Mon Sep 17 00:00:00 2001 From: Thomas SharedInbox Date: Thu, 4 Jun 2026 12:53:18 +0200 Subject: [PATCH] feat: run local Dart tasks via Dagger, eliminating local SDK dependency Adds CheckFast, Analyze, FormatWrite, Codegen, and AnalyzeFix Dagger functions to ci/main.go. Updates format, codegen, analyze, analyze-fix, and check-fast Taskfile tasks to run via Dagger and export changed files back to the host with -o .. Updates the dart-check pre-commit hook to call check-fast through Dagger instead of scripts/pre_commit_check.sh. Closes #417 Co-Authored-By: Claude Sonnet 4.6 --- .pre-commit-config.yaml | 2 +- Taskfile.yml | 40 ++++++++------------------ ci/main.go | 62 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 30 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0c0a29a..3f09fbd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: dart-check name: dart format (autofix) + check-fast (parallel) language: system - entry: bash -c 'cd "$(git rev-parse --show-toplevel)" && nix develop --command scripts/pre_commit_check.sh' + entry: bash -c 'cd "$(git rev-parse --show-toplevel)" && nix develop --command dagger call --progress=plain -q -m ci --source=. check-fast' pass_filenames: false always_run: true - id: ci-no-direct-dagger diff --git a/Taskfile.yml b/Taskfile.yml index c444883..1e90bde 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -96,34 +96,19 @@ tasks: - scripts/silent_on_success.sh fvm flutter pub run build_runner build --delete-conflicting-outputs codegen: - desc: Generate Drift DB code (run after any schema change) - deps: [_preflight, _pub-get] - sources: - - lib/**/*.dart - - pubspec.yaml - generates: - - lib/**/*.g.dart + desc: Generate Drift DB code via Dagger (exports generated files back to host) cmds: - - fvm flutter pub run build_runner build --delete-conflicting-outputs + - dagger call --progress=plain -q -m ci --source=. codegen -o . analyze: - desc: Static analysis (flutter analyze) - deps: [_preflight, _codegen] - sources: - - lib/**/*.dart - - test/**/*.dart - - pubspec.yaml - - analysis_options.yaml + desc: Static analysis via Dagger (dart analyze --fatal-infos) cmds: - - scripts/run_analyze.sh + - dagger call --progress=plain -q -m ci --source=. analyze format: - desc: Format all Dart source files - deps: [_preflight] - sources: - - "**/*.dart" + desc: Format all Dart source files via Dagger (writes back to host) cmds: - - fvm dart format lib test + - dagger call --progress=plain -q -m ci --source=. format-write -o . check-mocks: desc: Fail if any *.mocks.dart file is out of date (re-runs build_runner) @@ -136,13 +121,9 @@ tasks: - scripts/check_mocks_fresh.sh analyze-fix: - desc: Auto-fix lint issues with dart fix --apply - deps: [_preflight] - sources: - - lib/**/*.dart - - test/**/*.dart + desc: Auto-fix lint issues via Dagger (dart fix --apply, writes back to host) cmds: - - fvm dart fix --apply + - dagger call --progress=plain -q -m ci --source=. analyze-fix -o . test: desc: Unit tests + coverage gate (fails if any non-excluded lib/ file is missing) @@ -672,8 +653,9 @@ tasks: ${SSH_USER}@${SSH_HOST}:public_html/ check-fast: - desc: Pre-commit checks — analyze + unit+widget tests + coverage gate (no build, no integration) - deps: [analyze, check-coverage, check-hygiene, check-layers, check-mocks] + desc: Pre-commit checks via Dagger (format, analyze, mocks, coverage — no integration or backend) + cmds: + - dagger call --progress=plain -q -m ci --source=. check-fast check-layers: desc: Enforce architecture — ui/ must not import data/ (only core/ interfaces allowed) diff --git a/ci/main.go b/ci/main.go index 4aa3e7f..c53da04 100644 --- a/ci/main.go +++ b/ci/main.go @@ -422,6 +422,68 @@ func (m *Ci) Format(ctx context.Context) (string, error) { Stdout(ctx) } +// FormatWrite formats Dart files and exports the modified /src directory. +func (m *Ci) FormatWrite() *dagger.Directory { + return m.setup(m.checkSrc()). + WithExec([]string{"dart", "format", "lib", "test"}). + Directory("/src") +} + +// Analyze runs static analysis with dart analyze --fatal-infos. +func (m *Ci) Analyze(ctx context.Context) (string, error) { + return m.setup(m.checkSrc()). + WithExec([]string{"dart", "analyze", "--fatal-infos"}). + Stdout(ctx) +} + +// Codegen runs build_runner and exports the modified /src directory. +func (m *Ci) Codegen() *dagger.Directory { + return m.codegenBase().Directory("/src") +} + +// AnalyzeFix runs dart fix --apply and exports the modified /src directory. +func (m *Ci) AnalyzeFix() *dagger.Directory { + return m.setup(m.checkSrc()). + WithExec([]string{"dart", "fix", "--apply"}). + Directory("/src") +} + +// CheckFast runs fast checks (hygiene, layers, format, analyze, mocks, coverage) in parallel. +func (m *Ci) CheckFast(ctx context.Context) (string, error) { + ctx, cancel := context.WithTimeout(ctx, 15*time.Minute) + defer cancel() + + var eg errgroup.Group + eg.Go(func() error { + _, err := m.CheckHygiene(ctx) + return err + }) + eg.Go(func() error { + _, err := m.CheckLayers(ctx) + return err + }) + eg.Go(func() error { + _, err := m.Format(ctx) + return err + }) + eg.Go(func() error { + _, err := m.Analyze(ctx) + return err + }) + eg.Go(func() error { + _, err := m.CheckMocks(ctx) + return err + }) + eg.Go(func() error { + _, err := m.Coverage(ctx) + return err + }) + if err := eg.Wait(); err != nil { + return "", err + } + return "All fast checks passed!", nil +} + // CheckMocks verifies that generated mocks are up to date. // It snapshots the committed source (including any stale *.mocks.dart) before // running build_runner, so git diff detects real staleness instead of always