Pre-commit hooks that wrap common Flutter / Dart CLI commands through FVM, so every contributor uses the project-pinned Flutter SDK.
id |
Runs | Purpose |
|---|---|---|
check-fvm |
fvm doctor |
Fails fast if FVM is not installed / not configured. |
fvm-format |
fvm dart format |
Formats staged Dart files. |
fvm-analyze |
fvm dart analyze |
Runs the Dart analyzer once over the whole scope. |
As of v1.3.0, fvm-analyze is invoked with pass_filenames: false and
require_serial: true. This means pre-commit runs it exactly once, as a
single process, over a stable scope — it no longer appends the staged
file list and no longer fans the analyzer out across your CPUs.
Why: dart analyze <files> still builds the entire package's analysis context
before reporting, so passing staged files gave almost no speedup while missing
breakage in unstaged dependents. Worse, pre-commit's default
(require_serial: false) partitioned the staged files into chunks and ran the
analyzer concurrently (up to os.cpu_count()), loading N × the whole-app
analyzer into memory — the "memory leak"-like spike large monorepos hit.
The entry also switched from fvm flutter analyze to fvm dart analyze, which
skips the flutter_tools boot cost while honouring the same
analysis_options.yaml and analysis-server plugin lints. If you need
Flutter-specific analysis parity with CI, override the entry back to
fvm flutter analyze in your own fork — the single-process/memory fix is
independent of this choice.
Because filenames are no longer passed, provide the analyzer's scope and flags
via args: (e.g. a package path and/or --no-fatal-infos). With no args, it
analyzes the current directory.
For big repos, run fvm-analyze on pre-push rather than pre-commit, so
the (single, whole-scope) analysis happens once before you push instead of on
every commit. Keep fvm-format on pre-commit — dart format is syntactic and
cheap, and per-file parallelism there is fine.
- repo: https://github.com/motrieux-thomas/fvm-pre-commit
rev: v1.3.0
hooks:
- id: check-fvm
- id: fvm-format
- id: fvm-analyze
stages: [pre-push]
args: [--no-fatal-infos] # optionally add a package path, e.g. lib/Register the pre-push stage once with:
pre-commit install --install-hooks
pre-commit install --hook-type pre-pushAdd the following to your .pre-commit-config.yaml:
- repo: https://github.com/motrieux-thomas/fvm-pre-commit
rev: v1.3.0
hooks:
- id: check-fvm
- id: fvm-format
- id: fvm-analyzeBoth fvm-format and fvm-analyze forward any arguments you provide via
pre-commit's args: directly to the underlying fvm dart format /
fvm dart analyze invocation. Quoting is preserved, so paths with spaces
work correctly. For fvm-analyze, args: is the only way to set scope
(files are not passed automatically).
- repo: https://github.com/motrieux-thomas/fvm-pre-commit
rev: v1.3.0
hooks:
- id: fvm-analyze
args: [--no-fatal-infos, lib/, test/]--no-fatal-infos keeps info-level diagnostics visible in the output
without failing the hook — handy while migrating a codebase to a stricter
lint set. Despite being the
documented default, it is often still
required in practice; see
flutter/flutter#20855
for context.
- repo: https://github.com/motrieux-thomas/fvm-pre-commit
rev: v1.3.0
hooks:
- id: fvm-format
args: [--set-exit-if-changed]--set-exit-if-changed makes the hook exit non-zero if any file would be
rewritten, instead of silently formatting in place. Useful in CI to enforce
"already formatted" as a hard gate.
MIT — see LICENSE.