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

Commit 758c55e

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 b6d1345 commit 758c55e

14 files changed

+161
-89
lines changed

.cirrus.yml

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ task:
7272
- cd script/tool
7373
- dart analyze --fatal-infos
7474
script:
75-
- ./script/tool_runner.sh analyze
75+
- ./script/tool_runner.sh analyze --custom-analysis=script/configs/custom_analysis.yaml
7676
### Android tasks ###
7777
- name: build_all_plugins_apk
7878
env:
@@ -137,22 +137,6 @@ task:
137137
CHANNEL: "stable"
138138
MAPS_API_KEY: ENCRYPTED[596a9f6bca436694625ac50851dc5da6b4d34cba8025f7db5bc9465142e8cd44e15f69e3507787753accebfc4910d550]
139139
GCLOUD_FIREBASE_TESTLAB_KEY: ENCRYPTED[07586610af1fdfc894e5969f70ef2458341b9b7e9c3b7c4225a663b4a48732b7208a4d91c3b7d45305a6b55fa2a37fc4]
140-
# Currently missing harness files (https://github.com/flutter/flutter/issues/86749):
141-
# camera/camera
142-
# google_sign_in/google_sign_in
143-
# in_app_purchase/in_app_purchase
144-
# in_app_purchase_android
145-
# quick_actions
146-
# shared_preferences/shared_preferences
147-
# url_launcher/url_launcher
148-
# video_player/video_player
149-
# webview_flutter
150-
# Deprecated; no plan to backfill the missing files:
151-
# android_intent,connectivity/connectivity,device_info/device_info,sensors,share,wifi_info_flutter/wifi_info_flutter
152-
# No integration tests to run:
153-
# image_picker/image_picker - Native UI is the critical functionality
154-
# espresso - No Dart code, so no integration tests
155-
PLUGINS_TO_EXCLUDE_INTEGRATION_TESTS: "camera/camera,google_sign_in/google_sign_in,in_app_purchase/in_app_purchase,in_app_purchase_android,quick_actions,shared_preferences/shared_preferences,url_launcher/url_launcher,video_player/video_player,webview_flutter,android_intent,connectivity/connectivity,device_info/device_info,sensors,share,wifi_info_flutter/wifi_info_flutter,image_picker/image_picker,espresso"
156140
build_script:
157141
# Unsetting CIRRUS_CHANGE_MESSAGE and CIRRUS_COMMIT_MESSAGE as they
158142
# might include non-ASCII characters which makes Gradle crash.
@@ -177,16 +161,13 @@ task:
177161
- export CIRRUS_COMMIT_MESSAGE=""
178162
- if [[ -n "$GCLOUD_FIREBASE_TESTLAB_KEY" ]]; then
179163
- echo $GCLOUD_FIREBASE_TESTLAB_KEY > ${HOME}/gcloud-service-key.json
180-
- ./script/tool_runner.sh firebase-test-lab --device model=flame,version=29 --device model=starqlteue,version=26 --exclude $PLUGINS_TO_EXCLUDE_INTEGRATION_TESTS
164+
- ./script/tool_runner.sh firebase-test-lab --device model=flame,version=29 --device model=starqlteue,version=26 --exclude=script/configs/exclude_integration_android.yaml
181165
- else
182166
- echo "This user does not have permission to run Firebase Test Lab tests."
183167
- fi
184168
### Web tasks ###
185169
- name: build-web+drive-examples
186170
env:
187-
# Currently missing; see https://github.com/flutter/flutter/issues/81982
188-
# and https://github.com/flutter/flutter/issues/82211
189-
PLUGINS_TO_EXCLUDE_INTEGRATION_TESTS: "file_selector,shared_preferences_web"
190171
matrix:
191172
CHANNEL: "master"
192173
CHANNEL: "stable"
@@ -199,7 +180,7 @@ task:
199180
build_script:
200181
- ./script/tool_runner.sh build-examples --web
201182
drive_script:
202-
- ./script/tool_runner.sh drive-examples --web --exclude $PLUGINS_TO_EXCLUDE_INTEGRATION_TESTS
183+
- ./script/tool_runner.sh drive-examples --web --exclude=script/configs/exclude_integration_web.yaml
203184

204185
# macOS tasks.
205186
task:
@@ -221,10 +202,6 @@ task:
221202
- name: build-ipas+drive-examples
222203
env:
223204
PATH: $PATH:/usr/local/bin
224-
# in_app_purchase_ios is currently missing tests; see https://github.com/flutter/flutter/issues/81695
225-
# ios_platform_images is currently missing tests; see https://github.com/flutter/flutter/issues/82208
226-
# sensor hangs on CI.
227-
PLUGINS_TO_EXCLUDE_INTEGRATION_TESTS: "in_app_purchase_ios,ios_platform_images,sensors"
228205
matrix:
229206
PLUGIN_SHARDING: "--shardIndex 0 --shardCount 4"
230207
PLUGIN_SHARDING: "--shardIndex 1 --shardCount 4"
@@ -247,7 +224,7 @@ task:
247224
# `drive-examples` contains integration tests, which changes the UI of the application.
248225
# This UI change sometimes affects `xctest`.
249226
# So we run `drive-examples` after `native-test`; changing the order will result ci failure.
250-
- ./script/tool_runner.sh drive-examples --ios --exclude $PLUGINS_TO_EXCLUDE_INTEGRATION_TESTS
227+
- ./script/tool_runner.sh drive-examples --ios --exclude=script/configs/exclude_integration_ios.yaml
251228
### macOS desktop tasks ###
252229
- name: build_all_plugins_macos
253230
env:
@@ -259,9 +236,6 @@ task:
259236
- ./script/build_all_plugins_app.sh macos
260237
- name: build-macos+drive-examples
261238
env:
262-
# conncectivity_macos is deprecated, so is not getting unit test backfill.
263-
# package_info is deprecated, so is not getting unit test backfill.
264-
PLUGINS_TO_EXCLUDE_MACOS_XCTESTS: "connectivity_macos,package_info"
265239
matrix:
266240
CHANNEL: "master"
267241
CHANNEL: "stable"
@@ -272,6 +246,6 @@ task:
272246
xcode_analyze_script:
273247
- ./script/tool_runner.sh xcode-analyze --macos
274248
native_test_script:
275-
- ./script/tool_runner.sh native-test --macos --exclude $PLUGINS_TO_EXCLUDE_MACOS_XCTESTS
249+
- ./script/tool_runner.sh native-test --macos --exclude=script/configs/exclude_native_macos.yaml
276250
drive_script:
277251
- ./script/tool_runner.sh drive-examples --macos

packages/e2e/analysis_options.yaml

Lines changed: 0 additions & 1 deletion
This file was deleted.

script/configs/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
This folder contains configuration files that are passed to commands in place
2+
of plugin lists. They are primarily used by CI to opt specific packages out of
3+
tests, but can also useful when running multi-plugin tests locally.
4+
5+
**Any entry added to a file in this directory should include a comment**.
6+
Skipping tests or checks for plugins is usually not something we want to do,
7+
so should the comment should either include an issue link to the issue tracking
8+
removing it or—much more rarely—explaining why it is a permanent exclusion.

script/configs/custom_analysis.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Plugins that deliberately use their own analysis_options.yaml.
2+
#
3+
# This only exists to allow incrementally switching to the newer, stricter
4+
# analysis_options.yaml based on flutter/flutter, rather than the original
5+
# rules based on pedantic (now at analysis_options_legacy.yaml).
6+
#
7+
# DO NOT add new entries to the list, unless it is to push the legacy rules
8+
# from a top-level package into more specific packages in order to incrementally
9+
# migrate a federated plugin.
10+
#
11+
# TODO(ecosystem): Remove everything from this list. See:
12+
# https://github.com/flutter/flutter/issues/76229
13+
- camera
14+
- file_selector
15+
- flutter_plugin_android_lifecycle
16+
- google_maps_flutter
17+
- google_sign_in
18+
- image_picker
19+
- in_app_purchase
20+
- integration_test
21+
- ios_platform_images
22+
- local_auth
23+
- plugin_platform_interface
24+
- quick_actions
25+
- shared_preferences
26+
- url_launcher
27+
- video_player
28+
- webview_flutter
29+
30+
# These plugins are deprecated in favor of the Community Plus versions, and
31+
# will be removed from the repo once the critical support window has passed,
32+
# so are not worth updating.
33+
- android_alarm_manager
34+
- android_intent
35+
- battery
36+
- connectivity
37+
- device_info
38+
- package_info
39+
- sensors
40+
- share
41+
- wifi_info_flutter
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Currently missing harness files: https://github.com/flutter/flutter/issues/86749)
2+
- camera/camera
3+
- google_sign_in/google_sign_in
4+
- in_app_purchase/in_app_purchase
5+
- in_app_purchase_android
6+
- quick_actions
7+
- shared_preferences/shared_preferences
8+
- url_launcher/url_launcher
9+
- video_player/video_player
10+
- webview_flutter
11+
12+
# Deprecated; no plan to backfill the missing files
13+
- android_intent
14+
- connectivity/connectivity
15+
- device_info/device_info
16+
- sensors
17+
- share
18+
- wifi_info_flutter/wifi_info_flutter
19+
20+
# No integration tests to run:
21+
- image_picker/image_picker
22+
- espresso
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Currently missing: https://github.com/flutter/flutter/issues/81695
2+
- in_app_purchase_ios
3+
# Currently missing: https://github.com/flutter/flutter/issues/82208
4+
- ios_platform_images
5+
# Hangs on CI. Deprecated, so there is no plan to fix it.
6+
- sensors
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Currently missing: https://github.com/flutter/flutter/issues/81982
2+
- shared_preferences_web
3+
# Currently missing: https://github.com/flutter/flutter/issues/82211
4+
- file_selector
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Deprecated plugins that will not be getting unit test backfill.
2+
- connectivity_macos
3+
- package_info

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)