Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 9787752

Browse files
[flutter_plugin_tools] Migrate analyze to new base command (#4084)
Switches `analyze` to the new base command that handles the boilerplate of looping over target packages. This will change the output format slightly, but shoudn't have any functional change. Updates tests to use runCapturingPrint so that test run output isn't mixed with command output. Part of flutter/flutter#83413
1 parent 26e8278 commit 9787752

File tree

2 files changed

+52
-41
lines changed

2 files changed

+52
-41
lines changed

script/tool/lib/src/analyze_command.dart

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import 'package:file/file.dart';
88
import 'package:path/path.dart' as p;
99

1010
import 'common/core.dart';
11-
import 'common/plugin_command.dart';
11+
import 'common/package_looping_command.dart';
1212
import 'common/process_runner.dart';
1313

14+
const int _exitBadCustomAnalysisFile = 2;
15+
1416
/// A command to run Dart analysis on packages.
15-
class AnalyzeCommand extends PluginCommand {
17+
class AnalyzeCommand extends PackageLoopingCommand {
1618
/// Creates a analysis command instance.
1719
AnalyzeCommand(
1820
Directory packagesDir, {
@@ -32,6 +34,8 @@ class AnalyzeCommand extends PluginCommand {
3234

3335
static const String _analysisSdk = 'analysis-sdk';
3436

37+
late String _dartBinaryPath;
38+
3539
@override
3640
final String name = 'analyze';
3741

@@ -40,9 +44,10 @@ class AnalyzeCommand extends PluginCommand {
4044
'This command requires "dart" and "flutter" to be in your path.';
4145

4246
@override
43-
Future<void> run() async {
44-
print('Verifying analysis settings...');
47+
final bool hasLongOutput = false;
4548

49+
/// Checks that there are no unexpected analysis_options.yaml files.
50+
void _validateAnalysisOptions() {
4651
final List<FileSystemEntity> files = packagesDir.listSync(recursive: true);
4752
for (final FileSystemEntity file in files) {
4853
if (file.basename != 'analysis_options.yaml' &&
@@ -59,52 +64,55 @@ class AnalyzeCommand extends PluginCommand {
5964
continue;
6065
}
6166

62-
print('Found an extra analysis_options.yaml in ${file.absolute.path}.');
63-
print(
64-
'If this was deliberate, pass the package to the analyze command with the --$_customAnalysisFlag flag and try again.');
65-
throw ToolExit(1);
67+
printError(
68+
'Found an extra analysis_options.yaml in ${file.absolute.path}.');
69+
printError(
70+
'If this was deliberate, pass the package to the analyze command '
71+
'with the --$_customAnalysisFlag flag and try again.');
72+
throw ToolExit(_exitBadCustomAnalysisFile);
6673
}
74+
}
6775

76+
/// Ensures that the dependent packages have been fetched for all packages
77+
/// (including their sub-packages) that will be analyzed.
78+
Future<void> _runPackagesGetOnTargetPackages() async {
6879
final List<Directory> packageDirectories = await getPackages().toList();
6980
final Set<String> packagePaths =
7081
packageDirectories.map((Directory dir) => dir.path).toSet();
7182
packageDirectories.removeWhere((Directory directory) {
72-
// We remove the 'example' subdirectories - 'flutter pub get' automatically
73-
// runs 'pub get' there as part of handling the parent directory.
83+
// Remove the 'example' subdirectories; 'flutter packages get'
84+
// automatically runs 'pub get' there as part of handling the parent
85+
// directory.
7486
return directory.basename == 'example' &&
7587
packagePaths.contains(directory.parent.path);
7688
});
7789
for (final Directory package in packageDirectories) {
7890
await processRunner.runAndStream('flutter', <String>['packages', 'get'],
7991
workingDir: package, exitOnError: true);
8092
}
93+
}
94+
95+
@override
96+
Future<void> initializeRun() async {
97+
print('Verifying analysis settings...');
98+
_validateAnalysisOptions();
99+
100+
print('Fetching dependencies...');
101+
await _runPackagesGetOnTargetPackages();
81102

82103
// Use the Dart SDK override if one was passed in.
83104
final String? dartSdk = argResults![_analysisSdk] as String?;
84-
final String dartBinary =
85-
dartSdk == null ? 'dart' : p.join(dartSdk, 'bin', 'dart');
86-
87-
final List<String> failingPackages = <String>[];
88-
final List<Directory> pluginDirectories = await getPlugins().toList();
89-
for (final Directory package in pluginDirectories) {
90-
final int exitCode = await processRunner.runAndStream(
91-
dartBinary, <String>['analyze', '--fatal-infos'],
92-
workingDir: package);
93-
if (exitCode != 0) {
94-
failingPackages.add(p.basename(package.path));
95-
}
96-
}
97-
98-
print('\n\n');
105+
_dartBinaryPath = dartSdk == null ? 'dart' : p.join(dartSdk, 'bin', 'dart');
106+
}
99107

100-
if (failingPackages.isNotEmpty) {
101-
print('The following packages have analyzer errors (see above):');
102-
for (final String package in failingPackages) {
103-
print(' * $package');
104-
}
105-
throw ToolExit(1);
108+
@override
109+
Future<List<String>> runForPackage(Directory package) async {
110+
final int exitCode = await processRunner.runAndStream(
111+
_dartBinaryPath, <String>['analyze', '--fatal-infos'],
112+
workingDir: package);
113+
if (exitCode != 0) {
114+
return PackageLoopingCommand.failure;
106115
}
107-
108-
print('No analyzer errors found!');
116+
return PackageLoopingCommand.success;
109117
}
110118
}

script/tool/test/analyze_command_test.dart

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void main() {
3636
final MockProcess mockProcess = MockProcess();
3737
mockProcess.exitCodeCompleter.complete(0);
3838
processRunner.processToReturn = mockProcess;
39-
await runner.run(<String>['analyze']);
39+
await runCapturingPrint(runner, <String>['analyze']);
4040

4141
expect(
4242
processRunner.recordedCalls,
@@ -58,7 +58,7 @@ void main() {
5858
final MockProcess mockProcess = MockProcess();
5959
mockProcess.exitCodeCompleter.complete(0);
6060
processRunner.processToReturn = mockProcess;
61-
await runner.run(<String>['analyze']);
61+
await runCapturingPrint(runner, <String>['analyze']);
6262

6363
expect(
6464
processRunner.recordedCalls,
@@ -77,7 +77,7 @@ void main() {
7777
final MockProcess mockProcess = MockProcess();
7878
mockProcess.exitCodeCompleter.complete(0);
7979
processRunner.processToReturn = mockProcess;
80-
await runner.run(<String>['analyze']);
80+
await runCapturingPrint(runner, <String>['analyze']);
8181

8282
expect(
8383
processRunner.recordedCalls,
@@ -99,7 +99,8 @@ void main() {
9999
final MockProcess mockProcess = MockProcess();
100100
mockProcess.exitCodeCompleter.complete(0);
101101
processRunner.processToReturn = mockProcess;
102-
await runner.run(<String>['analyze', '--analysis-sdk', 'foo/bar/baz']);
102+
await runCapturingPrint(
103+
runner, <String>['analyze', '--analysis-sdk', 'foo/bar/baz']);
103104

104105
expect(
105106
processRunner.recordedCalls,
@@ -123,15 +124,15 @@ void main() {
123124
createFakePlugin('foo', packagesDir,
124125
extraFiles: <String>['analysis_options.yaml']);
125126

126-
await expectLater(() => runner.run(<String>['analyze']),
127+
await expectLater(() => runCapturingPrint(runner, <String>['analyze']),
127128
throwsA(const TypeMatcher<ToolExit>()));
128129
});
129130

130131
test('fails .analysis_options', () async {
131132
createFakePlugin('foo', packagesDir,
132133
extraFiles: <String>['.analysis_options']);
133134

134-
await expectLater(() => runner.run(<String>['analyze']),
135+
await expectLater(() => runCapturingPrint(runner, <String>['analyze']),
135136
throwsA(const TypeMatcher<ToolExit>()));
136137
});
137138

@@ -142,7 +143,8 @@ void main() {
142143
final MockProcess mockProcess = MockProcess();
143144
mockProcess.exitCodeCompleter.complete(0);
144145
processRunner.processToReturn = mockProcess;
145-
await runner.run(<String>['analyze', '--custom-analysis', 'foo']);
146+
await runCapturingPrint(
147+
runner, <String>['analyze', '--custom-analysis', 'foo']);
146148

147149
expect(
148150
processRunner.recordedCalls,
@@ -164,7 +166,8 @@ void main() {
164166
processRunner.processToReturn = mockProcess;
165167

166168
await expectLater(
167-
() => runner.run(<String>['analyze', '--custom-analysis', '']),
169+
() => runCapturingPrint(
170+
runner, <String>['analyze', '--custom-analysis', '']),
168171
throwsA(const TypeMatcher<ToolExit>()));
169172
});
170173
});

0 commit comments

Comments
 (0)