feat: run local Dart tasks via Dagger (#417) (#418)

## Summary

- 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 delegate to Dagger and export modified files back to the host (\`-o .\`)
- Updates the \`dart-check\` pre-commit hook to run \`dagger call ... check-fast\` instead of \`scripts/pre_commit_check.sh\`

These tasks no longer require a local Dart/Flutter SDK installation — Dagger pulls the toolchain image and runs everything in a container.

## New Dagger functions

| Function | Returns | What it does |
|---|---|---|
| \`CheckFast(ctx)\` | \`string\` | Runs CheckHygiene, CheckLayers, Format, Analyze, CheckMocks, Coverage in parallel |
| \`Analyze(ctx)\` | \`string\` | \`dart analyze --fatal-infos\` |
| \`FormatWrite()\` | \`*dagger.Directory\` | \`dart format lib test\` — writes files, returns \`/src\` |
| \`Codegen()\` | \`*dagger.Directory\` | \`flutter pub run build_runner build\` — returns \`/src\` with generated files |
| \`AnalyzeFix()\` | \`*dagger.Directory\` | \`dart fix --apply\` — writes files, returns \`/src\` |

## Test plan

- [ ] \`task format\` — runs Dagger, exports formatted files back to \`.\`
- [ ] \`task codegen\` — runs Dagger, exports generated \`.g.dart\` files back to \`.\`
- [ ] \`task analyze\` — runs Dagger, prints analysis output
- [ ] \`task analyze-fix\` — runs Dagger, exports fixed files back to \`.\`
- [ ] \`task check-fast\` — runs all fast checks in parallel via Dagger
- [ ] Pre-commit hook triggers \`dagger call ... check-fast\` on commit

Closes #417

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Thomas SharedInbox <sharedinbox@thomas-guettler.de>
Co-authored-by: guettli <guettli@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/guettli/sharedinbox/pulls/418
This commit was merged in pull request #418.
This commit is contained in:
Bot of Thomas Güttler
2026-06-05 11:50:49 +02:00
committed by guettli
co-authored by guettli Thomas SharedInbox
parent 8718339b4e
commit cca0e5d461
3 changed files with 74 additions and 30 deletions
+62
View File
@@ -440,6 +440,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.CheckGenerated(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
}
// CheckGenerated verifies that all generated files (*.g.dart, *.mocks.dart) are up to date.
// It snapshots the committed source (including any stale generated files) before
// running build_runner, so git diff detects real staleness instead of always