@@ -45,10 +45,10 @@ Future<void> main(List<String> arguments) async {
45
45
dart = path.join (dartSdk, 'bin' , Platform .isWindows ? 'dart.exe' : 'dart' );
46
46
pub = path.join (dartSdk, 'bin' , Platform .isWindows ? 'pub.bat' : 'pub' );
47
47
print ('$clock STARTING ANALYSIS' );
48
- try {
49
- await run (arguments);
50
- } on ExitException catch (error) {
51
- error. apply ();
48
+ await run (arguments);
49
+ if (hasError) {
50
+ print ( '$ clock ${ bold }Test failed.$ reset ' );
51
+ reportErrorsAndExit ();
52
52
}
53
53
print ('$clock ${bold }Analysis successful.$reset ' );
54
54
}
@@ -60,17 +60,20 @@ String? _getDartSdkFromArguments(List<String> arguments) {
60
60
for (int i = 0 ; i < arguments.length; i += 1 ) {
61
61
if (arguments[i] == '--dart-sdk' ) {
62
62
if (result != null ) {
63
- exitWithError (< String > ['The --dart-sdk argument must not be used more than once.' ]);
63
+ foundError (< String > ['The --dart-sdk argument must not be used more than once.' ]);
64
+ return null ;
64
65
}
65
66
if (i + 1 < arguments.length) {
66
67
result = arguments[i + 1 ];
67
68
} else {
68
- exitWithError (< String > ['--dart-sdk must be followed by a path.' ]);
69
+ foundError (< String > ['--dart-sdk must be followed by a path.' ]);
70
+ return null ;
69
71
}
70
72
}
71
73
if (arguments[i].startsWith ('--dart-sdk=' )) {
72
74
if (result != null ) {
73
- exitWithError (< String > ['The --dart-sdk argument must not be used more than once.' ]);
75
+ foundError (< String > ['The --dart-sdk argument must not be used more than once.' ]);
76
+ return null ;
74
77
}
75
78
result = arguments[i].substring ('--dart-sdk=' .length);
76
79
}
@@ -82,7 +85,7 @@ Future<void> run(List<String> arguments) async {
82
85
bool assertsEnabled = false ;
83
86
assert (() { assertsEnabled = true ; return true ; }());
84
87
if (! assertsEnabled) {
85
- exitWithError (< String > ['The analyze.dart script must be run with --enable-asserts.' ]);
88
+ foundError (< String > ['The analyze.dart script must be run with --enable-asserts.' ]);
86
89
}
87
90
88
91
print ('$clock No Double.clamp' );
@@ -268,7 +271,7 @@ Future<void> verifyNoDoubleClamp(String workingDirectory) async {
268
271
}
269
272
}
270
273
if (errors.isNotEmpty) {
271
- exitWithError (< String > [
274
+ foundError (< String > [
272
275
...errors,
273
276
'\n ${bold }See: https://github.com/flutter/flutter/pull/103559' ,
274
277
]);
@@ -315,7 +318,7 @@ Future<void> verifyToolTestsEndInTestDart(String workingDirectory) async {
315
318
violations.add (file.path);
316
319
}
317
320
if (violations.isNotEmpty) {
318
- exitWithError (< String > [
321
+ foundError (< String > [
319
322
'${bold }Found flutter_tools tests that do not end in `_test.dart`; these will not be run by the test runner$reset ' ,
320
323
...violations,
321
324
]);
@@ -354,7 +357,7 @@ Future<void> verifyNoSyncAsyncStar(String workingDirectory, {int minimumMatches
354
357
}
355
358
}
356
359
if (errors.isNotEmpty) {
357
- exitWithError (< String > [
360
+ foundError (< String > [
358
361
'${bold }Do not use sync*/async* methods. See https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#avoid-syncasync for details.$reset ' ,
359
362
...errors,
360
363
]);
@@ -420,7 +423,7 @@ Future<void> verifyGoldenTags(String workingDirectory, { int minimumMatches = 20
420
423
}
421
424
}
422
425
if (errors.isNotEmpty) {
423
- exitWithError (< String > [
426
+ foundError (< String > [
424
427
...errors,
425
428
'${bold }See: https://github.com/flutter/flutter/wiki/Writing-a-golden-file-test-for-package:flutter$reset ' ,
426
429
]);
@@ -529,7 +532,7 @@ Future<void> verifyDeprecations(String workingDirectory, { int minimumMatches =
529
532
}
530
533
// Fail if any errors
531
534
if (errors.isNotEmpty) {
532
- exitWithError (< String > [
535
+ foundError (< String > [
533
536
...errors,
534
537
'${bold }See: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes$reset ' ,
535
538
]);
@@ -561,7 +564,7 @@ Future<void> verifyNoMissingLicense(String workingDirectory, { bool checkMinimum
561
564
failed += await _verifyNoMissingLicenseForExtension (workingDirectory, 'xml' , overrideMinimumMatches ?? 1 , '<!-- ${_generateLicense ('' )} -->' , header: r'(<\?xml version="1.0" encoding="utf-8"\?>\n)?' );
562
565
failed += await _verifyNoMissingLicenseForExtension (workingDirectory, 'frag' , overrideMinimumMatches ?? 1 , _generateLicense ('// ' ), header: r'#version 320 es(\n)+' );
563
566
if (failed > 0 ) {
564
- exitWithError (< String > ['License check failed.' ]);
567
+ foundError (< String > ['License check failed.' ]);
565
568
}
566
569
}
567
570
@@ -670,7 +673,7 @@ Future<void> verifySkipTestComments(String workingDirectory) async {
670
673
671
674
// Fail if any errors
672
675
if (errors.isNotEmpty) {
673
- exitWithError (< String > [
676
+ foundError (< String > [
674
677
...errors,
675
678
'\n ${bold }See: https://github.com/flutter/flutter/wiki/Tree-hygiene#skipped-tests$reset ' ,
676
679
]);
@@ -700,7 +703,7 @@ Future<void> verifyNoTestImports(String workingDirectory) async {
700
703
// Fail if any errors
701
704
if (errors.isNotEmpty) {
702
705
final String s = errors.length == 1 ? '' : 's' ;
703
- exitWithError (< String > [
706
+ foundError (< String > [
704
707
'${bold }The following file$s import a test directly. Test utilities should be in their own file.$reset ' ,
705
708
...errors,
706
709
]);
@@ -769,7 +772,7 @@ Future<void> verifyNoBadImportsInFlutter(String workingDirectory) async {
769
772
}
770
773
// Fail if any errors
771
774
if (errors.isNotEmpty) {
772
- exitWithError (< String > [
775
+ foundError (< String > [
773
776
if (errors.length == 1 )
774
777
'${bold }An error was detected when looking at import dependencies within the Flutter package:$reset '
775
778
else
@@ -789,7 +792,7 @@ Future<void> verifyNoBadImportsInFlutterTools(String workingDirectory) async {
789
792
}
790
793
// Fail if any errors
791
794
if (errors.isNotEmpty) {
792
- exitWithError (< String > [
795
+ foundError (< String > [
793
796
if (errors.length == 1 )
794
797
'${bold }An error was detected when looking at import dependencies within the flutter_tools package:$reset '
795
798
else
@@ -814,7 +817,7 @@ Future<void> verifyIntegrationTestTimeouts(String workingDirectory) async {
814
817
}
815
818
}
816
819
if (errors.isNotEmpty) {
817
- exitWithError (< String > [
820
+ foundError (< String > [
818
821
if (errors.length == 1 )
819
822
'${bold }An error was detected when looking at integration test timeouts:$reset '
820
823
else
@@ -850,7 +853,7 @@ Future<void> verifyInternationalizations(String workingDirectory, String dartExe
850
853
final String expectedCupertinoResult = await File (cupertinoLocalizationsFile).readAsString ();
851
854
852
855
if (materialGenResult.stdout.trim () != expectedMaterialResult.trim ()) {
853
- exitWithError (< String > [
856
+ foundError (< String > [
854
857
'<<<<<<< $materialLocalizationsFile ' ,
855
858
expectedMaterialResult.trim (),
856
859
'=======' ,
@@ -862,7 +865,7 @@ Future<void> verifyInternationalizations(String workingDirectory, String dartExe
862
865
]);
863
866
}
864
867
if (cupertinoGenResult.stdout.trim () != expectedCupertinoResult.trim ()) {
865
- exitWithError (< String > [
868
+ foundError (< String > [
866
869
'<<<<<<< $cupertinoLocalizationsFile ' ,
867
870
expectedCupertinoResult.trim (),
868
871
'=======' ,
@@ -893,7 +896,7 @@ Future<void> verifyNoCheckedMode(String workingDirectory) async {
893
896
}
894
897
}
895
898
if (problems.isNotEmpty) {
896
- exitWithError (problems);
899
+ foundError (problems);
897
900
}
898
901
}
899
902
@@ -947,7 +950,7 @@ Future<void> verifyNoRuntimeTypeInToString(String workingDirectory) async {
947
950
}
948
951
}
949
952
if (problems.isNotEmpty) {
950
- exitWithError (problems);
953
+ foundError (problems);
951
954
}
952
955
}
953
956
@@ -977,7 +980,7 @@ Future<void> verifyNoTrailingSpaces(String workingDirectory, { int minimumMatche
977
980
}
978
981
}
979
982
if (problems.isNotEmpty) {
980
- exitWithError (problems);
983
+ foundError (problems);
981
984
}
982
985
}
983
986
@@ -1050,7 +1053,7 @@ Future<void> verifyIssueLinks(String workingDirectory) async {
1050
1053
}
1051
1054
assert (problems.isEmpty == suggestions.isEmpty);
1052
1055
if (problems.isNotEmpty) {
1053
- exitWithError (< String > [
1056
+ foundError (< String > [
1054
1057
...problems,
1055
1058
...suggestions,
1056
1059
]);
@@ -1507,7 +1510,7 @@ Future<void> verifyNoBinaries(String workingDirectory, { Set<Hash256>? legacyBin
1507
1510
}
1508
1511
}
1509
1512
if (problems.isNotEmpty) {
1510
- exitWithError (< String > [
1513
+ foundError (< String > [
1511
1514
...problems,
1512
1515
'All files in this repository must be UTF-8. In particular, images and other binaries' ,
1513
1516
'must not be checked into this repository. This is because we are very sensitive to the' ,
@@ -1545,7 +1548,7 @@ Future<List<File>> _gitFiles(String workingDirectory, {bool runSilently = true})
1545
1548
runSilently: runSilently,
1546
1549
);
1547
1550
if (evalResult.exitCode != 0 ) {
1548
- exitWithError (< String > [
1551
+ foundError (< String > [
1549
1552
'git ls-files failed with exit code ${evalResult .exitCode }' ,
1550
1553
'${bold }stdout:$reset ' ,
1551
1554
evalResult.stdout,
@@ -1671,7 +1674,7 @@ Future<EvalResult> _evalCommand(String executable, List<String> arguments, {
1671
1674
1672
1675
if (exitCode != 0 && ! allowNonZeroExit) {
1673
1676
stderr.write (result.stderr);
1674
- exitWithError (< String > [
1677
+ foundError (< String > [
1675
1678
'${bold }ERROR:$red Last command exited with $exitCode .$reset ' ,
1676
1679
'${bold }Command:$red $commandDescription $reset ' ,
1677
1680
'${bold }Relative working directory:$red $relativeWorkingDir $reset ' ,
@@ -1702,9 +1705,11 @@ Future<void> _checkConsumerDependencies() async {
1702
1705
'--directory=${path .join (flutterRoot , 'packages' , package )}' ,
1703
1706
]);
1704
1707
if (result.exitCode != 0 ) {
1705
- print (result.stdout as Object );
1706
- print (result.stderr as Object );
1707
- exit (result.exitCode);
1708
+ foundError (< String > [
1709
+ result.stdout.toString (),
1710
+ result.stderr.toString (),
1711
+ ]);
1712
+ return ;
1708
1713
}
1709
1714
final Map <String , Object ?> rawJson = json.decode (result.stdout as String ) as Map <String , Object ?>;
1710
1715
final Map <String , Map <String , Object ?>> dependencyTree = < String , Map <String , Object ?>> {
@@ -1734,7 +1739,7 @@ Future<void> _checkConsumerDependencies() async {
1734
1739
String plural (int n, String s, String p) => n == 1 ? s : p;
1735
1740
1736
1741
if (added.isNotEmpty) {
1737
- exitWithError (< String > [
1742
+ foundError (< String > [
1738
1743
'The transitive closure of package dependencies contains ${plural (added .length , "a non-allowlisted package" , "non-allowlisted packages" )}:' ,
1739
1744
' ${added .join (', ' )}' ,
1740
1745
'We strongly desire to keep the number of dependencies to a minimum and' ,
@@ -1745,7 +1750,7 @@ Future<void> _checkConsumerDependencies() async {
1745
1750
}
1746
1751
1747
1752
if (removed.isNotEmpty) {
1748
- exitWithError (< String > [
1753
+ foundError (< String > [
1749
1754
'Excellent news! ${plural (removed .length , "A package dependency has been removed!" , "Multiple package dependencies have been removed!" )}' ,
1750
1755
' ${removed .join (', ' )}' ,
1751
1756
'To make sure we do not accidentally add ${plural (removed .length , "this dependency" , "these dependencies" )} back in the future,' ,
@@ -1778,7 +1783,7 @@ Future<void> verifyNullInitializedDebugExpensiveFields(String workingDirectory,
1778
1783
}
1779
1784
1780
1785
if (errors.isNotEmpty) {
1781
- exitWithError (< String > [
1786
+ foundError (< String > [
1782
1787
'${bold }ERROR: ${red }fields annotated with @_debugOnly must null initialize.$reset ' ,
1783
1788
'to ensure both the field and initializer are removed from profile/release mode.' ,
1784
1789
'These fields should be written as:\n ' ,
0 commit comments