mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
Remove unused parts of migration tooling
Change-Id: Ib18224f42880c47be63e6f6814db99ac05eced48 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278373 Reviewed-by: Samuel Rawlins <srawlins@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
e925066175
commit
69f4dc0dcd
|
@ -1,196 +0,0 @@
|
|||
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// TODO(jcollins-g): Merge this with similar utilities in dartdoc
|
||||
// and extract into a separate package, generate testing and mirrors, and
|
||||
// reimport that into the SDK, before cut and paste gets out of hand.
|
||||
|
||||
/// This is a modified version of dartdoc's
|
||||
/// SubprocessLauncher from test/src/utils.dart, for use with the
|
||||
/// nnbd_migration script.
|
||||
library;
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'multi_future_tracker.dart';
|
||||
|
||||
/// Maximum number of parallel subprocesses. Use this to to avoid overloading
|
||||
/// your CPU.
|
||||
final MultiFutureTracker maxParallel =
|
||||
MultiFutureTracker(Platform.numberOfProcessors);
|
||||
|
||||
/// Route all executions of pub through this [MultiFutureTracker] to avoid
|
||||
/// parallel executions of the pub command.
|
||||
final MultiFutureTracker pubTracker = MultiFutureTracker(1);
|
||||
|
||||
final RegExp quotables = RegExp(r'[ "\r\n\$]');
|
||||
|
||||
/// SubprocessLauncher manages one or more launched, non-interactive
|
||||
/// subprocesses. It handles I/O streams, parses JSON output if
|
||||
/// available, and logs debugging information so the user can see exactly
|
||||
/// what was run.
|
||||
class SubprocessLauncher {
|
||||
final String context;
|
||||
final Map<String, String> environmentDefaults;
|
||||
|
||||
SubprocessLauncher(this.context, [Map<String, String>? environment])
|
||||
: environmentDefaults = environment ?? <String, String>{};
|
||||
|
||||
/// Wraps [runStreamedImmediate] as a closure around
|
||||
/// [maxParallel.addFutureFromClosure].
|
||||
///
|
||||
/// This essentially implements a 'make -j N' limit for all subcommands.
|
||||
Future<Iterable<Map>?> runStreamed(String executable, List<String> arguments,
|
||||
// TODO(jcollins-g): Fix primitive obsession: consolidate parameters into
|
||||
// another object.
|
||||
{String? workingDirectory,
|
||||
Map<String, String>? environment,
|
||||
bool includeParentEnvironment = true,
|
||||
void Function(String)? perLine,
|
||||
int retries = 0,
|
||||
String? instance,
|
||||
bool allowNonzeroExit = false}) async {
|
||||
// TODO(jcollins-g): The closure wrapping we've done has made it impossible
|
||||
// to catch exceptions when calling runStreamed. Fix this.
|
||||
return maxParallel.runFutureFromClosure(() async {
|
||||
return retryClosure(
|
||||
() async => await runStreamedImmediate(executable, arguments,
|
||||
workingDirectory: workingDirectory,
|
||||
environment: environment,
|
||||
includeParentEnvironment: includeParentEnvironment,
|
||||
perLine: perLine,
|
||||
instance: instance,
|
||||
allowNonzeroExit: allowNonzeroExit),
|
||||
retries: retries);
|
||||
});
|
||||
}
|
||||
|
||||
/// A wrapper around start/await process.exitCode that will display the
|
||||
/// output of the executable continuously and fail on non-zero exit codes.
|
||||
/// It will also parse any valid JSON objects (one per line) it encounters
|
||||
/// on stdout/stderr, and return them. Returns null if no JSON objects
|
||||
/// were encountered, or if DRY_RUN is set to 1 in the execution environment.
|
||||
///
|
||||
/// Makes running programs in grinder similar to set -ex for bash, even on
|
||||
/// Windows (though some of the bashisms will no longer make sense).
|
||||
/// TODO(jcollins-g): refactor to return a stream of stderr/stdout lines
|
||||
/// and their associated JSON objects.
|
||||
Future<Iterable<Map>?> runStreamedImmediate(
|
||||
String executable, List<String> arguments,
|
||||
{String? workingDirectory,
|
||||
Map<String, String>? environment,
|
||||
bool includeParentEnvironment = true,
|
||||
void Function(String)? perLine,
|
||||
// A tag added to [context] to construct the line prefix.
|
||||
// Use this to indicate the process or processes with the tag
|
||||
// share something in common, like a hostname, a package, or a
|
||||
// multi-step procedure.
|
||||
String? instance,
|
||||
bool allowNonzeroExit = false}) async {
|
||||
String prefix = context.isNotEmpty
|
||||
? '$context${instance != null ? "-$instance" : ""}: '
|
||||
: '';
|
||||
|
||||
environment ??= {};
|
||||
environment.addAll(environmentDefaults);
|
||||
List<Map>? jsonObjects;
|
||||
|
||||
/// Parses json objects generated by the subprocess. If a json object
|
||||
/// contains the key 'message' or the keys 'data' and 'text', return that
|
||||
/// value as a collection of lines suitable for printing.
|
||||
Iterable<String> jsonCallback(String line) {
|
||||
if (perLine != null) perLine(line);
|
||||
Map? result;
|
||||
try {
|
||||
result = json.decoder.convert(line) as Map?;
|
||||
} on FormatException {
|
||||
// ignore
|
||||
}
|
||||
if (result != null) {
|
||||
jsonObjects ??= [];
|
||||
jsonObjects!.add(result);
|
||||
if (result.containsKey('message')) {
|
||||
line = result['message'] as String;
|
||||
} else if (result.containsKey('data') &&
|
||||
result['data'] is Map &&
|
||||
(result['data'] as Map).containsKey('key')) {
|
||||
line = result['data']['text'] as String;
|
||||
}
|
||||
}
|
||||
return line.split('\n');
|
||||
}
|
||||
|
||||
stderr.write('$prefix+ ');
|
||||
if (workingDirectory != null) stderr.write('(cd "$workingDirectory" && ');
|
||||
stderr.write(environment.keys.map((String key) {
|
||||
if (environment![key]!.contains(quotables)) {
|
||||
return "$key='${environment[key]}'";
|
||||
} else {
|
||||
return '$key=${environment[key]}';
|
||||
}
|
||||
}).join(' '));
|
||||
stderr.write(' ');
|
||||
stderr.write(executable);
|
||||
if (arguments.isNotEmpty) {
|
||||
for (String arg in arguments) {
|
||||
if (arg.contains(quotables)) {
|
||||
stderr.write(" '$arg'");
|
||||
} else {
|
||||
stderr.write(' $arg');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (workingDirectory != null) stderr.write(')');
|
||||
stderr.write('\n');
|
||||
|
||||
if (Platform.environment.containsKey('DRY_RUN')) return null;
|
||||
|
||||
String realExecutable = executable;
|
||||
final List<String> realArguments = [];
|
||||
if (Platform.isLinux) {
|
||||
// Use GNU coreutils to force line buffering. This makes sure that
|
||||
// subprocesses that die due to fatal signals do not chop off the
|
||||
// last few lines of their output.
|
||||
//
|
||||
// Dart does not actually do this (seems to flush manually) unless
|
||||
// the VM crashes.
|
||||
realExecutable = 'stdbuf';
|
||||
realArguments.addAll(['-o', 'L', '-e', 'L']);
|
||||
realArguments.add(executable);
|
||||
}
|
||||
realArguments.addAll(arguments);
|
||||
|
||||
Process process = await Process.start(realExecutable, realArguments,
|
||||
workingDirectory: workingDirectory,
|
||||
environment: environment,
|
||||
includeParentEnvironment: includeParentEnvironment);
|
||||
Future<void> stdoutFuture = _printStream(process.stdout, stdout,
|
||||
prefix: prefix, filter: jsonCallback);
|
||||
Future<void> stderrFuture = _printStream(process.stderr, stderr,
|
||||
prefix: prefix, filter: jsonCallback);
|
||||
await Future.wait([stderrFuture, stdoutFuture, process.exitCode]);
|
||||
|
||||
int exitCode = await process.exitCode;
|
||||
if (exitCode != 0 && !allowNonzeroExit) {
|
||||
throw ProcessException(executable, arguments,
|
||||
'SubprocessLauncher got non-zero exitCode: $exitCode', exitCode);
|
||||
}
|
||||
return jsonObjects;
|
||||
}
|
||||
|
||||
/// From flutter:dev/tools/dartdoc.dart, modified.
|
||||
static Future<void> _printStream(Stream<List<int>> stream, Stdout output,
|
||||
{String prefix = '', Iterable<String> Function(String line)? filter}) {
|
||||
filter ??= (line) => [line];
|
||||
return stream
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.expand(filter)
|
||||
.listen((String line) {
|
||||
output.write('$prefix$line'.trim());
|
||||
output.write('\n');
|
||||
}).asFuture();
|
||||
}
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:nnbd_migration/src/utilities/subprocess_launcher.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(SubprocessLauncherTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class SubprocessLauncherTest {
|
||||
Function(String)? outputCallback;
|
||||
List<String>? output;
|
||||
late Directory tempDir;
|
||||
|
||||
void setUp() async {
|
||||
output = [];
|
||||
outputCallback = output!.add;
|
||||
tempDir = await Directory.systemTemp.createTemp();
|
||||
}
|
||||
|
||||
void tearDown() async {
|
||||
await tempDir.delete(recursive: true);
|
||||
}
|
||||
|
||||
Future<void> test_subprocessPassesArgs() async {
|
||||
SubprocessLauncher launcher =
|
||||
SubprocessLauncher('test_subprocessPassesArgs');
|
||||
File testScript =
|
||||
File(path.join(tempDir.path, 'subprocess_test_script.dart'));
|
||||
await testScript.writeAsString(r'''
|
||||
import 'dart:io';
|
||||
|
||||
main(List<String> args) {
|
||||
print('args: $args');
|
||||
}''');
|
||||
|
||||
await launcher.runStreamedImmediate(
|
||||
Platform.resolvedExecutable, [testScript.path, 'testArgument'],
|
||||
perLine: outputCallback);
|
||||
expect(output, anyElement(contains('args: [testArgument]')));
|
||||
}
|
||||
|
||||
Future<void> test_subprocessPassesEnvironment() async {
|
||||
SubprocessLauncher launcher =
|
||||
SubprocessLauncher('test_subprocessPassesEnvironment');
|
||||
File testScript =
|
||||
File(path.join(tempDir.path, 'subprocess_test_script.dart'));
|
||||
await testScript.writeAsString(r'''
|
||||
import 'dart:io';
|
||||
|
||||
main(List<String> args) {
|
||||
print('environment: ${Platform.environment}');
|
||||
}''');
|
||||
|
||||
await launcher.runStreamedImmediate(
|
||||
Platform.resolvedExecutable, [testScript.path],
|
||||
environment: {'__SUBPROCESS_PASSES_ENVIRONMENT_TEST': 'yes'},
|
||||
perLine: outputCallback);
|
||||
expect(
|
||||
output,
|
||||
anyElement(contains(RegExp(
|
||||
'^environment: .*__SUBPROCESS_PASSES_ENVIRONMENT_TEST: yes'))));
|
||||
}
|
||||
|
||||
Future<void> test_subprocessRunsValidExecutable() async {
|
||||
SubprocessLauncher launcher =
|
||||
SubprocessLauncher('test_subprocessRunsValidExecutable');
|
||||
|
||||
await launcher.runStreamedImmediate(
|
||||
Platform.resolvedExecutable, ['--version'],
|
||||
perLine: outputCallback);
|
||||
expect(output, anyElement(contains('Dart')));
|
||||
}
|
||||
|
||||
Future<void> test_subprocessSetsWorkingDirectory() async {
|
||||
SubprocessLauncher launcher =
|
||||
SubprocessLauncher('test_subprocessSetsWorkingDirectory');
|
||||
File testScript =
|
||||
File(path.join(tempDir.path, 'subprocess_test_script.dart'));
|
||||
await testScript.writeAsString(r'''
|
||||
import 'dart:io';
|
||||
|
||||
main() {
|
||||
print('working directory: ${Directory.current.path}');
|
||||
}''');
|
||||
|
||||
await launcher.runStreamedImmediate(
|
||||
Platform.resolvedExecutable, [testScript.path],
|
||||
workingDirectory: tempDir.path, perLine: outputCallback);
|
||||
expect(
|
||||
output,
|
||||
anyElement(contains(
|
||||
'working directory: ${tempDir.resolveSymbolicLinksSync()}')));
|
||||
}
|
||||
|
||||
Future<void> test_subprocessThrowsOnNonzeroExitCode() async {
|
||||
SubprocessLauncher launcher =
|
||||
SubprocessLauncher('test_subprocessThrowsOnNonzeroExitCode');
|
||||
File testScript =
|
||||
File(path.join(tempDir.path, 'subprocess_test_script.dart'));
|
||||
await testScript.writeAsString(r'''
|
||||
import 'dart:io';
|
||||
|
||||
main() {
|
||||
exit(1);
|
||||
}''');
|
||||
await expectLater(
|
||||
() async => await launcher.runStreamedImmediate(
|
||||
Platform.resolvedExecutable, [testScript.path],
|
||||
perLine: outputCallback),
|
||||
throwsA(TypeMatcher<ProcessException>()));
|
||||
}
|
||||
|
||||
Future<void> test_subprocessWorksViaParallelSubprocessLimit() async {
|
||||
SubprocessLauncher launcher =
|
||||
SubprocessLauncher('test_subprocessWorksViaParallelSubprocessLimit');
|
||||
|
||||
await launcher.runStreamed(Platform.resolvedExecutable, ['--version'],
|
||||
perLine: outputCallback);
|
||||
expect(output, anyElement(contains('Dart')));
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@ import 'multi_future_tracker_test.dart' as multi_future_tracker_test;
|
|||
import 'scoped_set_test.dart' as scoped_set_test;
|
||||
import 'source_edit_diff_formatter_test.dart'
|
||||
as source_edit_diff_formatter_test;
|
||||
import 'subprocess_launcher_test.dart' as subprocess_launcher_test;
|
||||
import 'where_not_null_transformer_test.dart'
|
||||
as where_not_null_transformer_test;
|
||||
import 'where_or_null_transformer_test.dart' as where_or_null_transformer_test;
|
||||
|
@ -18,7 +17,6 @@ main() {
|
|||
multi_future_tracker_test.main();
|
||||
scoped_set_test.main();
|
||||
source_edit_diff_formatter_test.main();
|
||||
subprocess_launcher_test.main();
|
||||
where_not_null_transformer_test.main();
|
||||
where_or_null_transformer_test.main();
|
||||
});
|
||||
|
|
|
@ -1,220 +0,0 @@
|
|||
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/// Abstractions for the different sources of truth for different packages.
|
||||
library;
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:nnbd_migration/src/utilities/subprocess_launcher.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
final String defaultPlaygroundPath =
|
||||
Platform.environment['TRIAL_MIGRATION_PLAYGROUND'] ??
|
||||
resolveTildePath('~/.nnbd_trial_migration');
|
||||
|
||||
/// The pub cache inherited by this process.
|
||||
final String defaultPubCache =
|
||||
Platform.environment['PUB_CACHE'] ?? resolveTildePath('~/.pub-cache');
|
||||
|
||||
/// Returns the path to the SDK repository this script is a part of.
|
||||
final String thisSdkRepo = () {
|
||||
var maybeSdkRepoDir = Platform.script.toFilePath();
|
||||
while (maybeSdkRepoDir != path.dirname(maybeSdkRepoDir)) {
|
||||
maybeSdkRepoDir = path.dirname(maybeSdkRepoDir);
|
||||
if (File(path.join(maybeSdkRepoDir, 'README.dart-sdk')).existsSync()) {
|
||||
return maybeSdkRepoDir;
|
||||
}
|
||||
}
|
||||
throw UnsupportedError(
|
||||
'Script ${Platform.script} using this library must be within the SDK repository');
|
||||
}();
|
||||
Uri get thisSdkUri => Uri.file(thisSdkRepo);
|
||||
|
||||
/// Return a resolved path including the home directory in place of tilde
|
||||
/// references.
|
||||
String resolveTildePath(String originalPath) {
|
||||
if (!originalPath.startsWith('~/')) {
|
||||
return originalPath;
|
||||
}
|
||||
|
||||
String homeDir;
|
||||
|
||||
if (Platform.isWindows) {
|
||||
homeDir = path.absolute(Platform.environment['USERPROFILE']!);
|
||||
} else {
|
||||
homeDir = path.absolute(Platform.environment['HOME']!);
|
||||
}
|
||||
|
||||
return path.join(homeDir, originalPath.substring(2));
|
||||
}
|
||||
|
||||
/// Abstraction for a package fetched via Git.
|
||||
class GitPackage extends Package {
|
||||
static final RegExp _pathAndPeriodSplitter = RegExp('[\\/.]');
|
||||
final String _clonePath;
|
||||
final bool? _keepUpdated;
|
||||
final String label;
|
||||
|
||||
final Playground _playground;
|
||||
|
||||
SubprocessLauncher? _launcher;
|
||||
|
||||
String? _packagePath;
|
||||
|
||||
GitPackage._(this._clonePath, this._playground, this._keepUpdated,
|
||||
{String? name, this.label = 'master'})
|
||||
: super(name ?? _buildName(_clonePath));
|
||||
|
||||
SubprocessLauncher get launcher =>
|
||||
_launcher ??= SubprocessLauncher('$name-$label', _playground.env);
|
||||
|
||||
@override
|
||||
List<String?> get migrationPaths => [_packagePath];
|
||||
String get packagePath =>
|
||||
// TODO(jcollins-g): allow packages from subdirectories of clones
|
||||
_packagePath ??= path.join(_playground.playgroundPath, '$name-$label');
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '$_clonePath ($label)${_keepUpdated! ? ' [synced]' : ''}';
|
||||
}
|
||||
|
||||
/// Initialize the package with a shallow clone. Run only once per
|
||||
/// [GitPackage] instance.
|
||||
Future<void> _init() async {
|
||||
if (_keepUpdated! || !await Directory(packagePath).exists()) {
|
||||
// Clone or update.
|
||||
if (await Directory(packagePath).exists()) {
|
||||
await launcher.runStreamed('git', ['pull'],
|
||||
workingDirectory: packagePath);
|
||||
} else {
|
||||
await launcher.runStreamed('git',
|
||||
['clone', '--branch=$label', '--depth=1', _clonePath, packagePath],
|
||||
workingDirectory: _playground.playgroundPath);
|
||||
await launcher.runStreamed('git', ['checkout', '-b', '_test_migration'],
|
||||
workingDirectory: packagePath);
|
||||
await launcher.runStreamed(
|
||||
'git', ['branch', '--set-upstream-to', 'origin/$label'],
|
||||
workingDirectory: packagePath);
|
||||
// TODO(jcollins-g): allow for migrating dependencies?
|
||||
}
|
||||
await pubTracker.runFutureFromClosure(() =>
|
||||
launcher.runStreamed('pub', ['get'], workingDirectory: packagePath));
|
||||
}
|
||||
}
|
||||
|
||||
static Future<GitPackage> gitPackageFactory(
|
||||
String clonePath, Playground playground, bool? keepUpdated,
|
||||
{String? name, String label = 'master'}) async {
|
||||
GitPackage gitPackage = GitPackage._(clonePath, playground, keepUpdated,
|
||||
name: name, label: label);
|
||||
await gitPackage._init();
|
||||
return gitPackage;
|
||||
}
|
||||
|
||||
/// Calculate the "humanish" name of the clone (see `git help clone`).
|
||||
static String _buildName(String clonePath) {
|
||||
if (Directory(clonePath).existsSync()) {
|
||||
// assume we are cloning locally
|
||||
return path.basename(clonePath);
|
||||
}
|
||||
List<String> pathParts = clonePath.split(_pathAndPeriodSplitter);
|
||||
int indexOfName = pathParts.lastIndexOf('git') - 1;
|
||||
if (indexOfName < 0) {
|
||||
throw ArgumentError(
|
||||
'GitPackage can not figure out the name for $clonePath, pass it in manually?');
|
||||
}
|
||||
return pathParts[indexOfName];
|
||||
}
|
||||
}
|
||||
|
||||
/// Abstraction for an unmanaged package.
|
||||
class ManualPackage extends Package {
|
||||
final String _packagePath;
|
||||
ManualPackage(this._packagePath) : super(_packagePath);
|
||||
|
||||
@override
|
||||
List<String> get migrationPaths => [_packagePath];
|
||||
}
|
||||
|
||||
/// Base class for pub, github, SDK, or possibly other package sources.
|
||||
abstract class Package {
|
||||
final String name;
|
||||
|
||||
Package(this.name);
|
||||
|
||||
/// Returns the set of directories for this package.
|
||||
List<String?> get migrationPaths;
|
||||
|
||||
@override
|
||||
String toString() => name;
|
||||
}
|
||||
|
||||
class Playground {
|
||||
final String playgroundPath;
|
||||
|
||||
/// If [clean] is true, this will delete the playground. Otherwise,
|
||||
/// if it exists it will assume it is properly constructed.
|
||||
Playground(this.playgroundPath, bool clean) {
|
||||
Directory playground = Directory(playgroundPath);
|
||||
if (clean) {
|
||||
if (playground.existsSync()) {
|
||||
playground.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
||||
if (!playground.existsSync()) playground.createSync();
|
||||
}
|
||||
|
||||
/// Build an environment for subprocesses.
|
||||
Map<String, String> get env => {'PUB_CACHE': pubCachePath};
|
||||
|
||||
String get pubCachePath => path.join(playgroundPath, '.pub-cache');
|
||||
}
|
||||
|
||||
/// Abstraction for a package fetched via pub.
|
||||
class PubPackage extends Package {
|
||||
PubPackage(super.name, [String? version]) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
// TODO: implement packagePath
|
||||
List<String> get migrationPaths => throw UnimplementedError();
|
||||
}
|
||||
|
||||
/// Abstraction for compiled Dart SDKs (not this repository).
|
||||
class Sdk {
|
||||
/// The root of the compiled SDK.
|
||||
late final String sdkPath;
|
||||
|
||||
Sdk(String sdkPath) {
|
||||
this.sdkPath = path.canonicalize(sdkPath);
|
||||
}
|
||||
}
|
||||
|
||||
/// Abstraction for a package located within pkg or third_party/pkg.
|
||||
class SdkPackage extends Package {
|
||||
/// Where to find packages. Constructor searches in-order.
|
||||
static final List<String> _searchPaths = [
|
||||
'pkg',
|
||||
path.join('third_party', 'pkg'),
|
||||
];
|
||||
|
||||
late final String _packagePath;
|
||||
|
||||
SdkPackage(String name) : super(name) {
|
||||
for (String potentialPath
|
||||
in _searchPaths.map((p) => path.join(thisSdkRepo, p, name))) {
|
||||
if (Directory(potentialPath).existsSync()) {
|
||||
_packagePath = potentialPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@override
|
||||
List<String> get migrationPaths => [_packagePath];
|
||||
|
||||
@override
|
||||
String toString() => path.relative(_packagePath, from: thisSdkRepo);
|
||||
}
|
|
@ -1,359 +0,0 @@
|
|||
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// This is a hacked-together client of the NNBD migration API, intended for
|
||||
// early testing of the migration process. It runs a small hardcoded set of
|
||||
// packages through the migration engine and outputs statistics about the
|
||||
// result of migration, as well as categories (and counts) of exceptions that
|
||||
// occurred.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:analyzer/dart/analysis/results.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/diagnostic/diagnostic.dart';
|
||||
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
|
||||
import 'package:analyzer/src/generated/source.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
import 'package:args/args.dart';
|
||||
import 'package:nnbd_migration/nnbd_migration.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'src/package.dart';
|
||||
|
||||
void main(List<String> args) async {
|
||||
ArgResults parsedArgs = parseArguments(args)!;
|
||||
|
||||
Sdk sdk = Sdk(parsedArgs['sdk'] as String);
|
||||
|
||||
warnOnNoAssertions();
|
||||
|
||||
Playground playground =
|
||||
Playground(defaultPlaygroundPath, parsedArgs['clean'] as bool);
|
||||
|
||||
List<Package> packages = [
|
||||
for (String package in parsedArgs['packages'] as Iterable<String>)
|
||||
SdkPackage(package),
|
||||
for (String package in parsedArgs['manual_packages'] as Iterable<String>)
|
||||
ManualPackage(package),
|
||||
];
|
||||
|
||||
var packageNames = parsedArgs['git_packages'] as Iterable<String>;
|
||||
await Future.wait(packageNames.map((n) async => packages.add(
|
||||
await GitPackage.gitPackageFactory(
|
||||
n, playground, parsedArgs['update'] as bool?))));
|
||||
|
||||
String? categoryOfInterest =
|
||||
parsedArgs.rest.isEmpty ? null : parsedArgs.rest.single;
|
||||
|
||||
var listener = _Listener(categoryOfInterest,
|
||||
printExceptionNodeOnly: parsedArgs['exception_node_only'] as bool?);
|
||||
assert(listener.numExceptions == 0);
|
||||
var overallStartTime = DateTime.now();
|
||||
for (var package in packages) {
|
||||
print('Migrating $package');
|
||||
var startTime = DateTime.now();
|
||||
listener.currentPackage = package.name;
|
||||
var contextCollection = AnalysisContextCollectionImpl(
|
||||
includedPaths: package.migrationPaths as List<String>,
|
||||
sdkPath: sdk.sdkPath);
|
||||
|
||||
var files = <String>{};
|
||||
var previousExceptionCount = listener.numExceptions;
|
||||
for (var context in contextCollection.contexts) {
|
||||
var localFiles =
|
||||
context.contextRoot.analyzedFiles().where((s) => s.endsWith('.dart'));
|
||||
files.addAll(localFiles);
|
||||
var session = context.currentSession;
|
||||
var migration = NullabilityMigration(listener, permissive: true);
|
||||
for (var file in localFiles) {
|
||||
var resolvedUnit =
|
||||
await session.getResolvedUnit(file) as ResolvedUnitResult;
|
||||
if (!resolvedUnit.errors.any((e) => e.severity == Severity.error)) {
|
||||
migration.prepareInput(resolvedUnit);
|
||||
} else {
|
||||
print(' Skipping $file; it has errors.');
|
||||
}
|
||||
}
|
||||
for (var file in localFiles) {
|
||||
var resolvedUnit =
|
||||
await session.getResolvedUnit(file) as ResolvedUnitResult;
|
||||
if (!resolvedUnit.errors.any((e) => e.severity == Severity.error)) {
|
||||
migration.processInput(resolvedUnit);
|
||||
}
|
||||
}
|
||||
for (var file in localFiles) {
|
||||
var resolvedUnit =
|
||||
await session.getResolvedUnit(file) as ResolvedUnitResult;
|
||||
if (!resolvedUnit.errors.any((e) => e.severity == Severity.error)) {
|
||||
migration.finalizeInput(resolvedUnit);
|
||||
}
|
||||
}
|
||||
migration.finish();
|
||||
}
|
||||
|
||||
var endTime = DateTime.now();
|
||||
print(' Migrated $package in ${endTime.difference(startTime).inSeconds} '
|
||||
'seconds');
|
||||
print(' ${files.length} files found');
|
||||
var exceptionCount = listener.numExceptions - previousExceptionCount;
|
||||
print(' $exceptionCount exceptions in this package');
|
||||
}
|
||||
|
||||
var overallDuration = DateTime.now().difference(overallStartTime);
|
||||
print('${packages.length} packages migrated in ${overallDuration.inSeconds} '
|
||||
'seconds');
|
||||
print('${listener.numTypesMadeNullable} types made nullable');
|
||||
print('${listener.numNullChecksAdded} null checks added');
|
||||
print('${listener.numVariablesMarkedLate} variables marked late');
|
||||
print('${listener.numInsertedCasts} casts inserted');
|
||||
print('${listener.numInsertedParenthesis} parenthesis groupings inserted');
|
||||
print('${listener.numMetaImportsAdded} meta imports added');
|
||||
print('${listener.numRequiredAnnotationsAdded} required annotations added');
|
||||
print('${listener.numDeadCodeSegmentsFound} dead code segments found');
|
||||
print('and ${listener.numOtherEdits} other edits not categorized');
|
||||
print('${listener.numExceptions} exceptions in '
|
||||
'${listener.groupedExceptions.length} categories');
|
||||
|
||||
var sortedExceptions = [
|
||||
for (var entry in listener.groupedExceptions.entries)
|
||||
ExceptionCategory(entry.key, entry.value)
|
||||
]..sort((category1, category2) => category2.count.compareTo(category1.count));
|
||||
var exceptionalPackages =
|
||||
sortedExceptions.expand((category) => category.packageNames).toSet();
|
||||
print('Packages with exceptions: $exceptionalPackages');
|
||||
print('Exception categories:');
|
||||
for (var category in sortedExceptions) {
|
||||
print(' $category');
|
||||
}
|
||||
|
||||
if (categoryOfInterest == null) {
|
||||
print('\n(Note: to show stack traces & nodes for a particular failure,'
|
||||
' rerun with a search string as an argument.)');
|
||||
}
|
||||
}
|
||||
|
||||
ArgResults? parseArguments(List<String> args) {
|
||||
ArgParser argParser = ArgParser();
|
||||
ArgResults? parsedArgs;
|
||||
|
||||
argParser.addFlag('clean',
|
||||
abbr: 'c',
|
||||
defaultsTo: false,
|
||||
help: 'Recursively delete the playground directory before beginning.');
|
||||
|
||||
argParser.addFlag('help', abbr: 'h', help: 'Display options');
|
||||
|
||||
argParser.addFlag('exception_node_only',
|
||||
defaultsTo: false,
|
||||
negatable: true,
|
||||
help: 'Only print the exception node instead of the full stack trace.');
|
||||
|
||||
argParser.addFlag('update',
|
||||
abbr: 'u',
|
||||
defaultsTo: false,
|
||||
negatable: true,
|
||||
help: 'Auto-update fetched packages in the playground.');
|
||||
|
||||
argParser.addOption('sdk',
|
||||
abbr: 's',
|
||||
defaultsTo: path.dirname(path.dirname(Platform.resolvedExecutable)),
|
||||
help: 'Select the root of the SDK to analyze against for this run '
|
||||
'(compiled with --nnbd). For example: ../../xcodebuild/DebugX64NNBD/dart-sdk');
|
||||
|
||||
argParser.addMultiOption(
|
||||
'git_packages',
|
||||
abbr: 'g',
|
||||
defaultsTo: [],
|
||||
help: 'Shallow-clone the given git repositories into a playground area,'
|
||||
' run pub get on them, and migrate them.',
|
||||
);
|
||||
|
||||
argParser.addMultiOption(
|
||||
'manual_packages',
|
||||
abbr: 'm',
|
||||
defaultsTo: [],
|
||||
help: 'Run migration against packages in these directories. Does not '
|
||||
'run pub get, any git commands, or any other preparation.',
|
||||
);
|
||||
|
||||
argParser.addMultiOption(
|
||||
'packages',
|
||||
abbr: 'p',
|
||||
defaultsTo: [],
|
||||
help: 'The list of SDK packages to run the migration against.',
|
||||
);
|
||||
|
||||
try {
|
||||
parsedArgs = argParser.parse(args);
|
||||
} on ArgParserException {
|
||||
stderr.writeln(argParser.usage);
|
||||
exit(1);
|
||||
}
|
||||
if (parsedArgs['help'] as bool) {
|
||||
print(argParser.usage);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (parsedArgs.rest.length > 1) {
|
||||
throw 'invalid args. Specify *one* argument to get exceptions of interest.';
|
||||
}
|
||||
return parsedArgs;
|
||||
}
|
||||
|
||||
void printWarning(String warn) {
|
||||
stderr.writeln('''
|
||||
!!!
|
||||
!!! Warning! $warn
|
||||
!!!
|
||||
''');
|
||||
}
|
||||
|
||||
void warnOnNoAssertions() {
|
||||
try {
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
printWarning("You didn't --enable-asserts!");
|
||||
}
|
||||
|
||||
class ExceptionCategory {
|
||||
final String topOfStack;
|
||||
final List<MapEntry<String?, int>> exceptionCountPerPackage;
|
||||
|
||||
ExceptionCategory(this.topOfStack, Map<String?, int> exceptions)
|
||||
: exceptionCountPerPackage = exceptions.entries.toList()
|
||||
..sort((e1, e2) => e2.value.compareTo(e1.value));
|
||||
|
||||
int get count => exceptionCountPerPackage.length;
|
||||
|
||||
List<String?> get packageNames =>
|
||||
[for (var entry in exceptionCountPerPackage) entry.key];
|
||||
|
||||
Iterable<String> get packageNamesAndCounts =>
|
||||
exceptionCountPerPackage.map((entry) => '${entry.key} x${entry.value}');
|
||||
|
||||
String toString() => '$topOfStack (${packageNamesAndCounts.join(', ')})';
|
||||
}
|
||||
|
||||
class _Listener implements NullabilityMigrationListener {
|
||||
/// Set this to `true` to cause just the exception nodes to be printed when
|
||||
/// `_Listener.categoryOfInterest` is non-null. Set this to `false` to cause
|
||||
/// the full stack trace to be printed.
|
||||
final bool? printExceptionNodeOnly;
|
||||
|
||||
/// Set this to a non-null value to cause any exception to be printed in full
|
||||
/// if its category contains the string.
|
||||
final String? categoryOfInterest;
|
||||
|
||||
/// Exception mapped to a map of packages & exception counts.
|
||||
final groupedExceptions = <String, Map<String?, int>>{};
|
||||
|
||||
int numExceptions = 0;
|
||||
|
||||
int numTypesMadeNullable = 0;
|
||||
|
||||
int numVariablesMarkedLate = 0;
|
||||
|
||||
int numInsertedCasts = 0;
|
||||
|
||||
int numInsertedParenthesis = 0;
|
||||
|
||||
int numNullChecksAdded = 0;
|
||||
|
||||
int numMetaImportsAdded = 0;
|
||||
|
||||
int numRequiredAnnotationsAdded = 0;
|
||||
|
||||
int numDeadCodeSegmentsFound = 0;
|
||||
|
||||
int numOtherEdits = 0;
|
||||
|
||||
String? currentPackage;
|
||||
|
||||
_Listener(this.categoryOfInterest, {this.printExceptionNodeOnly = false});
|
||||
|
||||
@override
|
||||
void addEdit(Source source, SourceEdit edit) {
|
||||
if (edit.replacement == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (edit.replacement.contains('!')) {
|
||||
++numNullChecksAdded;
|
||||
}
|
||||
|
||||
if (edit.replacement.contains('(')) {
|
||||
++numInsertedParenthesis;
|
||||
}
|
||||
|
||||
if (edit.replacement == '?' && edit.length == 0) {
|
||||
++numTypesMadeNullable;
|
||||
} else if (edit.replacement == "import 'package:meta/meta.dart';\n" &&
|
||||
edit.length == 0) {
|
||||
++numMetaImportsAdded;
|
||||
} else if (edit.replacement == 'required ' && edit.length == 0) {
|
||||
++numRequiredAnnotationsAdded;
|
||||
} else if (edit.replacement == 'late ' && edit.length == 0) {
|
||||
++numVariablesMarkedLate;
|
||||
} else if (edit.replacement.startsWith(' as ') && edit.length == 0) {
|
||||
++numInsertedCasts;
|
||||
} else if ((edit.replacement == '/* ' ||
|
||||
edit.replacement == ' /*' ||
|
||||
edit.replacement == '; /*') &&
|
||||
edit.length == 0) {
|
||||
++numDeadCodeSegmentsFound;
|
||||
} else if ((edit.replacement == '*/ ' ||
|
||||
edit.replacement == ' */' ||
|
||||
edit.replacement == ')' ||
|
||||
edit.replacement == '!' ||
|
||||
edit.replacement == '(') &&
|
||||
edit.length == 0) {
|
||||
} else {
|
||||
numOtherEdits++;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void addSuggestion(String descriptions, Location location) {}
|
||||
|
||||
@override
|
||||
void reportException(
|
||||
Source? source, AstNode? node, Object exception, StackTrace stackTrace) {
|
||||
var category = _classifyStackTrace(stackTrace.toString().split('\n'));
|
||||
String detail = '''
|
||||
In file $source
|
||||
While processing $node
|
||||
Exception $exception
|
||||
$stackTrace
|
||||
''';
|
||||
if (categoryOfInterest != null && category.contains(categoryOfInterest!)) {
|
||||
if (printExceptionNodeOnly!) {
|
||||
print('$node');
|
||||
} else {
|
||||
print(detail);
|
||||
}
|
||||
}
|
||||
(groupedExceptions[category] ??= <String?, int>{})
|
||||
.update(currentPackage, (value) => ++value, ifAbsent: () => 1);
|
||||
++numExceptions;
|
||||
}
|
||||
|
||||
String _classifyStackTrace(List<String> stackTrace) {
|
||||
for (var entry in stackTrace) {
|
||||
if (entry.contains('EdgeBuilder._unimplemented')) continue;
|
||||
if (entry.contains('_AssertionError._doThrowNew')) continue;
|
||||
if (entry.contains('_AssertionError._throwNew')) continue;
|
||||
if (entry.contains('NodeBuilder._unimplemented')) continue;
|
||||
if (entry.contains('Object.noSuchMethod')) continue;
|
||||
if (entry.contains('List.[] (dart:core-patch/growable_array.dart')) {
|
||||
continue;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
return '???';
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
||||
# for details. All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
#
|
||||
|
||||
TRIAL_MIGRATION=`dirname "$0"`/trial_migration.dart
|
||||
|
||||
# Priority One, Group One, as defined at go/dart-null-safety-migration-order.
|
||||
p1g1 () {
|
||||
for n in charcode collection logging path pedantic term_glyph typed_data ; do
|
||||
echo "-g https://dart.googlesource.com/${n}.git"
|
||||
done
|
||||
# Some packages do not have googlesource mirrors; use GitHub directly.
|
||||
echo "-g https://github.com/google/vector_math.dart.git"
|
||||
# SDK-only packages.
|
||||
echo "-p meta"
|
||||
}
|
||||
|
||||
|
||||
# The current "official" set of parameters for the trial_migration script.
|
||||
set -x
|
||||
dart --enable-asserts ${TRIAL_MIGRATION} \
|
||||
$(p1g1) \
|
||||
"$@"
|
|
@ -1,148 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
# for details. All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
#
|
||||
|
||||
TRIAL_MIGRATION=`dirname "$0"`/trial_migration.dart
|
||||
|
||||
# Priority Two, Group One, as defined at go/dart-null-safety-migration-order.
|
||||
p2g1 () {
|
||||
echo "-g https://github.com/google/ansicolor-dart.git"
|
||||
echo "-g https://dart.googlesource.com/args.git"
|
||||
echo "-p dart_internal"
|
||||
echo "-g https://dart.googlesource.com/fixnum.git"
|
||||
echo "-g https://github.com/google/inject.dart.git"
|
||||
echo "-p js"
|
||||
echo "-g https://github.com/a14n/dart-js-wrapping.git"
|
||||
echo "-g https://dart.googlesource.com/mime.git"
|
||||
echo "-g https://github.com/xxgreg/mustache.git"
|
||||
echo "-g https://github.com/leonsenft/path_to_regexp.git"
|
||||
echo "-g https://github.com/petitparser/dart-petitparser.git"
|
||||
echo "-g https://github.com/google/platform.dart.git"
|
||||
echo "-g https://github.com/dart-lang/stream_transform.git"
|
||||
echo "-g https://github.com/dart-lang/sync_http.git"
|
||||
echo "-g https://github.com/srawlins/timezone.git"
|
||||
}
|
||||
|
||||
# Priority Two, Group Two, as defined at go/dart-null-safety-migration-order.
|
||||
p2g2 () {
|
||||
echo "-g https://github.com/google/ansicolor-dart.git"
|
||||
echo "-g https://dart.googlesource.com/cli_util.git"
|
||||
echo "-g https://github.com/dart-lang/clock.git"
|
||||
echo "-g https://github.com/kevmoo/completion.dart.git"
|
||||
echo "-g https://dart.googlesource.com/convert.git"
|
||||
echo "-g https://github.com/a14n/dart-google-maps.git"
|
||||
echo "-g https://github.com/dart-lang/http_server.git"
|
||||
echo "-g https://dart.googlesource.com/intl.git"
|
||||
echo "-p kernel"
|
||||
echo "-g https://dart.googlesource.com/package_config.git"
|
||||
# TODO(srawlins): Add protobuf, from monorepo
|
||||
# https://github.com/dart-lang/protobuf.
|
||||
echo "-g https://dart.googlesource.com/pub_semver.git"
|
||||
echo "-g https://github.com/google/quiver-dart.git"
|
||||
}
|
||||
|
||||
# Priority Two, Group Three, as defined at go/dart-null-safety-migration-order.
|
||||
p2g3 () {
|
||||
# TODO(srawlins): Add android_intent, from monorepo
|
||||
# https://github.com/flutter/plugins/tree/master/packages/android_intent.
|
||||
# SDK-only packages.
|
||||
echo "-g https://dart.googlesource.com/bazel_worker.git"
|
||||
echo "-g https://github.com/google/built_collection.dart.git"
|
||||
# TODO(srawlins): Add charts_common, from monorepo
|
||||
# https://github.com/google/charts/tree/master/charts_common.
|
||||
echo "-g https://github.com/jathak/cli_repl.git"
|
||||
echo "-g https://dart.googlesource.com/crypto.git"
|
||||
echo "-g https://dart.googlesource.com/csslib.git"
|
||||
echo "-g https://github.com/google/file.dart.git"
|
||||
# TODO(srawlins): Add front_end, which currently crashes.
|
||||
echo "-g https://github.com/reyerstudio/google-maps-markerclusterer.git"
|
||||
# TODO(srawlins): Add google_sign_in, from monorepo
|
||||
# https://github.com/flutter/plugins/tree/master/packages/google_sign_in.
|
||||
echo "-g https://dart.googlesource.com/http_multi_server.git"
|
||||
echo "-g https://github.com/dart-lang/observable.git"
|
||||
# TODO(srawlins): Add package_info, from monorepo
|
||||
# https://github.com/flutter/plugins/tree/master/packages/package_info.
|
||||
echo "-g https://dart.googlesource.com/pool.git"
|
||||
# TODO(srawlins): Add protoc_plugin, from monorepo
|
||||
# https://github.com/dart-lang/protobuf.
|
||||
echo "-g https://github.com/google/quiver-log.git"
|
||||
# TODO(srawlins): Add shared_preferences, from monorepo
|
||||
# https://github.com/flutter/plugins/tree/master/packages/shared_preferences.
|
||||
echo "-g https://dart.googlesource.com/source_maps.git"
|
||||
echo "-g https://dart.googlesource.com/string_scanner.git"
|
||||
echo "-g https://github.com/renggli/dart-xml.git"
|
||||
}
|
||||
|
||||
# Priority Two, Group Four, as defined at go/dart-null-safety-migration-order.
|
||||
p2g4 () {
|
||||
echo "-g https://github.com/brendan-duncan/archive.git"
|
||||
# TODO(srawlins): Add built_value, from monorepo
|
||||
# https://github.com/google/built_value.dart
|
||||
# Not including charted; concern is internal copy; not old published copy.
|
||||
echo "-g https://dart.googlesource.com/glob.git"
|
||||
echo "-g https://dart.googlesource.com/html.git"
|
||||
echo "-g https://dart.googlesource.com/http_parser.git"
|
||||
echo "-g https://dart.googlesource.com/json_rpc_2.git"
|
||||
# Not including observe; concern is internal copy; not old published copy.
|
||||
echo "-g https://github.com/google/process.dart.git"
|
||||
# Not including scissors; concern is internal copy; not old published copy.
|
||||
}
|
||||
|
||||
# Priority Two, Group Five, as defined at go/dart-null-safety-migration-order.
|
||||
p2g5 () {
|
||||
echo "-p analyzer"
|
||||
# Not including angular_forms; concern is internal copy; not old published copy.
|
||||
# Not including angular_router; concern is internal copy; not old published copy.
|
||||
# Not including angular_test; concern is internal copy; not old published copy.
|
||||
echo "-g https://github.com/dart-lang/code_builder.git"
|
||||
echo "-g https://dart.googlesource.com/http.git"
|
||||
echo "-g https://github.com/brendan-duncan/image.git"
|
||||
echo "-g https://dart.googlesource.com/shelf.git"
|
||||
}
|
||||
|
||||
# Priority Two, Group Six, as defined at go/dart-null-safety-migration-order.
|
||||
p2g6 () {
|
||||
echo "-p analyzer_plugin"
|
||||
# TODO(srawlins): Add build, from monorepo
|
||||
# https://github.com/dart-lang/build/tree/master/build.
|
||||
echo "-g https://github.com/dart-lang/coverage.git"
|
||||
echo "-g https://dart.googlesource.com/dart_style.git"
|
||||
# TODO(srawlins): Add flutter_test.
|
||||
echo "-g https://github.com/dart-lang/googleapis_auth.git"
|
||||
echo "-g https://github.com/dart-lang/intl_translation.git"
|
||||
echo "-g https://dart.googlesource.com/mockito.git"
|
||||
echo "-g https://dart.googlesource.com/package_resolver.git"
|
||||
# Not including pageloader ("2"); concern is internal copy; not old published copy.
|
||||
echo "-g https://dart.googlesource.com/shelf_static.git"
|
||||
echo "-g https://dart.googlesource.com/shelf_web_socket.git"
|
||||
}
|
||||
|
||||
# Priority Two, Group Seven, as defined at go/dart-null-safety-migration-order.
|
||||
p2g7 () {
|
||||
echo "-g https://github.com/dart-lang/grpc-dart.git"
|
||||
echo "-g https://github.com/google/pageloader.git" # This is pageloader3.
|
||||
echo "-g https://github.com/sass/dart-sass.git"
|
||||
echo "-g https://dart.googlesource.com/shelf_packages_handler.git"
|
||||
# TODO(srawlins): Add source_gen.
|
||||
echo "-g https://dart.googlesource.com/source_map_stack_trace.git"
|
||||
}
|
||||
|
||||
# Priority Two, Group Eight, as defined at go/dart-null-safety-migration-order.
|
||||
p2g8 () {
|
||||
# Not including angular_compiler; concern is internal copy; not old published copy.
|
||||
# TODO(srawlins): Add built_value_generator, from monorepo
|
||||
# https://github.com/google/built_value.dart.
|
||||
# TODO(srawlins): Add flutter_tools, from monorepo
|
||||
# https://github.com/flutter/flutter.
|
||||
# TODO(srawlins): Locate and add rpc_client.
|
||||
echo ""
|
||||
}
|
||||
|
||||
# The current "official" set of parameters for the trial_migration script.
|
||||
set -x
|
||||
dart --enable-asserts ${TRIAL_MIGRATION} \
|
||||
$(p2g1) $(p2g2) $(p2g3) $(p2g4) $(p2g5) $(p2g6) $(p2g7) $(p2g8) \
|
||||
"$@"
|
Loading…
Reference in a new issue