mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
create SDK package allowlist for core packages (#80318)
This commit is contained in:
parent
9c03bce290
commit
f6f59c58bc
76
dev/bots/allowlist.dart
Normal file
76
dev/bots/allowlist.dart
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
/// The SDK package allowlist for the flutter, flutter_test, flutter_driver, flutter_localizations,
|
||||
/// and integration_test packages.
|
||||
///
|
||||
/// The goal of the allowlist is to make it more difficult to accidentally add new dependencies
|
||||
/// to the core SDK packages that users depend on. Any dependencies added to this set can have a
|
||||
/// large impact on the allowed version solving of a given flutter application because of how
|
||||
/// the SDK pins to an exact version.
|
||||
///
|
||||
/// Before adding a new Dart Team owned dependency to this set, please clear with natebosch@
|
||||
/// or jakemac53@. For other packages please contact hixie@ or jonahwilliams@ .
|
||||
const Set<String> kCorePackageAllowList = <String>{
|
||||
'characters',
|
||||
'clock',
|
||||
'collection',
|
||||
'fake_async',
|
||||
'file',
|
||||
'intl',
|
||||
'meta',
|
||||
'path',
|
||||
'stack_trace',
|
||||
'test',
|
||||
'test_api',
|
||||
'typed_data',
|
||||
'vector_math',
|
||||
'vm_service',
|
||||
'webdriver',
|
||||
'_fe_analyzer_shared',
|
||||
'analyzer',
|
||||
'archive',
|
||||
'args',
|
||||
'async',
|
||||
'boolean_selector',
|
||||
'charcode',
|
||||
'cli_util',
|
||||
'convert',
|
||||
'coverage',
|
||||
'crypto',
|
||||
'glob',
|
||||
'http_multi_server',
|
||||
'http_parser',
|
||||
'io',
|
||||
'js',
|
||||
'logging',
|
||||
'matcher',
|
||||
'mime',
|
||||
'node_preamble',
|
||||
'package_config',
|
||||
'pedantic',
|
||||
'pool',
|
||||
'pub_semver',
|
||||
'shelf',
|
||||
'shelf_packages_handler',
|
||||
'shelf_static',
|
||||
'shelf_web_socket',
|
||||
'source_map_stack_trace',
|
||||
'source_maps',
|
||||
'source_span',
|
||||
'stream_channel',
|
||||
'string_scanner',
|
||||
'sync_http',
|
||||
'term_glyph',
|
||||
'test_core',
|
||||
'watcher',
|
||||
'web_socket_channel',
|
||||
'webkit_inspection_protocol',
|
||||
'yaml',
|
||||
'flutter',
|
||||
'flutter_driver',
|
||||
'flutter_localizations',
|
||||
'flutter_test',
|
||||
'integration_test'
|
||||
};
|
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:core' hide print;
|
||||
import 'dart:io' hide exit;
|
||||
@ -11,6 +12,7 @@ import 'package:crypto/crypto.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'allowlist.dart';
|
||||
import 'run_command.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
@ -76,6 +78,11 @@ Future<void> run(List<String> arguments) async {
|
||||
workingDirectory: flutterRoot,
|
||||
);
|
||||
|
||||
/// Ensure that no new dependencies have been accidentally
|
||||
/// added to core packages.
|
||||
print('$clock Package Allowlist...');
|
||||
await _checkConsumerDependencies();
|
||||
|
||||
// Analyze all the Dart code in the repo.
|
||||
print('$clock Dart analysis...');
|
||||
await _runFlutterAnalyze(flutterRoot, options: <String>[
|
||||
@ -1129,6 +1136,62 @@ Future<EvalResult> _evalCommand(String executable, List<String> arguments, {
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<void> _checkConsumerDependencies() async {
|
||||
final ProcessResult result = await Process.run(flutter, <String>[
|
||||
'update-packages',
|
||||
'--transitive-closure',
|
||||
'--consumer-only',
|
||||
]);
|
||||
if (result.exitCode != 0) {
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
exit(result.exitCode);
|
||||
}
|
||||
final Set<String> dependencySet = <String>{};
|
||||
for (final String line in result.stdout.toString().split('\n')) {
|
||||
if (!line.contains('->')) {
|
||||
continue;
|
||||
}
|
||||
final List<String> parts = line.split('->');
|
||||
final String name = parts[0].trim();
|
||||
dependencySet.add(name);
|
||||
}
|
||||
final List<String> dependencies = dependencySet.toList()
|
||||
..sort();
|
||||
final List<String> disallowed = <String>[];
|
||||
final StreamController<Digest> controller = StreamController<Digest>();
|
||||
final ByteConversionSink hasher = sha256.startChunkedConversion(controller.sink);
|
||||
for (final String dependency in dependencies) {
|
||||
hasher.add(utf8.encode(dependency));
|
||||
if (!kCorePackageAllowList.contains(dependency)) {
|
||||
disallowed.add(dependency);
|
||||
}
|
||||
}
|
||||
hasher.close();
|
||||
final Digest digest = await controller.stream.last;
|
||||
final String signature = base64.encode(digest.bytes);
|
||||
|
||||
// Do not change this signature without following the directions in
|
||||
// dev/bots/allowlist.dart
|
||||
const String kExpected = '3S20q38QbN+dDAp+jApXiTRaDgVGGBZ0t4bMJgD3AUY=';
|
||||
|
||||
if (disallowed.isNotEmpty) {
|
||||
exitWithError(<String>[
|
||||
'Warning: transitive closure contained non-allowlisted packages:',
|
||||
'${disallowed..join(', ')}',
|
||||
'See dev/bots/allowlist.dart for instructions on how to update the package allowlist.',
|
||||
]);
|
||||
}
|
||||
|
||||
if (signature != kExpected) {
|
||||
exitWithError(<String>[
|
||||
'Warning: transitive closure sha256 does not match expected signature.',
|
||||
'See dev/bots/allowlist.dart for instructions on how to update the package allowlist.',
|
||||
'$signature != $kExpected',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _runFlutterAnalyze(String workingDirectory, {
|
||||
List<String> options = const <String>[],
|
||||
}) async {
|
||||
|
Loading…
Reference in New Issue
Block a user