Unverified Commit f6f59c58 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

create SDK package allowlist for core packages (#80318)

parent 9c03bce2
// 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 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment