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
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:core' hide print;
|
import 'dart:core' hide print;
|
||||||
import 'dart:io' hide exit;
|
import 'dart:io' hide exit;
|
||||||
@ -11,6 +12,7 @@ import 'package:crypto/crypto.dart';
|
|||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
import 'allowlist.dart';
|
||||||
import 'run_command.dart';
|
import 'run_command.dart';
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
|
||||||
@ -76,6 +78,11 @@ Future<void> run(List<String> arguments) async {
|
|||||||
workingDirectory: flutterRoot,
|
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.
|
// Analyze all the Dart code in the repo.
|
||||||
print('$clock Dart analysis...');
|
print('$clock Dart analysis...');
|
||||||
await _runFlutterAnalyze(flutterRoot, options: <String>[
|
await _runFlutterAnalyze(flutterRoot, options: <String>[
|
||||||
@ -1129,6 +1136,62 @@ Future<EvalResult> _evalCommand(String executable, List<String> arguments, {
|
|||||||
return result;
|
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, {
|
Future<void> _runFlutterAnalyze(String workingDirectory, {
|
||||||
List<String> options = const <String>[],
|
List<String> options = const <String>[],
|
||||||
}) async {
|
}) async {
|
||||||
|
Loading…
Reference in New Issue
Block a user