From 69f4dc0dcdab309411f27bd93c76e5f2a89e47a0 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Thu, 5 Jan 2023 15:59:07 +0000 Subject: [PATCH] Remove unused parts of migration tooling Change-Id: Ib18224f42880c47be63e6f6814db99ac05eced48 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278373 Reviewed-by: Samuel Rawlins Commit-Queue: Paul Berry --- .../src/utilities/subprocess_launcher.dart | 196 ---------- .../utilities/subprocess_launcher_test.dart | 131 ------- .../test/utilities/test_all.dart | 2 - pkg/nnbd_migration/tool/src/package.dart | 220 ----------- pkg/nnbd_migration/tool/trial_migration.dart | 359 ------------------ pkg/nnbd_migration/tool/trial_migration.sh | 26 -- pkg/nnbd_migration/tool/trial_migration_p2.sh | 148 -------- 7 files changed, 1082 deletions(-) delete mode 100644 pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart delete mode 100644 pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart delete mode 100644 pkg/nnbd_migration/tool/src/package.dart delete mode 100644 pkg/nnbd_migration/tool/trial_migration.dart delete mode 100755 pkg/nnbd_migration/tool/trial_migration.sh delete mode 100755 pkg/nnbd_migration/tool/trial_migration_p2.sh diff --git a/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart b/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart deleted file mode 100644 index edec874dbf3..00000000000 --- a/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart +++ /dev/null @@ -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 environmentDefaults; - - SubprocessLauncher(this.context, [Map? environment]) - : environmentDefaults = environment ?? {}; - - /// Wraps [runStreamedImmediate] as a closure around - /// [maxParallel.addFutureFromClosure]. - /// - /// This essentially implements a 'make -j N' limit for all subcommands. - Future?> runStreamed(String executable, List arguments, - // TODO(jcollins-g): Fix primitive obsession: consolidate parameters into - // another object. - {String? workingDirectory, - Map? 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?> runStreamedImmediate( - String executable, List arguments, - {String? workingDirectory, - Map? 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? 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 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 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 stdoutFuture = _printStream(process.stdout, stdout, - prefix: prefix, filter: jsonCallback); - Future 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 _printStream(Stream> stream, Stdout output, - {String prefix = '', Iterable 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(); - } -} diff --git a/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart b/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart deleted file mode 100644 index 5c6babb0d13..00000000000 --- a/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart +++ /dev/null @@ -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? 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 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 args) { - print('args: $args'); - }'''); - - await launcher.runStreamedImmediate( - Platform.resolvedExecutable, [testScript.path, 'testArgument'], - perLine: outputCallback); - expect(output, anyElement(contains('args: [testArgument]'))); - } - - Future 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 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 test_subprocessRunsValidExecutable() async { - SubprocessLauncher launcher = - SubprocessLauncher('test_subprocessRunsValidExecutable'); - - await launcher.runStreamedImmediate( - Platform.resolvedExecutable, ['--version'], - perLine: outputCallback); - expect(output, anyElement(contains('Dart'))); - } - - Future 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 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())); - } - - Future test_subprocessWorksViaParallelSubprocessLimit() async { - SubprocessLauncher launcher = - SubprocessLauncher('test_subprocessWorksViaParallelSubprocessLimit'); - - await launcher.runStreamed(Platform.resolvedExecutable, ['--version'], - perLine: outputCallback); - expect(output, anyElement(contains('Dart'))); - } -} diff --git a/pkg/nnbd_migration/test/utilities/test_all.dart b/pkg/nnbd_migration/test/utilities/test_all.dart index 9c04ec1e5ec..dc5758e38ed 100644 --- a/pkg/nnbd_migration/test/utilities/test_all.dart +++ b/pkg/nnbd_migration/test/utilities/test_all.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(); }); diff --git a/pkg/nnbd_migration/tool/src/package.dart b/pkg/nnbd_migration/tool/src/package.dart deleted file mode 100644 index 0fc154b0286..00000000000 --- a/pkg/nnbd_migration/tool/src/package.dart +++ /dev/null @@ -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 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 _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 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 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 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 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 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 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 _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 get migrationPaths => [_packagePath]; - - @override - String toString() => path.relative(_packagePath, from: thisSdkRepo); -} diff --git a/pkg/nnbd_migration/tool/trial_migration.dart b/pkg/nnbd_migration/tool/trial_migration.dart deleted file mode 100644 index d4f9d61e630..00000000000 --- a/pkg/nnbd_migration/tool/trial_migration.dart +++ /dev/null @@ -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 args) async { - ArgResults parsedArgs = parseArguments(args)!; - - Sdk sdk = Sdk(parsedArgs['sdk'] as String); - - warnOnNoAssertions(); - - Playground playground = - Playground(defaultPlaygroundPath, parsedArgs['clean'] as bool); - - List packages = [ - for (String package in parsedArgs['packages'] as Iterable) - SdkPackage(package), - for (String package in parsedArgs['manual_packages'] as Iterable) - ManualPackage(package), - ]; - - var packageNames = parsedArgs['git_packages'] as Iterable; - 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, - sdkPath: sdk.sdkPath); - - var files = {}; - 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 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> exceptionCountPerPackage; - - ExceptionCategory(this.topOfStack, Map exceptions) - : exceptionCountPerPackage = exceptions.entries.toList() - ..sort((e1, e2) => e2.value.compareTo(e1.value)); - - int get count => exceptionCountPerPackage.length; - - List get packageNames => - [for (var entry in exceptionCountPerPackage) entry.key]; - - Iterable 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 = >{}; - - 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] ??= {}) - .update(currentPackage, (value) => ++value, ifAbsent: () => 1); - ++numExceptions; - } - - String _classifyStackTrace(List 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 '???'; - } -} diff --git a/pkg/nnbd_migration/tool/trial_migration.sh b/pkg/nnbd_migration/tool/trial_migration.sh deleted file mode 100755 index 4db1c2bec40..00000000000 --- a/pkg/nnbd_migration/tool/trial_migration.sh +++ /dev/null @@ -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) \ - "$@" diff --git a/pkg/nnbd_migration/tool/trial_migration_p2.sh b/pkg/nnbd_migration/tool/trial_migration_p2.sh deleted file mode 100755 index bca1231f751..00000000000 --- a/pkg/nnbd_migration/tool/trial_migration_p2.sh +++ /dev/null @@ -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) \ - "$@"