fix: cap dart_style below 3.1.10 so generated code matches dart format (v2.8.1) - #51
Merged
Merged
Conversation
The generated `*.reflection.g.dart` is formatted by `DartFormatter`, using
the `dart_style` that `pub` resolves for *this* package, while consumers
check that code with the `dart format` bundled in *their* Dart SDK.
`dart_style` 3.1.10 changed the splitting of an argument list containing a
collection literal — exactly the shape of the generated proxy code:
onCall(this, 'mapKeys', <String, dynamic>{
'map': map,
}, const __TR<Future<List<String>>>(Future, <__TR>[__TR.tListString]))
The Dart SDK 3.12.2 still bundles `dart_style` 3.1.6 (`dart format
--version`), which splits that instead. So a package generating with
3.1.10+ gets generated code that its own `dart format` wants to rewrite,
making 2 common CI checks mutually exclusive: committing the generator
output fails `dart format --set-exit-if-changed`, and committing the
formatted output fails a `build_verify` check, since `build_runner`
rewrites the file back. Hit in `bones_api`.
`>=3.1.9 <3.1.10` is the narrowest range that still satisfies
`analyzer: ^13.0.0` — 3.1.9 is the first `dart_style` accepting analyzer
13 — so nothing else is rolled back.
NOT a language-version bug: the builder already resolves and passes the
correct language version to `DartFormatter` (verified: it logs 3.7.0 for a
3.7 package, single call site). The divergence reproduces identically at
language versions 3.7, 3.10, 3.11 and 3.12, so raising a consumer's SDK
constraint does not avoid it.
Tests: `reflection_factory_format_test.dart` guards both directions —
the committed `*.g.dart` are untouched by the SDK's `dart format`, and
`DartFormatter` agrees with the SDK's `dart format` on the generated-proxy
shape. The second test is the one that catches this: the repository's own
generated code happens not to contain a diverging shape, so it passed on
3.1.12 while `bones_api` broke.
Lift the bound once the Dart SDK bundles `dart_style` >= 3.1.10.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #51 +/- ##
=======================================
Coverage 89.51% 89.51%
=======================================
Files 14 14
Lines 6398 6398
=======================================
Hits 5727 5727
Misses 671 671
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
gmpassos
added a commit
to Colossus-Services/bones_api
that referenced
this pull request
Aug 1, 2026
`^2.7.5` let CI's `dart pub upgrade` resolve 2.8.0, whose bundled `dart_style` 3.1.12 formats the generated code differently from the `dart format` of the Dart SDK (3.1.6), breaking `ensure_build_test`. reflection_factory 2.8.1 caps `dart_style` below 3.1.10 (gmpassos/reflection_factory#51), so the generated code is byte-identical to what the SDK's `dart format` wants again. Requiring `^2.8.1` -- and not `^2.7.5` -- also keeps consumers of the released bones_api off the broken 2.8.0. The regenerated files only change the builder version stamp (2.7.5 -> 2.8.1); there is no formatting change. Verified: `dart format --set-exit-if-changed` 0 changed, `dart analyze --fatal-infos --fatal-warnings` clean, `ensure_build_test` green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The generated
*.reflection.g.dartis formatted byDartFormatter, using thedart_stylethat pub resolves for this package, while consumers check that same code with thedart formatbundled in their Dart SDK.Those two are not the same version, and
dart_styledoes not guarantee identical output across its own versions.dart_style3.1.6 (dart format --version→3.1.6)dart_style: ^3.1.9→ pub resolves 3.1.12dart_style3.1.10 changed the splitting of an argument list containing a collection literalThat shape is exactly the generated proxy code:
Why it breaks consumers
It makes two ordinary CI checks mutually exclusive:
dart format --set-exit-if-changedbuild_verify(build is up to date)dart formatoutputbuild_runnerrewrites it backHit in
bones_api, where CI'sdart pub upgradepicked up 2.8.0 and thetest_vmjob started failing onensure_build_test.Fix
dart_style: ^3.1.9→'>=3.1.9 <3.1.10'This is the narrowest range that still satisfies
analyzer: ^13.0.0— 3.1.9 is the firstdart_stylethat accepts analyzer 13 — so nothing else is rolled back (analyzer stays at 13.3.0).What this is not
Not a language-version bug. The builder already resolves and passes the correct language version to
DartFormatter:reflection_factory_builder.dart:301→codeTable.resolveLanguageVersion(), single_writeGeneratedCodecall site, so the?? DartFormatter.latestLanguageVersionfallback is not reachedResolved languageVersion: 3.7.0for every generated fileAnd raising the consumer's SDK constraint does not avoid it. Regenerating a real package's
*.g.dartwith dart_style 3.1.12 at each language version:sdk:lower bounddart format>=3.7.0>=3.10.0>=3.11.0>=3.12.0Tests
New
test/reflection_factory_format_test.dart, taggedbuild:*.g.dartare left untouched by the SDK'sdart format.DartFormatteragrees with the SDK'sdart formaton an argument list containing a collection literal — the generated-proxy shape — formatted at this package's own language version.Test 2 is the one that actually catches this. Test 1 alone is not sufficient: this repository's own generated code happens not to contain a diverging shape, so it passes even on
dart_style3.1.12 while a downstream package with a proxy breaks. Verified by running both against 3.1.12 — only test 2 fails, with:Full suite: 272 tests pass;
dart formatanddart analyze --fatal-infos --fatal-warningsclean.Follow-up
Lift the upper bound once the Dart SDK bundles
dart_style>= 3.1.10 — at that point test 2 keeps the two aligned automatically.🤖 Generated with Claude Code