[flutter_releases] Flutter beta 2.10.0-0.3.pre Framework Cherrypicks (#97259)
* Fix analyze --watch command iterator (#96264)
* 'add branch flutter-2.8-candidate.16 to enabled_branches in .ci.yaml'
* 'Update Engine revision to 5ac30ef0c70b76c5d5b5465b0ad4f08d5433684f for beta release 2.10.0-0.3.pre'
* remove unnecessary ref to branch candidate
Co-authored-by: Jenn Magder <magder@google.com>
Co-authored-by: Kevin Chisholm <kevinjchisholm@google.com>
Co-authored-by: godofredoc <godofredoc@google.com>
diff --git a/bin/internal/engine.version b/bin/internal/engine.version
index 9c1fbfe..8fe8bb8 100644
--- a/bin/internal/engine.version
+++ b/bin/internal/engine.version
@@ -1 +1 @@
-74b74b10ea6764e373ca2bcb420fdb4a6f6b5918
+5ac30ef0c70b76c5d5b5465b0ad4f08d5433684f
diff --git a/packages/flutter_tools/lib/src/commands/analyze_continuously.dart b/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
index b791ae2..705ed33 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
@@ -110,27 +110,29 @@
logger.printStatus(terminal.clearScreen(), newline: false);
// Remove errors for deleted files, sort, and print errors.
- final List<AnalysisError> errors = <AnalysisError>[];
+ final List<AnalysisError> sortedErrors = <AnalysisError>[];
+ final List<String> pathsToRemove = <String>[];
analysisErrors.forEach((String path, List<AnalysisError> errors) {
if (fileSystem.isFileSync(path)) {
- errors.addAll(errors);
+ sortedErrors.addAll(errors);
} else {
- analysisErrors.remove(path);
+ pathsToRemove.add(path);
}
});
+ analysisErrors.removeWhere((String path, _) => pathsToRemove.contains(path));
- errors.sort();
+ sortedErrors.sort();
- for (final AnalysisError error in errors) {
+ for (final AnalysisError error in sortedErrors) {
logger.printStatus(error.toString());
if (error.code != null) {
logger.printTrace('error code: ${error.code}');
}
}
- dumpErrors(errors.map<String>((AnalysisError error) => error.toLegacyString()));
+ dumpErrors(sortedErrors.map<String>((AnalysisError error) => error.toLegacyString()));
- final int issueCount = errors.length;
+ final int issueCount = sortedErrors.length;
final int issueDiff = issueCount - lastErrorCount;
lastErrorCount = issueCount;
final String seconds = (analysisTimer.elapsedMilliseconds / 1000.0).toStringAsFixed(2);
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart
index 8a0620e..35f63ca 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart
@@ -6,6 +6,7 @@
import 'dart:async';
+import 'package:fake_async/fake_async.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/common.dart';
@@ -174,7 +175,6 @@
});
testUsingContext('Can run AnalysisService with customized cache location', () async {
- final Completer<void> completer = Completer<void>();
final StreamController<List<int>> stdin = StreamController<List<int>>();
final FakeProcessManager processManager = FakeProcessManager.list(
<FakeCommand>[
@@ -188,7 +188,6 @@
'--sdk',
'HostArtifact.engineDartSdkPath',
],
- completer: completer,
stdin: IOSink(stdin.sink),
),
]);
@@ -212,6 +211,11 @@
});
testUsingContext('Can run AnalysisService with customized cache location --watch', () async {
+ final MemoryFileSystem fileSystem = MemoryFileSystem.test();
+ fileSystem.directory('directoryA').childFile('foo').createSync(recursive: true);
+
+ final BufferLogger logger = BufferLogger.test();
+
final Completer<void> completer = Completer<void>();
final StreamController<List<int>> stdin = StreamController<List<int>>();
final FakeProcessManager processManager = FakeProcessManager.list(
@@ -226,8 +230,12 @@
'--sdk',
'HostArtifact.engineDartSdkPath',
],
- completer: completer,
stdin: IOSink(stdin.sink),
+ stdout: '''
+{"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
+{"event":"analysis.errors","params":{"file":"/directoryA/foo","errors":[{"type":"TestError","message":"It's an error.","severity":"warning","code":"500","location":{"file":"/directoryA/foo","startLine": 100,"startColumn":5,"offset":0}}]}}
+{"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
+'''
),
]);
@@ -235,17 +243,78 @@
final AnalyzeCommand command = AnalyzeCommand(
terminal: Terminal.test(),
artifacts: artifacts,
- logger: BufferLogger.test(),
+ logger: logger,
+ platform: FakePlatform(),
+ fileSystem: fileSystem,
+ processManager: processManager,
+ );
+
+ await FakeAsync().run((FakeAsync time) async {
+ final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner();
+ commandRunner.addCommand(command);
+ unawaited(commandRunner.run(<String>['analyze', '--watch']));
+
+ while (!logger.statusText.contains('analyzed 1 file')) {
+ time.flushMicrotasks();
+ }
+ completer.complete();
+ return completer.future;
+ });
+ expect(logger.statusText, contains("warning • It's an error • directoryA/foo:100:5 • 500"));
+ expect(logger.statusText, contains('1 issue found. (1 new)'));
+ expect(logger.errorText, isEmpty);
+ expect(processManager, hasNoRemainingExpectations);
+ });
+
+ testUsingContext('AnalysisService --watch skips errors from non-files', () async {
+ final BufferLogger logger = BufferLogger.test();
+ final Completer<void> completer = Completer<void>();
+ final StreamController<List<int>> stdin = StreamController<List<int>>();
+ final FakeProcessManager processManager = FakeProcessManager.list(
+ <FakeCommand>[
+ FakeCommand(
+ command: const <String>[
+ 'HostArtifact.engineDartSdkPath/bin/dart',
+ '--disable-dart-dev',
+ 'HostArtifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
+ '--disable-server-feature-completion',
+ '--disable-server-feature-search',
+ '--sdk',
+ 'HostArtifact.engineDartSdkPath',
+ ],
+ stdin: IOSink(stdin.sink),
+ stdout: '''
+{"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
+{"event":"analysis.errors","params":{"file":"/directoryA/bar","errors":[{"type":"TestError","message":"It's an error.","severity":"warning","code":"500","location":{"file":"/directoryA/bar","startLine":100,"startColumn":5,"offset":0}}]}}
+{"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
+'''
+ ),
+ ]);
+
+ final Artifacts artifacts = Artifacts.test();
+ final AnalyzeCommand command = AnalyzeCommand(
+ terminal: Terminal.test(),
+ artifacts: artifacts,
+ logger: logger,
platform: FakePlatform(),
fileSystem: MemoryFileSystem.test(),
processManager: processManager,
);
- final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner();
- commandRunner.addCommand(command);
- unawaited(commandRunner.run(<String>['analyze', '--watch']));
- await stdin.stream.first;
+ await FakeAsync().run((FakeAsync time) async {
+ final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner();
+ commandRunner.addCommand(command);
+ unawaited(commandRunner.run(<String>['analyze', '--watch']));
+ while (!logger.statusText.contains('analyzed 1 file')) {
+ time.flushMicrotasks();
+ }
+ completer.complete();
+ return completer.future;
+ });
+
+ expect(logger.statusText, contains('No issues found!'));
+ expect(logger.errorText, isEmpty);
expect(processManager, hasNoRemainingExpectations);
});
}