Skip to content

Commit d17489c

Browse files
[flutter_plugin_tools] Support YAML exception lists (#4183)
Currently the tool accepts `--custom-analysis` to allow a list of packages for which custom `analysis_options.yaml` are allowed, and `--exclude` to exclude a set of packages when running a command against all, or all changed, packages. This results in these exception lists being embedded into CI configuration files (e.g., .cirrus.yaml) or scripts, which makes them harder to maintain, and harder to re-use in other contexts (local runs, new CI systems). This adds support for both flags to accept paths to YAML files that contain the lists, so that they can be maintained separately, and with inline comments about the reasons things are on the lists. Also updates the CI to use this new support, eliminating those lists from `.cirrus.yaml` and `tool_runner.sh` Fixes flutter/flutter#86799
1 parent 97178af commit d17489c

File tree

5 files changed

+70
-4
lines changed

5 files changed

+70
-4
lines changed

script/tool/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## NEXT
22

3+
- `--exclude` and `--custom-analysis` now accept paths to YAML files that
4+
contain lists of packages to exclude, in addition to just package names,
5+
so that exclude lists can be maintained separately from scripts and CI
6+
configuration.
37
- Added an `xctest` flag to select specific test targets, to allow running only
48
unit tests or integration tests.
59
- **Breaking change**: Split Xcode analysis out of `xctest` and into a new

script/tool/lib/src/analyze_command.dart

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:async';
66

77
import 'package:file/file.dart';
88
import 'package:platform/platform.dart';
9+
import 'package:yaml/yaml.dart';
910

1011
import 'common/core.dart';
1112
import 'common/package_looping_command.dart';
@@ -23,7 +24,10 @@ class AnalyzeCommand extends PackageLoopingCommand {
2324
}) : super(packagesDir, processRunner: processRunner, platform: platform) {
2425
argParser.addMultiOption(_customAnalysisFlag,
2526
help:
26-
'Directories (comma separated) that are allowed to have their own analysis options.',
27+
'Directories (comma separated) that are allowed to have their own '
28+
'analysis options.\n\n'
29+
'Alternately, a list of one or more YAML files that contain a list '
30+
'of allowed directories.',
2731
defaultsTo: <String>[]);
2832
argParser.addOption(_analysisSdk,
2933
valueHelp: 'dart-sdk',
@@ -37,6 +41,8 @@ class AnalyzeCommand extends PackageLoopingCommand {
3741

3842
late String _dartBinaryPath;
3943

44+
Set<String> _allowedCustomAnalysisDirectories = const <String>{};
45+
4046
@override
4147
final String name = 'analyze';
4248

@@ -56,7 +62,7 @@ class AnalyzeCommand extends PackageLoopingCommand {
5662
continue;
5763
}
5864

59-
final bool allowed = (getStringListArg(_customAnalysisFlag)).any(
65+
final bool allowed = _allowedCustomAnalysisDirectories.any(
6066
(String directory) =>
6167
directory.isNotEmpty &&
6268
path.isWithin(
@@ -107,6 +113,17 @@ class AnalyzeCommand extends PackageLoopingCommand {
107113
throw ToolExit(_exitPackagesGetFailed);
108114
}
109115

116+
_allowedCustomAnalysisDirectories =
117+
getStringListArg(_customAnalysisFlag).expand<String>((String item) {
118+
if (item.endsWith('.yaml')) {
119+
final File file = packagesDir.fileSystem.file(item);
120+
return (loadYaml(file.readAsStringSync()) as YamlList)
121+
.toList()
122+
.cast<String>();
123+
}
124+
return <String>[item];
125+
}).toSet();
126+
110127
// Use the Dart SDK override if one was passed in.
111128
final String? dartSdk = argResults![_analysisSdk] as String?;
112129
_dartBinaryPath =

script/tool/lib/src/common/plugin_command.dart

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:file/file.dart';
99
import 'package:git/git.dart';
1010
import 'package:path/path.dart' as p;
1111
import 'package:platform/platform.dart';
12+
import 'package:yaml/yaml.dart';
1213

1314
import 'core.dart';
1415
import 'git_version_finder.dart';
@@ -48,7 +49,9 @@ abstract class PluginCommand extends Command<void> {
4849
argParser.addMultiOption(
4950
_excludeArg,
5051
abbr: 'e',
51-
help: 'Exclude packages from this command.',
52+
help: 'A list of packages to exclude from from this command.\n\n'
53+
'Alternately, a list of one or more YAML files that contain a list '
54+
'of packages to exclude.',
5255
defaultsTo: <String>[],
5356
);
5457
argParser.addFlag(_runOnChangedPackagesArg,
@@ -214,8 +217,18 @@ abstract class PluginCommand extends Command<void> {
214217
/// of packages in the flutter/packages repository.
215218
Stream<Directory> _getAllPlugins() async* {
216219
Set<String> plugins = Set<String>.from(getStringListArg(_packagesArg));
220+
217221
final Set<String> excludedPlugins =
218-
Set<String>.from(getStringListArg(_excludeArg));
222+
getStringListArg(_excludeArg).expand<String>((String item) {
223+
if (item.endsWith('.yaml')) {
224+
final File file = packagesDir.fileSystem.file(item);
225+
return (loadYaml(file.readAsStringSync()) as YamlList)
226+
.toList()
227+
.cast<String>();
228+
}
229+
return <String>[item];
230+
}).toSet();
231+
219232
final bool runOnChangedPackages = getBoolArg(_runOnChangedPackagesArg);
220233
if (plugins.isEmpty &&
221234
runOnChangedPackages &&

script/tool/test/analyze_command_test.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,25 @@ void main() {
176176
]));
177177
});
178178

179+
test('takes an allow config file', () async {
180+
final Directory pluginDir = createFakePlugin('foo', packagesDir,
181+
extraFiles: <String>['analysis_options.yaml']);
182+
final File allowFile = packagesDir.childFile('custom.yaml');
183+
allowFile.writeAsStringSync('- foo');
184+
185+
await runCapturingPrint(
186+
runner, <String>['analyze', '--custom-analysis', allowFile.path]);
187+
188+
expect(
189+
processRunner.recordedCalls,
190+
orderedEquals(<ProcessCall>[
191+
ProcessCall(
192+
'flutter', const <String>['packages', 'get'], pluginDir.path),
193+
ProcessCall('dart', const <String>['analyze', '--fatal-infos'],
194+
pluginDir.path),
195+
]));
196+
});
197+
179198
// See: https://github.com/flutter/flutter/issues/78994
180199
test('takes an empty allow list', () async {
181200
createFakePlugin('foo', packagesDir,

script/tool/test/common/plugin_command_test.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,19 @@ void main() {
172172
expect(plugins, unorderedEquals(<String>[plugin2.path]));
173173
});
174174

175+
test('exclude accepts config files', () async {
176+
createFakePlugin('plugin1', packagesDir);
177+
final File configFile = packagesDir.childFile('exclude.yaml');
178+
configFile.writeAsStringSync('- plugin1');
179+
180+
await runCapturingPrint(runner, <String>[
181+
'sample',
182+
'--packages=plugin1',
183+
'--exclude=${configFile.path}'
184+
]);
185+
expect(plugins, unorderedEquals(<String>[]));
186+
});
187+
175188
group('test run-on-changed-packages', () {
176189
test('all plugins should be tested if there are no changes.', () async {
177190
final Directory plugin1 = createFakePlugin('plugin1', packagesDir);

0 commit comments

Comments
 (0)