fix: stop verify, reports and briefs from claiming more than pipe checked #1

Merged
trevon merged 12 commits from fix/verify-soundness-and-injection into main 2026-09-22 18:24:06 +00:00
2 changed files with 58 additions and 5 deletions
Showing only changes of commit d6b6bcb438 - Show all commits

fix(analysis): report an unreadable SDK cleanly instead of crashing
Some checks failed
Lint Commits / commitlint (pull_request) Successful in 17s
Tests / Static Analysis (pull_request) Has been cancelled
Tests / Tests (pull_request) Has been cancelled

ae412a7 routed filesystem failures to exit 2, but the analyzer throws its own
FileSystemException (package:analyzer/file_system), which the dart:io catch
in bin/pipe.dart never matched. A project whose package_config still named a
moved Flutter SDK therefore crashed with exit 255 and a stack trace. Found
by dogfooding on word_alive after its SDK moved.

Analyzer.create now turns that into a PipeException naming the SDK path, with
the remedy to re-run flutter pub get or pass --sdk.
trvon 2026-09-22 12:11:33 -06:00
Signed by: trevon
GPG key ID: 38686EA797D7A8A7

View file

@ -5,8 +5,10 @@ import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/results.dart'; import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart'; import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/file_system/file_system.dart' as fs;
import 'package:analyzer/file_system/physical_file_system.dart'; import 'package:analyzer/file_system/physical_file_system.dart';
import 'errors.dart';
import 'project.dart'; import 'project.dart';
import 'sdk.dart'; import 'sdk.dart';
@ -127,11 +129,25 @@ class Analyzer {
explicit: sdkOverride, explicit: sdkOverride,
flutterRootHint: project.flutterRoot, flutterRootHint: project.flutterRoot,
); );
final collection = AnalysisContextCollection( final AnalysisContextCollection collection;
includedPaths: [project.root], try {
resourceProvider: PhysicalResourceProvider.INSTANCE, collection = AnalysisContextCollection(
sdkPath: resolution.sdkPath, includedPaths: [project.root],
); resourceProvider: PhysicalResourceProvider.INSTANCE,
sdkPath: resolution.sdkPath,
);
} on fs.FileSystemException catch (error) {
// The analyzer throws its own FileSystemException, not dart:io's, so the
// catch in bin/pipe.dart does not see it. The usual cause is a project
// whose package_config still names a Flutter SDK that has moved.
throw PipeException(
'cannot read the Dart SDK at ${resolution.sdkPath}: ${error.message} '
'(${error.path})',
remedy:
'run `flutter pub get` in the project so its package_config '
'names the current SDK, or pass --sdk <dart-sdk-path>',
);
}
return Analyzer._(collection, resolution); return Analyzer._(collection, resolution);
} }

View file

@ -0,0 +1,37 @@
import 'dart:io';
import 'package:pipe/src/cli.dart';
import 'package:pipe/src/errors.dart';
import 'package:test/test.dart';
void main() {
test(
'an SDK the analyzer cannot read is a clean error, not a crash',
() async {
// A project whose package_config names a Flutter SDK that has since moved
// left the analyzer unable to read the SDK's allowed_experiments.json. The
// analyzer throws its own FileSystemException, which bin/pipe.dart's
// dart:io catch never saw: exit 255 and a stack trace.
final sdk = Directory.systemTemp.createTempSync('pipe-hollow-sdk');
addTearDown(() => sdk.deleteSync(recursive: true));
File('${sdk.path}/version').writeAsStringSync('3.13.0\n');
Directory('${sdk.path}/lib').createSync();
await expectLater(
PipeRunner().run([
'check',
'test/fixtures/stuck_loading',
'--sdk',
sdk.path,
]),
throwsA(
isA<PipeException>().having(
(error) => error.remedy,
'remedy',
contains('flutter pub get'),
),
),
);
},
);
}