From 3d9e5232180d6fc71567675e23fa8a4c91976243 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 6 Apr 2021 13:04:25 -0700 Subject: [PATCH] Switch script/tools over to the new analysis options (#3777) Removes the legacy analysis options override and fixes all resulting issues. This is a combination of dart fix and manual changes (mostly mechanical, but some small restructuring to address warnings more cleanly, such as creating typed structs from args when they are used repeatedly to avoid repeated casting, or making things that were unnecessarily public private). One small opportunistic extra cleanup is that the handling of null-safety prerelease versions is removed, as any new plugin would be written null-safe from the start, so we no longer need to allow those versions. Part of flutter/flutter#76229 --- script/tool/analysis_options.yaml | 1 - script/tool/lib/src/analyze_command.dart | 18 +- .../tool/lib/src/build_examples_command.dart | 59 +++--- script/tool/lib/src/common.dart | 83 ++++---- .../src/create_all_plugins_app_command.dart | 16 +- .../tool/lib/src/drive_examples_command.dart | 56 +++--- .../lib/src/firebase_test_lab_command.dart | 39 ++-- script/tool/lib/src/format_command.dart | 43 +++-- script/tool/lib/src/java_test_command.dart | 11 +- .../tool/lib/src/license_check_command.dart | 15 +- .../tool/lib/src/lint_podspecs_command.dart | 33 ++-- script/tool/lib/src/list_command.dart | 16 +- script/tool/lib/src/main.dart | 6 +- .../tool/lib/src/publish_check_command.dart | 27 +-- .../tool/lib/src/publish_plugin_command.dart | 24 +-- script/tool/lib/src/test_command.dart | 13 +- .../tool/lib/src/version_check_command.dart | 77 +++----- script/tool/lib/src/xctest_command.dart | 51 ++--- script/tool/test/analyze_command_test.dart | 37 ++-- .../test/build_examples_command_test.dart | 22 +-- script/tool/test/common_test.dart | 48 ++--- .../create_all_plugins_app_command_test.dart | 6 +- .../test/drive_examples_command_test.dart | 37 ++-- script/tool/test/firebase_test_lab_test.dart | 8 +- script/tool/test/java_test_command_test.dart | 8 +- .../tool/test/license_check_command_test.dart | 97 +++++----- .../tool/test/lint_podspecs_command_test.dart | 22 +-- script/tool/test/list_command_test.dart | 4 +- script/tool/test/mocks.dart | 2 +- .../tool/test/publish_check_command_test.dart | 28 +-- .../test/publish_plugin_command_test.dart | 34 ++-- script/tool/test/test_command_test.dart | 31 +-- script/tool/test/util.dart | 33 ++-- script/tool/test/version_check_test.dart | 181 ++++++++---------- script/tool/test/xctest_command_test.dart | 141 +++++++------- 35 files changed, 675 insertions(+), 652 deletions(-) delete mode 100644 script/tool/analysis_options.yaml diff --git a/script/tool/analysis_options.yaml b/script/tool/analysis_options.yaml deleted file mode 100644 index cda4f6e153..0000000000 --- a/script/tool/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: ../../analysis_options_legacy.yaml diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart index 9489303f56..e22bb0b17b 100644 --- a/script/tool/lib/src/analyze_command.dart +++ b/script/tool/lib/src/analyze_command.dart @@ -9,7 +9,9 @@ import 'package:path/path.dart' as p; import 'common.dart'; +/// A command to run Dart analysis on packages. class AnalyzeCommand extends PluginCommand { + /// Creates a analysis command instance. AnalyzeCommand( Directory packagesDir, FileSystem fileSystem, { @@ -31,9 +33,7 @@ class AnalyzeCommand extends PluginCommand { 'This command requires "pub" and "flutter" to be in your path.'; @override - Future run() async { - checkSharding(); - + Future run() async { print('Verifying analysis settings...'); final List files = packagesDir.listSync(recursive: true); for (final FileSystemEntity file in files) { @@ -42,8 +42,8 @@ class AnalyzeCommand extends PluginCommand { continue; } - final bool allowed = argResults[_customAnalysisFlag].any( - (String directory) => + final bool allowed = (argResults[_customAnalysisFlag] as List) + .any((String directory) => directory != null && directory.isNotEmpty && p.isWithin(p.join(packagesDir.path, directory), file.path)); @@ -62,7 +62,7 @@ class AnalyzeCommand extends PluginCommand { 'pub', ['global', 'activate', 'tuneup'], workingDir: packagesDir, exitOnError: true); - await for (Directory package in getPackages()) { + await for (final Directory package in getPackages()) { if (isFlutterPackage(package, fileSystem)) { await processRunner.runAndStream('flutter', ['packages', 'get'], workingDir: package, exitOnError: true); @@ -73,7 +73,7 @@ class AnalyzeCommand extends PluginCommand { } final List failingPackages = []; - await for (Directory package in getPlugins()) { + await for (final Directory package in getPlugins()) { final int exitCode = await processRunner.runAndStream( 'pub', ['global', 'run', 'tuneup', 'check'], workingDir: package); @@ -85,9 +85,9 @@ class AnalyzeCommand extends PluginCommand { print('\n\n'); if (failingPackages.isNotEmpty) { print('The following packages have analyzer errors (see above):'); - failingPackages.forEach((String package) { + for (final String package in failingPackages) { print(' * $package'); - }); + } throw ToolExit(1); } diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart index 966fdc9b99..0069c05868 100644 --- a/script/tool/lib/src/build_examples_command.dart +++ b/script/tool/lib/src/build_examples_command.dart @@ -11,7 +11,9 @@ import 'package:platform/platform.dart'; import 'common.dart'; +/// A command to build the example applications for packages. class BuildExamplesCommand extends PluginCommand { + /// Creates an instance of the build command. BuildExamplesCommand( Directory packagesDir, FileSystem fileSystem, { @@ -39,33 +41,40 @@ class BuildExamplesCommand extends PluginCommand { 'This command requires "flutter" to be in your path.'; @override - Future run() async { - if (!argResults[kIpa] && - !argResults[kApk] && - !argResults[kLinux] && - !argResults[kMacos] && - !argResults[kWeb] && - !argResults[kWindows]) { - print('None of --linux, --macos, --web, --windows, --apk, or --ipa were ' - 'specified, so not building anything.'); + Future run() async { + final List platformSwitches = [ + kApk, + kIpa, + kLinux, + kMacos, + kWeb, + kWindows, + ]; + final Map platforms = { + for (final String platform in platformSwitches) + platform: argResults[platform] as bool + }; + if (!platforms.values.any((bool enabled) => enabled)) { + print( + 'None of ${platformSwitches.map((String platform) => '--$platform').join(', ')} ' + 'were specified, so not building anything.'); return; } final String flutterCommand = - LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; + const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; - final String enableExperiment = argResults[kEnableExperiment]; + final String enableExperiment = argResults[kEnableExperiment] as String; - checkSharding(); final List failingPackages = []; - await for (Directory plugin in getPlugins()) { - for (Directory example in getExamplesForPlugin(plugin)) { + await for (final Directory plugin in getPlugins()) { + for (final Directory example in getExamplesForPlugin(plugin)) { final String packageName = p.relative(example.path, from: packagesDir.path); - if (argResults[kLinux]) { + if (platforms[kLinux]) { print('\nBUILDING Linux for $packageName'); if (isLinuxPlugin(plugin, fileSystem)) { - int buildExitCode = await processRunner.runAndStream( + final int buildExitCode = await processRunner.runAndStream( flutterCommand, [ 'build', @@ -82,10 +91,10 @@ class BuildExamplesCommand extends PluginCommand { } } - if (argResults[kMacos]) { + if (platforms[kMacos]) { print('\nBUILDING macOS for $packageName'); if (isMacOsPlugin(plugin, fileSystem)) { - int exitCode = await processRunner.runAndStream( + final int exitCode = await processRunner.runAndStream( flutterCommand, [ 'build', @@ -102,10 +111,10 @@ class BuildExamplesCommand extends PluginCommand { } } - if (argResults[kWeb]) { + if (platforms[kWeb]) { print('\nBUILDING web for $packageName'); if (isWebPlugin(plugin, fileSystem)) { - int buildExitCode = await processRunner.runAndStream( + final int buildExitCode = await processRunner.runAndStream( flutterCommand, [ 'build', @@ -122,10 +131,10 @@ class BuildExamplesCommand extends PluginCommand { } } - if (argResults[kWindows]) { + if (platforms[kWindows]) { print('\nBUILDING Windows for $packageName'); if (isWindowsPlugin(plugin, fileSystem)) { - int buildExitCode = await processRunner.runAndStream( + final int buildExitCode = await processRunner.runAndStream( flutterCommand, [ 'build', @@ -142,7 +151,7 @@ class BuildExamplesCommand extends PluginCommand { } } - if (argResults[kIpa]) { + if (platforms[kIpa]) { print('\nBUILDING IPA for $packageName'); if (isIosPlugin(plugin, fileSystem)) { final int exitCode = await processRunner.runAndStream( @@ -163,7 +172,7 @@ class BuildExamplesCommand extends PluginCommand { } } - if (argResults[kApk]) { + if (platforms[kApk]) { print('\nBUILDING APK for $packageName'); if (isAndroidPlugin(plugin, fileSystem)) { final int exitCode = await processRunner.runAndStream( @@ -188,7 +197,7 @@ class BuildExamplesCommand extends PluginCommand { if (failingPackages.isNotEmpty) { print('The following build are failing (see above for details):'); - for (String package in failingPackages) { + for (final String package in failingPackages) { print(' * $package'); } throw ToolExit(1); diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index 7d3063a20f..fc1fdca6a1 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io' as io; import 'dart:math'; @@ -15,7 +16,9 @@ import 'package:path/path.dart' as p; import 'package:pub_semver/pub_semver.dart'; import 'package:yaml/yaml.dart'; -typedef void Print(Object object); +/// The signature for a print handler for commands that allow overriding the +/// print destination. +typedef Print = void Function(Object object); /// Key for windows platform. const String kWindows = 'windows'; @@ -53,8 +56,9 @@ bool isFlutterPackage(FileSystemEntity entity, FileSystem fileSystem) { try { final File pubspecFile = fileSystem.file(p.join(entity.path, 'pubspec.yaml')); - final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()); - final YamlMap dependencies = pubspecYaml['dependencies']; + final YamlMap pubspecYaml = + loadYaml(pubspecFile.readAsStringSync()) as YamlMap; + final YamlMap dependencies = pubspecYaml['dependencies'] as YamlMap; if (dependencies == null) { return false; } @@ -89,16 +93,17 @@ bool pluginSupportsPlatform( try { final File pubspecFile = fileSystem.file(p.join(entity.path, 'pubspec.yaml')); - final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()); - final YamlMap flutterSection = pubspecYaml['flutter']; + final YamlMap pubspecYaml = + loadYaml(pubspecFile.readAsStringSync()) as YamlMap; + final YamlMap flutterSection = pubspecYaml['flutter'] as YamlMap; if (flutterSection == null) { return false; } - final YamlMap pluginSection = flutterSection['plugin']; + final YamlMap pluginSection = flutterSection['plugin'] as YamlMap; if (pluginSection == null) { return false; } - final YamlMap platforms = pluginSection['platforms']; + final YamlMap platforms = pluginSection['platforms'] as YamlMap; if (platforms == null) { // Legacy plugin specs are assumed to support iOS and Android. if (!pluginSection.containsKey('platforms')) { @@ -153,12 +158,16 @@ void printErrorAndExit({@required String errorMessage, int exitCode = 1}) { /// Error thrown when a command needs to exit with a non-zero exit code. class ToolExit extends Error { + /// Creates a tool exit with the given [exitCode]. ToolExit(this.exitCode); + /// The code that the process should exit with. final int exitCode; } -abstract class PluginCommand extends Command { +/// Interface definition for all commands in this tool. +abstract class PluginCommand extends Command { + /// Creates a command to operate on [packagesDir] with the given environment. PluginCommand( this.packagesDir, this.fileSystem, { @@ -230,23 +239,25 @@ abstract class PluginCommand extends Command { int _shardIndex; int _shardCount; + /// The shard of the overall command execution that this instance should run. int get shardIndex { if (_shardIndex == null) { - checkSharding(); + _checkSharding(); } return _shardIndex; } + /// The number of shards this command is divided into. int get shardCount { if (_shardCount == null) { - checkSharding(); + _checkSharding(); } return _shardCount; } - void checkSharding() { - final int shardIndex = int.tryParse(argResults[_shardIndexArg]); - final int shardCount = int.tryParse(argResults[_shardCountArg]); + void _checkSharding() { + final int shardIndex = int.tryParse(argResults[_shardIndexArg] as String); + final int shardCount = int.tryParse(argResults[_shardCountArg] as String); if (shardIndex == null) { usageException('$_shardIndexArg must be an integer'); } @@ -281,7 +292,7 @@ abstract class PluginCommand extends Command { final int start = min(shardIndex * shardSize, allPlugins.length); final int end = min(start + shardSize, allPlugins.length); - for (Directory plugin in allPlugins.sublist(start, end)) { + for (final Directory plugin in allPlugins.sublist(start, end)) { yield plugin; } } @@ -301,25 +312,28 @@ abstract class PluginCommand extends Command { /// "client library" package, which declares the API for the plugin, as /// well as one or more platform-specific implementations. Stream _getAllPlugins() async* { - Set plugins = Set.from(argResults[_pluginsArg]); + Set plugins = + Set.from(argResults[_pluginsArg] as List); final Set excludedPlugins = - Set.from(argResults[_excludeArg]); - final bool runOnChangedPackages = argResults[_runOnChangedPackagesArg]; + Set.from(argResults[_excludeArg] as List); + final bool runOnChangedPackages = + argResults[_runOnChangedPackagesArg] as bool; if (plugins.isEmpty && runOnChangedPackages) { plugins = await _getChangedPackages(); } - await for (FileSystemEntity entity + await for (final FileSystemEntity entity in packagesDir.list(followLinks: false)) { // A top-level Dart package is a plugin package. if (_isDartPackage(entity)) { if (!excludedPlugins.contains(entity.basename) && (plugins.isEmpty || plugins.contains(p.basename(entity.path)))) { - yield entity; + yield entity as Directory; } } else if (entity is Directory) { // Look for Dart packages under this top-level directory. - await for (FileSystemEntity subdir in entity.list(followLinks: false)) { + await for (final FileSystemEntity subdir + in entity.list(followLinks: false)) { if (_isDartPackage(subdir)) { // If --plugin=my_plugin is passed, then match all federated // plugins under 'my_plugin'. Also match if the exact plugin is @@ -334,7 +348,7 @@ abstract class PluginCommand extends Command { (plugins.isEmpty || plugins.contains(relativePath) || plugins.contains(basenamePath))) { - yield subdir; + yield subdir as Directory; } } } @@ -350,7 +364,7 @@ abstract class PluginCommand extends Command { /// Returns all Dart package folders (typically, plugin + example) of the /// plugins involved in this command execution. Stream getPackages() async* { - await for (Directory plugin in getPlugins()) { + await for (final Directory plugin in getPlugins()) { yield plugin; yield* plugin .list(recursive: true, followLinks: false) @@ -401,7 +415,7 @@ abstract class PluginCommand extends Command { /// Throws tool exit if [gitDir] nor root directory is a git directory. Future retrieveVersionFinder() async { final String rootDir = packagesDir.parent.absolute.path; - String baseSha = argResults[_kBaseSha]; + final String baseSha = argResults[_kBaseSha] as String; GitDir baseGitDir = gitDir; if (baseGitDir == null) { @@ -424,14 +438,14 @@ abstract class PluginCommand extends Command { final List allChangedFiles = await gitVersionFinder.getChangedFiles(); final Set packages = {}; - allChangedFiles.forEach((String path) { + for (final String path in allChangedFiles) { final List pathComponents = path.split('/'); final int packagesIndex = pathComponents.indexWhere((String element) => element == 'packages'); if (packagesIndex != -1) { packages.add(pathComponents[packagesIndex + 1]); } - }); + } if (packages.isNotEmpty) { final String changedPackages = packages.join(','); print(changedPackages); @@ -446,6 +460,7 @@ abstract class PluginCommand extends Command { /// We use this instead of directly running the process so it can be overridden /// in tests. class ProcessRunner { + /// Creates a new process runner. const ProcessRunner(); /// Run the [executable] with [args] and stream output to stderr and stdout. @@ -490,8 +505,8 @@ class ProcessRunner { Future run(String executable, List args, {Directory workingDir, bool exitOnError = false, - stdoutEncoding = io.systemEncoding, - stderrEncoding = io.systemEncoding}) async { + Encoding stdoutEncoding = io.systemEncoding, + Encoding stderrEncoding = io.systemEncoding}) async { return io.Process.run(executable, args, workingDirectory: workingDir?.path, stdoutEncoding: stdoutEncoding, @@ -569,15 +584,15 @@ class GitVersionFinder { Future> getChangedFiles() async { final String baseSha = await _getBaseSha(); final io.ProcessResult changedFilesCommand = await baseGitDir - .runCommand(['diff', '--name-only', '$baseSha', 'HEAD']); + .runCommand(['diff', '--name-only', baseSha, 'HEAD']); print('Determine diff with base sha: $baseSha'); - final String changedFilesStdout = changedFilesCommand.stdout.toString() ?? ''; + final String changedFilesStdout = + changedFilesCommand.stdout.toString() ?? ''; if (changedFilesStdout.isEmpty) { return []; } - final List changedFiles = changedFilesStdout - .split('\n') - ..removeWhere((element) => element.isEmpty); + final List changedFiles = changedFilesStdout.split('\n') + ..removeWhere((String element) => element.isEmpty); return changedFiles.toList(); } @@ -585,8 +600,8 @@ class GitVersionFinder { Future getPackageVersion(String pubspecPath, String gitRef) async { final io.ProcessResult gitShow = await baseGitDir.runCommand(['show', '$gitRef:$pubspecPath']); - final String fileContent = gitShow.stdout; - final String versionString = loadYaml(fileContent)['version']; + final String fileContent = gitShow.stdout as String; + final String versionString = loadYaml(fileContent)['version'] as String; return versionString == null ? null : Version.parse(versionString); } diff --git a/script/tool/lib/src/create_all_plugins_app_command.dart b/script/tool/lib/src/create_all_plugins_app_command.dart index aaa7f7fb96..4b5b4c6b8d 100644 --- a/script/tool/lib/src/create_all_plugins_app_command.dart +++ b/script/tool/lib/src/create_all_plugins_app_command.dart @@ -12,7 +12,9 @@ import 'package:pubspec_parse/pubspec_parse.dart'; import 'common.dart'; +/// A command to create an application that builds all in a single application. class CreateAllPluginsAppCommand extends PluginCommand { + /// Creates an instance of the builder command. CreateAllPluginsAppCommand( Directory packagesDir, FileSystem fileSystem, { @@ -36,7 +38,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { String get name => 'all-plugins-app'; @override - Future run() async { + Future run() async { final int exitCode = await _createApp(); if (exitCode != 0) { throw ToolExit(exitCode); @@ -76,7 +78,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { } final StringBuffer newGradle = StringBuffer(); - for (String line in gradleFile.readAsLinesSync()) { + for (final String line in gradleFile.readAsLinesSync()) { newGradle.writeln(line); if (line.contains('defaultConfig {')) { newGradle.writeln(' multiDexEnabled true'); @@ -105,7 +107,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { } final StringBuffer newManifest = StringBuffer(); - for (String line in manifestFile.readAsLinesSync()) { + for (final String line in manifestFile.readAsLinesSync()) { if (line.contains('package="com.example.all_plugins"')) { newManifest ..writeln('package="com.example.all_plugins"') @@ -149,7 +151,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { final Map pathDependencies = {}; - await for (Directory package in getPlugins()) { + await for (final Directory package in getPlugins()) { final String pluginName = package.path.split('/').last; final File pubspecFile = fileSystem.file(p.join(package.path, 'pubspec.yaml')); @@ -183,15 +185,15 @@ dev_dependencies:${_pubspecMapString(pubspec.devDependencies)} String _pubspecMapString(Map values) { final StringBuffer buffer = StringBuffer(); - for (MapEntry entry in values.entries) { + for (final MapEntry entry in values.entries) { buffer.writeln(); if (entry.value is VersionConstraint) { buffer.write(' ${entry.key}: ${entry.value}'); } else if (entry.value is SdkDependency) { - final SdkDependency dep = entry.value; + final SdkDependency dep = entry.value as SdkDependency; buffer.write(' ${entry.key}: \n sdk: ${dep.sdk}'); } else if (entry.value is PathDependency) { - final PathDependency dep = entry.value; + final PathDependency dep = entry.value as PathDependency; buffer.write(' ${entry.key}: \n path: ${dep.path}'); } else { throw UnimplementedError( diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index 54e0eee264..e52052a49a 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -8,7 +8,9 @@ import 'package:path/path.dart' as p; import 'package:platform/platform.dart'; import 'common.dart'; +/// A command to run the example applications for packages via Flutter driver. class DriveExamplesCommand extends PluginCommand { + /// Creates an instance of the drive command. DriveExamplesCommand( Directory packagesDir, FileSystem fileSystem, { @@ -48,20 +50,19 @@ class DriveExamplesCommand extends PluginCommand { 'integration_test/*_test.dart.'; @override - Future run() async { - checkSharding(); + Future run() async { final List failingTests = []; - final bool isLinux = argResults[kLinux]; - final bool isMacos = argResults[kMacos]; - final bool isWeb = argResults[kWeb]; - final bool isWindows = argResults[kWindows]; - await for (Directory plugin in getPlugins()) { + final bool isLinux = argResults[kLinux] == true; + final bool isMacos = argResults[kMacos] == true; + final bool isWeb = argResults[kWeb] == true; + final bool isWindows = argResults[kWindows] == true; + await for (final Directory plugin in getPlugins()) { final String flutterCommand = - LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; - for (Directory example in getExamplesForPlugin(plugin)) { + const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; + for (final Directory example in getExamplesForPlugin(plugin)) { final String packageName = p.relative(example.path, from: packagesDir.path); - if (!(await pluginSupportedOnCurrentPlatform(plugin, fileSystem))) { + if (!(await _pluginSupportedOnCurrentPlatform(plugin, fileSystem))) { continue; } final Directory driverTests = @@ -71,7 +72,7 @@ class DriveExamplesCommand extends PluginCommand { continue; } // Look for driver tests ending in _test.dart in test_driver/ - await for (FileSystemEntity test in driverTests.list()) { + await for (final FileSystemEntity test in driverTests.list()) { final String driverTestName = p.relative(test.path, from: driverTests.path); if (!driverTestName.endsWith('_test.dart')) { @@ -100,7 +101,7 @@ class DriveExamplesCommand extends PluginCommand { fileSystem.directory(p.join(example.path, 'integration_test')); if (await integrationTests.exists()) { - await for (FileSystemEntity integration_test + await for (final FileSystemEntity integration_test in integrationTests.list()) { if (!integration_test.basename.endsWith('_test.dart')) { continue; @@ -125,7 +126,8 @@ Tried searching for the following: final List driveArgs = ['drive']; - final String enableExperiment = argResults[kEnableExperiment]; + final String enableExperiment = + argResults[kEnableExperiment] as String; if (enableExperiment.isNotEmpty) { driveArgs.add('--enable-experiment=$enableExperiment'); } @@ -157,10 +159,10 @@ Tried searching for the following: ]); } - for (final targetPath in targetPaths) { + for (final String targetPath in targetPaths) { final int exitCode = await processRunner.runAndStream( flutterCommand, - [ + [ ...driveArgs, '--driver', p.join('test_driver', driverTestName), @@ -180,7 +182,7 @@ Tried searching for the following: if (failingTests.isNotEmpty) { print('The following driver tests are failing (see above for details):'); - for (String test in failingTests) { + for (final String test in failingTests) { print(' * $test'); } throw ToolExit(1); @@ -189,16 +191,16 @@ Tried searching for the following: print('All driver tests successful!'); } - Future pluginSupportedOnCurrentPlatform( + Future _pluginSupportedOnCurrentPlatform( FileSystemEntity plugin, FileSystem fileSystem) async { - final bool isAndroid = argResults[kAndroid]; - final bool isIOS = argResults[kIos]; - final bool isLinux = argResults[kLinux]; - final bool isMacos = argResults[kMacos]; - final bool isWeb = argResults[kWeb]; - final bool isWindows = argResults[kWindows]; + final bool isAndroid = argResults[kAndroid] == true; + final bool isIOS = argResults[kIos] == true; + final bool isLinux = argResults[kLinux] == true; + final bool isMacos = argResults[kMacos] == true; + final bool isWeb = argResults[kWeb] == true; + final bool isWindows = argResults[kWindows] == true; if (isAndroid) { - return (isAndroidPlugin(plugin, fileSystem)); + return isAndroidPlugin(plugin, fileSystem); } if (isIOS) { return isIosPlugin(plugin, fileSystem); @@ -216,9 +218,9 @@ Tried searching for the following: return isWindowsPlugin(plugin, fileSystem); } // When we are here, no flags are specified. Only return true if the plugin - // supports Android for legacy command support. TODO(cyanglaz): Make Android - // flag also required like other platforms (breaking change). - // https://github.com/flutter/flutter/issues/58285 + // supports Android for legacy command support. + // TODO(cyanglaz): Make Android flag also required like other platforms + // (breaking change). https://github.com/flutter/flutter/issues/58285 return isAndroidPlugin(plugin, fileSystem); } } diff --git a/script/tool/lib/src/firebase_test_lab_command.dart b/script/tool/lib/src/firebase_test_lab_command.dart index 8e0abd5074..2998522da0 100644 --- a/script/tool/lib/src/firebase_test_lab_command.dart +++ b/script/tool/lib/src/firebase_test_lab_command.dart @@ -11,7 +11,9 @@ import 'package:uuid/uuid.dart'; import 'common.dart'; +/// A command to run tests via Firebase test lab. class FirebaseTestLabCommand extends PluginCommand { + /// Creates an instance of the test runner command. FirebaseTestLabCommand( Directory packagesDir, FileSystem fileSystem, { @@ -76,11 +78,11 @@ class FirebaseTestLabCommand extends PluginCommand { 'activate-service-account', '--key-file=${argResults['service-key']}', ]); - int exitCode = await processRunner.runAndStream('gcloud', [ + final int exitCode = await processRunner.runAndStream('gcloud', [ 'config', 'set', 'project', - argResults['project'], + argResults['project'] as String, ]); if (exitCode == 0) { _print('\nFirebase project configured.'); @@ -93,8 +95,7 @@ class FirebaseTestLabCommand extends PluginCommand { } @override - Future run() async { - checkSharding(); + Future run() async { final Stream packagesWithTests = getPackages().where( (Directory d) => isFlutterPackage(d, fileSystem) && @@ -107,7 +108,7 @@ class FirebaseTestLabCommand extends PluginCommand { final List missingFlutterBuild = []; int resultsCounter = 0; // We use a unique GCS bucket for each Firebase Test Lab run - await for (Directory package in packagesWithTests) { + await for (final Directory package in packagesWithTests) { // See https://github.com/flutter/flutter/issues/38983 final Directory exampleDirectory = @@ -119,7 +120,7 @@ class FirebaseTestLabCommand extends PluginCommand { final Directory androidDirectory = fileSystem.directory(p.join(exampleDirectory.path, 'android')); - final String enableExperiment = argResults[kEnableExperiment]; + final String enableExperiment = argResults[kEnableExperiment] as String; final String encodedEnableExperiment = Uri.encodeComponent('--enable-experiment=$enableExperiment'); @@ -166,16 +167,18 @@ class FirebaseTestLabCommand extends PluginCommand { // Look for tests recursively in folders that start with 'test' and that // live in the root or example folders. bool isTestDir(FileSystemEntity dir) { - return p.basename(dir.path).startsWith('test') || - p.basename(dir.path) == 'integration_test'; + return dir is Directory && + (p.basename(dir.path).startsWith('test') || + p.basename(dir.path) == 'integration_test'); } - final List testDirs = - package.listSync().where(isTestDir).toList(); + final List testDirs = + package.listSync().where(isTestDir).cast().toList(); final Directory example = fileSystem.directory(p.join(package.path, 'example')); - testDirs.addAll(example.listSync().where(isTestDir).toList()); - for (Directory testDir in testDirs) { + testDirs.addAll( + example.listSync().where(isTestDir).cast().toList()); + for (final Directory testDir in testDirs) { bool isE2ETest(FileSystemEntity file) { return file.path.endsWith('_e2e.dart') || (file.parent.basename == 'integration_test' && @@ -186,7 +189,7 @@ class FirebaseTestLabCommand extends PluginCommand { .listSync(recursive: true, followLinks: true) .where(isE2ETest) .toList(); - for (FileSystemEntity test in testFiles) { + for (final FileSystemEntity test in testFiles) { exitCode = await processRunner.runAndStream( p.join(androidDirectory.path, _gradleWrapper), [ @@ -205,7 +208,7 @@ class FirebaseTestLabCommand extends PluginCommand { continue; } final String buildId = io.Platform.environment['CIRRUS_BUILD_ID']; - final String testRunId = argResults['test-run-id']; + final String testRunId = argResults['test-run-id'] as String; final String resultsDir = 'plugins_android_test/$packageName/$buildId/$testRunId/${resultsCounter++}/'; final List args = [ @@ -222,9 +225,9 @@ class FirebaseTestLabCommand extends PluginCommand { '--timeout', '5m', '--results-bucket=${argResults['results-bucket']}', - '--results-dir=${resultsDir}', + '--results-dir=$resultsDir', ]; - for (String device in argResults['device']) { + for (final String device in argResults['device'] as List) { args.addAll(['--device', device]); } exitCode = await processRunner.runAndStream('gcloud', args, @@ -243,14 +246,14 @@ class FirebaseTestLabCommand extends PluginCommand { _print( 'The instrumentation tests for the following packages are failing (see above for' 'details):'); - for (String package in failingPackages) { + for (final String package in failingPackages) { _print(' * $package'); } } if (missingFlutterBuild.isNotEmpty) { _print('Run "pub global run flutter_plugin_tools build-examples --apk" on' 'the following packages before executing tests again:'); - for (String package in missingFlutterBuild) { + for (final String package in missingFlutterBuild) { _print(' * $package'); } } diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index d849dc9aa9..19b6004d24 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -16,7 +16,9 @@ import 'common.dart'; const String _googleFormatterUrl = 'https://github.com/google/google-java-format/releases/download/google-java-format-1.3/google-java-format-1.3-all-deps.jar'; +/// A command to format all package code. class FormatCommand extends PluginCommand { + /// Creates an instance of the format command. FormatCommand( Directory packagesDir, FileSystem fileSystem, { @@ -38,15 +40,14 @@ class FormatCommand extends PluginCommand { 'your path.'; @override - Future run() async { - checkSharding(); + Future run() async { final String googleFormatterPath = await _getGoogleFormatterPath(); await _formatDart(); await _formatJava(googleFormatterPath); await _formatCppAndObjectiveC(); - if (argResults['fail-on-change']) { + if (argResults['fail-on-change'] == true) { final bool modified = await _didModifyAnything(); if (modified) { throw ToolExit(1); @@ -61,15 +62,14 @@ class FormatCommand extends PluginCommand { print('\n\n'); - if (modifiedFiles.stdout.isEmpty) { + final String stdout = modifiedFiles.stdout as String; + if (stdout.isEmpty) { print('All files formatted correctly.'); return false; } print('These files are not formatted correctly (see diff below):'); - LineSplitter.split(modifiedFiles.stdout) - .map((String line) => ' $line') - .forEach(print); + LineSplitter.split(stdout).map((String line) => ' $line').forEach(print); print('\nTo fix run "pub global activate flutter_plugin_tools && ' 'pub global run flutter_plugin_tools format" or copy-paste ' @@ -83,33 +83,34 @@ class FormatCommand extends PluginCommand { return true; } - Future _formatCppAndObjectiveC() async { + Future _formatCppAndObjectiveC() async { print('Formatting all .cc, .cpp, .mm, .m, and .h files...'); - final Iterable allFiles = [] - ..addAll(await _getFilesWithExtension('.h')) - ..addAll(await _getFilesWithExtension('.m')) - ..addAll(await _getFilesWithExtension('.mm')) - ..addAll(await _getFilesWithExtension('.cc')) - ..addAll(await _getFilesWithExtension('.cpp')); + final Iterable allFiles = [ + ...await _getFilesWithExtension('.h'), + ...await _getFilesWithExtension('.m'), + ...await _getFilesWithExtension('.mm'), + ...await _getFilesWithExtension('.cc'), + ...await _getFilesWithExtension('.cpp'), + ]; // Split this into multiple invocations to avoid a // 'ProcessException: Argument list too long'. final Iterable> batches = partition(allFiles, 100); - for (List batch in batches) { - await processRunner.runAndStream(argResults['clang-format'], - ['-i', '--style=Google']..addAll(batch), + for (final List batch in batches) { + await processRunner.runAndStream(argResults['clang-format'] as String, + ['-i', '--style=Google', ...batch], workingDir: packagesDir, exitOnError: true); } } - Future _formatJava(String googleFormatterPath) async { + Future _formatJava(String googleFormatterPath) async { print('Formatting all .java files...'); final Iterable javaFiles = await _getFilesWithExtension('.java'); await processRunner.runAndStream('java', - ['-jar', googleFormatterPath, '--replace']..addAll(javaFiles), + ['-jar', googleFormatterPath, '--replace', ...javaFiles], workingDir: packagesDir, exitOnError: true); } - Future _formatDart() async { + Future _formatDart() async { // This actually should be fine for non-Flutter Dart projects, no need to // specifically shell out to dartfmt -w in that case. print('Formatting all .dart files...'); @@ -119,7 +120,7 @@ class FormatCommand extends PluginCommand { 'No .dart files to format. If you set the `--exclude` flag, most likey they were skipped'); } else { await processRunner.runAndStream( - 'flutter', ['format']..addAll(dartFiles), + 'flutter', ['format', ...dartFiles], workingDir: packagesDir, exitOnError: true); } } diff --git a/script/tool/lib/src/java_test_command.dart b/script/tool/lib/src/java_test_command.dart index 4b6a561b9e..5df97627ce 100644 --- a/script/tool/lib/src/java_test_command.dart +++ b/script/tool/lib/src/java_test_command.dart @@ -9,7 +9,9 @@ import 'package:path/path.dart' as p; import 'common.dart'; +/// A command to run the Java tests of Android plugins. class JavaTestCommand extends PluginCommand { + /// Creates an instance of the test runner. JavaTestCommand( Directory packagesDir, FileSystem fileSystem, { @@ -27,8 +29,7 @@ class JavaTestCommand extends PluginCommand { static const String _gradleWrapper = 'gradlew'; @override - Future run() async { - checkSharding(); + Future run() async { final Stream examplesWithTests = getExamples().where( (Directory d) => isFlutterPackage(d, fileSystem) && @@ -41,7 +42,7 @@ class JavaTestCommand extends PluginCommand { final List failingPackages = []; final List missingFlutterBuild = []; - await for (Directory example in examplesWithTests) { + await for (final Directory example in examplesWithTests) { final String packageName = p.relative(example.path, from: packagesDir.path); print('\nRUNNING JAVA TESTS for $packageName'); @@ -71,14 +72,14 @@ class JavaTestCommand extends PluginCommand { print( 'The Java tests for the following packages are failing (see above for' 'details):'); - for (String package in failingPackages) { + for (final String package in failingPackages) { print(' * $package'); } } if (missingFlutterBuild.isNotEmpty) { print('Run "pub global run flutter_plugin_tools build-examples --apk" on' 'the following packages before executing tests again:'); - for (String package in missingFlutterBuild) { + for (final String package in missingFlutterBuild) { print(' * $package'); } } diff --git a/script/tool/lib/src/license_check_command.dart b/script/tool/lib/src/license_check_command.dart index 4f78e4e966..adb2f93152 100644 --- a/script/tool/lib/src/license_check_command.dart +++ b/script/tool/lib/src/license_check_command.dart @@ -62,8 +62,8 @@ final List _thirdPartyLicenseBlockRegexes = [ // Slight variants are not accepted because they may prevent consolidation in // tools that assemble all licenses used in distributed applications. // standardized. -final String _fullBsdLicenseText = - '''Copyright 2013 The Flutter Authors. All rights reserved. +const String _fullBsdLicenseText = ''' +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -110,7 +110,7 @@ class LicenseCheckCommand extends PluginCommand { 'Ensures that all code files have copyright/license blocks.'; @override - Future run() async { + Future run() async { final Iterable codeFiles = (await _getAllFiles()).where((File file) => _codeFileExtensions.contains(p.extension(file.path)) && !_shouldIgnoreFile(file)); @@ -160,7 +160,7 @@ class LicenseCheckCommand extends PluginCommand { if (_isThirdParty(file)) { if (!_thirdPartyLicenseBlockRegexes - .any((regex) => regex.hasMatch(content))) { + .any((RegExp regex) => regex.hasMatch(content))) { unrecognizedThirdPartyFiles.add(file); } } else { @@ -175,7 +175,8 @@ class LicenseCheckCommand extends PluginCommand { _print('\n'); // Sort by path for more usable output. - final pathCompare = (File a, File b) => a.path.compareTo(b.path); + final int Function(File, File) pathCompare = + (File a, File b) => a.path.compareTo(b.path); incorrectFirstPartyFiles.sort(pathCompare); unrecognizedThirdPartyFiles.sort(pathCompare); @@ -200,7 +201,7 @@ class LicenseCheckCommand extends PluginCommand { 'the new third-party license block.\n'); } - bool succeeded = + final bool succeeded = incorrectFirstPartyFiles.isEmpty && unrecognizedThirdPartyFiles.isEmpty; if (succeeded) { _print('All source files passed validation!'); @@ -230,7 +231,7 @@ class LicenseCheckCommand extends PluginCommand { 'Please ensure that they use the exact format used in this repository".\n'); } - bool succeeded = incorrectLicenseFiles.isEmpty; + final bool succeeded = incorrectLicenseFiles.isEmpty; if (succeeded) { _print('All LICENSE files passed validation!'); } diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart index 3261072d71..1fe6b71cf1 100644 --- a/script/tool/lib/src/lint_podspecs_command.dart +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -12,19 +12,19 @@ import 'package:platform/platform.dart'; import 'common.dart'; -typedef void Print(Object object); - /// Lint the CocoaPod podspecs and run unit tests. /// /// See https://guides.cocoapods.org/terminal/commands.html#pod_lib_lint. class LintPodspecsCommand extends PluginCommand { + /// Creates an instance of the linter command. LintPodspecsCommand( Directory packagesDir, FileSystem fileSystem, { ProcessRunner processRunner = const ProcessRunner(), - this.platform = const LocalPlatform(), + Platform platform = const LocalPlatform(), Print print = print, - }) : _print = print, + }) : _platform = platform, + _print = print, super(packagesDir, fileSystem, processRunner: processRunner) { argParser.addMultiOption('skip', help: @@ -47,26 +47,24 @@ class LintPodspecsCommand extends PluginCommand { 'Runs "pod lib lint" on all iOS and macOS plugin podspecs.\n\n' 'This command requires "pod" and "flutter" to be in your path. Runs on macOS only.'; - final Platform platform; + final Platform _platform; final Print _print; @override - Future run() async { - if (!platform.isMacOS) { + Future run() async { + if (!_platform.isMacOS) { _print('Detected platform is not macOS, skipping podspec lint'); return; } - checkSharding(); - await processRunner.runAndExitOnError('which', ['pod'], workingDir: packagesDir); _print('Starting podspec lint test'); final List failingPlugins = []; - for (File podspec in await _podspecsToLint()) { + for (final File podspec in await _podspecsToLint()) { if (!await _lintPodspec(podspec)) { failingPlugins.add(p.basenameWithoutExtension(podspec.path)); } @@ -75,9 +73,9 @@ class LintPodspecsCommand extends PluginCommand { _print('\n\n'); if (failingPlugins.isNotEmpty) { _print('The following plugins have podspec errors (see above):'); - failingPlugins.forEach((String plugin) { + for (final String plugin in failingPlugins) { _print(' * $plugin'); - }); + } throw ToolExit(1); } } @@ -86,7 +84,8 @@ class LintPodspecsCommand extends PluginCommand { final List podspecs = await getFiles().where((File entity) { final String filePath = entity.path; return p.extension(filePath) == '.podspec' && - !argResults['skip'].contains(p.basenameWithoutExtension(filePath)); + !(argResults['skip'] as List) + .contains(p.basenameWithoutExtension(filePath)); }).toList(); podspecs.sort( @@ -102,12 +101,14 @@ class LintPodspecsCommand extends PluginCommand { _print('Linting $podspecBasename'); // Lint plugin as framework (use_frameworks!). - final ProcessResult frameworkResult = await _runPodLint(podspecPath, libraryLint: true); + final ProcessResult frameworkResult = + await _runPodLint(podspecPath, libraryLint: true); _print(frameworkResult.stdout); _print(frameworkResult.stderr); // Lint plugin as library. - final ProcessResult libraryResult = await _runPodLint(podspecPath, libraryLint: false); + final ProcessResult libraryResult = + await _runPodLint(podspecPath, libraryLint: false); _print(libraryResult.stdout); _print(libraryResult.stderr); @@ -116,7 +117,7 @@ class LintPodspecsCommand extends PluginCommand { Future _runPodLint(String podspecPath, {bool libraryLint}) async { - final bool allowWarnings = argResults['ignore-warnings'] + final bool allowWarnings = (argResults['ignore-warnings'] as List) .contains(p.basenameWithoutExtension(podspecPath)); final List arguments = [ 'lib', diff --git a/script/tool/lib/src/list_command.dart b/script/tool/lib/src/list_command.dart index 3571786ab7..49302a91ad 100644 --- a/script/tool/lib/src/list_command.dart +++ b/script/tool/lib/src/list_command.dart @@ -8,7 +8,10 @@ import 'package:file/file.dart'; import 'common.dart'; +/// A command to list different types of repository content. class ListCommand extends PluginCommand { + /// Creates an instance of the list command, whose behavior depends on the + /// 'type' argument it provides. ListCommand(Directory packagesDir, FileSystem fileSystem) : super(packagesDir, fileSystem) { argParser.addOption( @@ -32,26 +35,25 @@ class ListCommand extends PluginCommand { final String description = 'Lists packages or files'; @override - Future run() async { - checkSharding(); - switch (argResults[_type]) { + Future run() async { + switch (argResults[_type] as String) { case _plugin: - await for (Directory package in getPlugins()) { + await for (final Directory package in getPlugins()) { print(package.path); } break; case _example: - await for (Directory package in getExamples()) { + await for (final Directory package in getExamples()) { print(package.path); } break; case _package: - await for (Directory package in getPackages()) { + await for (final Directory package in getPackages()) { print(package.path); } break; case _file: - await for (File file in getFiles()) { + await for (final File file in getFiles()) { print(file.path); } break; diff --git a/script/tool/lib/src/main.dart b/script/tool/lib/src/main.dart index 2e29aac1e7..6fba3b34b9 100644 --- a/script/tool/lib/src/main.dart +++ b/script/tool/lib/src/main.dart @@ -27,7 +27,7 @@ import 'version_check_command.dart'; import 'xctest_command.dart'; void main(List args) { - final FileSystem fileSystem = const LocalFileSystem(); + const FileSystem fileSystem = LocalFileSystem(); Directory packagesDir = fileSystem .directory(p.join(fileSystem.currentDirectory.path, 'packages')); @@ -41,7 +41,7 @@ void main(List args) { } } - final CommandRunner commandRunner = CommandRunner( + final CommandRunner commandRunner = CommandRunner( 'pub global run flutter_plugin_tools', 'Productivity utils for hosting multiple plugins within one repository.') ..addCommand(AnalyzeCommand(packagesDir, fileSystem)) @@ -61,7 +61,7 @@ void main(List args) { ..addCommand(XCTestCommand(packagesDir, fileSystem)); commandRunner.run(args).catchError((Object e) { - final ToolExit toolExit = e; + final ToolExit toolExit = e as ToolExit; io.exit(toolExit.exitCode); }, test: (Object e) => e is ToolExit); } diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index fb57dfcd6d..07bf0aa866 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -11,7 +11,9 @@ import 'package:pubspec_parse/pubspec_parse.dart'; import 'common.dart'; +/// A command to check that packages are publishable via 'dart publish'. class PublishCheckCommand extends PluginCommand { + /// Creates an instance of the publish command. PublishCheckCommand( Directory packagesDir, FileSystem fileSystem, { @@ -26,12 +28,13 @@ class PublishCheckCommand extends PluginCommand { 'Checks to make sure that a plugin *could* be published.'; @override - Future run() async { - checkSharding(); + Future run() async { final List failedPackages = []; - await for (Directory plugin in getPlugins()) { - if (!(await passesPublishCheck(plugin))) failedPackages.add(plugin); + await for (final Directory plugin in getPlugins()) { + if (!(await _passesPublishCheck(plugin))) { + failedPackages.add(plugin); + } } if (failedPackages.isNotEmpty) { @@ -51,7 +54,7 @@ class PublishCheckCommand extends PluginCommand { print(passedMessage); } - Pubspec tryParsePubspec(Directory package) { + Pubspec _tryParsePubspec(Directory package) { final File pubspecFile = package.childFile('pubspec.yaml'); try { @@ -64,7 +67,7 @@ class PublishCheckCommand extends PluginCommand { } } - Future hasValidPublishCheckRun(Directory package) async { + Future _hasValidPublishCheckRun(Directory package) async { final io.Process process = await processRunner.start( 'flutter', ['pub', 'publish', '--', '--dry-run'], @@ -91,7 +94,9 @@ class PublishCheckCommand extends PluginCommand { onDone: () => stdInCompleter.complete(), ); - if (await process.exitCode == 0) return true; + if (await process.exitCode == 0) { + return true; + } await stdOutCompleter.future; await stdInCompleter.future; @@ -102,11 +107,11 @@ class PublishCheckCommand extends PluginCommand { 'Packages with an SDK constraint on a pre-release of the Dart SDK should themselves be published as a pre-release version.'); } - Future passesPublishCheck(Directory package) async { + Future _passesPublishCheck(Directory package) async { final String packageName = package.basename; print('Checking that $packageName can be published.'); - final Pubspec pubspec = tryParsePubspec(package); + final Pubspec pubspec = _tryParsePubspec(package); if (pubspec == null) { return false; } else if (pubspec.publishTo == 'none') { @@ -114,8 +119,8 @@ class PublishCheckCommand extends PluginCommand { return true; } - if (await hasValidPublishCheckRun(package)) { - print("Package $packageName is able to be published."); + if (await _hasValidPublishCheckRun(package)) { + print('Package $packageName is able to be published.'); return true; } else { print('Unable to publish $packageName'); diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index d00400294a..0dae3a502b 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -26,6 +26,7 @@ import 'common.dart'; /// /// [processRunner], [print], and [stdin] can be overriden for easier testing. class PublishPluginCommand extends PluginCommand { + /// Creates an instance of the publish command. PublishPluginCommand( Directory packagesDir, FileSystem fileSystem, { @@ -88,9 +89,8 @@ class PublishPluginCommand extends PluginCommand { StreamSubscription _stdinSubscription; @override - Future run() async { - checkSharding(); - final String package = argResults[_packageOption]; + Future run() async { + final String package = argResults[_packageOption] as String; if (package == null) { _print( 'Must specify a package to publish. See `plugin_tools help publish-plugin`.'); @@ -103,8 +103,8 @@ class PublishPluginCommand extends PluginCommand { throw ToolExit(1); } - final bool shouldPushTag = argResults[_pushTagsOption]; - final String remote = argResults[_remoteOption]; + final bool shouldPushTag = argResults[_pushTagsOption] == true; + final String remote = argResults[_remoteOption] as String; String remoteUrl; if (shouldPushTag) { remoteUrl = await _verifyRemote(remote); @@ -173,7 +173,7 @@ class PublishPluginCommand extends PluginCommand { ], workingDir: packageDir); - final String statusOutput = statusResult.stdout; + final String statusOutput = statusResult.stdout as String; if (statusOutput.isNotEmpty) { _print( "There are files in the package directory that haven't been saved in git. Refusing to publish these files:\n\n" @@ -187,11 +187,12 @@ class PublishPluginCommand extends PluginCommand { final ProcessResult remoteInfo = await processRunner.runAndExitOnError( 'git', ['remote', 'get-url', remote], workingDir: packagesDir); - return remoteInfo.stdout; + return remoteInfo.stdout as String; } Future _publish(Directory packageDir) async { - final List publishFlags = argResults[_pubFlagsOption]; + final List publishFlags = + argResults[_pubFlagsOption] as List; _print( 'Running `pub publish ${publishFlags.join(' ')}` in ${packageDir.absolute.path}...\n'); final Process publish = await processRunner.start( @@ -216,9 +217,10 @@ class PublishPluginCommand extends PluginCommand { String _getTag(Directory packageDir) { final File pubspecFile = fileSystem.file(p.join(packageDir.path, 'pubspec.yaml')); - final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()); - final String name = pubspecYaml['name']; - final String version = pubspecYaml['version']; + final YamlMap pubspecYaml = + loadYaml(pubspecFile.readAsStringSync()) as YamlMap; + final String name = pubspecYaml['name'] as String; + final String version = pubspecYaml['version'] as String; // We should have failed to publish if these were unset. assert(name.isNotEmpty && version.isNotEmpty); return _tagFormat diff --git a/script/tool/lib/src/test_command.dart b/script/tool/lib/src/test_command.dart index 10ded4621a..bb4f9c12a7 100644 --- a/script/tool/lib/src/test_command.dart +++ b/script/tool/lib/src/test_command.dart @@ -9,7 +9,9 @@ import 'package:path/path.dart' as p; import 'common.dart'; +/// A command to run Dart unit tests for packages. class TestCommand extends PluginCommand { + /// Creates an instance of the test command. TestCommand( Directory packagesDir, FileSystem fileSystem, { @@ -30,10 +32,9 @@ class TestCommand extends PluginCommand { 'This command requires "flutter" to be in your path.'; @override - Future run() async { - checkSharding(); + Future run() async { final List failingPackages = []; - await for (Directory packageDir in getPackages()) { + await for (final Directory packageDir in getPackages()) { final String packageName = p.relative(packageDir.path, from: packagesDir.path); if (!fileSystem.directory(p.join(packageDir.path, 'test')).existsSync()) { @@ -43,7 +44,7 @@ class TestCommand extends PluginCommand { print('RUNNING $packageName tests...'); - final String enableExperiment = argResults[kEnableExperiment]; + final String enableExperiment = argResults[kEnableExperiment] as String; // `flutter test` automatically gets packages. `pub run test` does not. :( int exitCode = 0; @@ -90,9 +91,9 @@ class TestCommand extends PluginCommand { print('\n\n'); if (failingPackages.isNotEmpty) { print('Tests for the following packages are failing (see above):'); - failingPackages.forEach((String package) { + for (final String package in failingPackages) { print(' * $package'); - }); + } throw ToolExit(1); } diff --git a/script/tool/lib/src/version_check_command.dart b/script/tool/lib/src/version_check_command.dart index fb939a71e3..086fa54888 100644 --- a/script/tool/lib/src/version_check_command.dart +++ b/script/tool/lib/src/version_check_command.dart @@ -15,47 +15,32 @@ import 'common.dart'; const String _kBaseSha = 'base-sha'; +/// Categories of version change types. enum NextVersionType { + /// A breaking change. BREAKING_MAJOR, - MAJOR_NULLSAFETY_PRE_RELEASE, - MINOR_NULLSAFETY_PRE_RELEASE, + + /// A minor change (e.g., added feature). MINOR, + + /// A bugfix change. PATCH, + + /// The release of an existing prerelease version. RELEASE, } -Version getNextNullSafetyPreRelease(Version current, Version next) { - String nextNullsafetyPrerelease = 'nullsafety'; - if (current.isPreRelease && - current.preRelease.first is String && - current.preRelease.first == 'nullsafety') { - if (current.preRelease.length == 1) { - nextNullsafetyPrerelease = 'nullsafety.1'; - } else if (current.preRelease.length == 2 && - current.preRelease.last is int) { - nextNullsafetyPrerelease = 'nullsafety.${current.preRelease.last + 1}'; - } - } - return Version( - next.major, - next.minor, - next.patch, - pre: nextNullsafetyPrerelease, - ); -} - +/// Returns the set of allowed next versions, with their change type, for +/// [masterVersion]. +/// +/// [headVerison] is used to check whether this is a pre-1.0 version bump, as +/// those have different semver rules. @visibleForTesting Map getAllowedNextVersions( Version masterVersion, Version headVersion) { - final Version nextNullSafetyMajor = - getNextNullSafetyPreRelease(masterVersion, masterVersion.nextMajor); - final Version nextNullSafetyMinor = - getNextNullSafetyPreRelease(masterVersion, masterVersion.nextMinor); final Map allowedNextVersions = { masterVersion.nextMajor: NextVersionType.BREAKING_MAJOR, - nextNullSafetyMajor: NextVersionType.MAJOR_NULLSAFETY_PRE_RELEASE, - nextNullSafetyMinor: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE, masterVersion.nextMinor: NextVersionType.MINOR, masterVersion.nextPatch: NextVersionType.PATCH, }; @@ -65,7 +50,7 @@ Map getAllowedNextVersions( if (masterVersion.build.isEmpty) { nextBuildNumber = 1; } else { - final int currentBuildNumber = masterVersion.build.first; + final int currentBuildNumber = masterVersion.build.first as int; nextBuildNumber = currentBuildNumber + 1; } final Version preReleaseVersion = Version( @@ -80,21 +65,13 @@ Map getAllowedNextVersions( NextVersionType.BREAKING_MAJOR; allowedNextVersions[masterVersion.nextPatch] = NextVersionType.MINOR; allowedNextVersions[preReleaseVersion] = NextVersionType.PATCH; - - final Version nextNullSafetyMajor = - getNextNullSafetyPreRelease(masterVersion, masterVersion.nextMinor); - final Version nextNullSafetyMinor = - getNextNullSafetyPreRelease(masterVersion, masterVersion.nextPatch); - - allowedNextVersions[nextNullSafetyMajor] = - NextVersionType.MAJOR_NULLSAFETY_PRE_RELEASE; - allowedNextVersions[nextNullSafetyMinor] = - NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE; } return allowedNextVersions; } +/// A command to validate version changes to packages. class VersionCheckCommand extends PluginCommand { + /// Creates an instance of the version check command. VersionCheckCommand( Directory packagesDir, FileSystem fileSystem, { @@ -113,14 +90,13 @@ class VersionCheckCommand extends PluginCommand { 'This command requires "pub" and "flutter" to be in your path.'; @override - Future run() async { - checkSharding(); + Future run() async { final GitVersionFinder gitVersionFinder = await retrieveVersionFinder(); final List changedPubspecs = await gitVersionFinder.getChangedPubSpecs(); - final String baseSha = argResults[_kBaseSha]; + final String baseSha = argResults[_kBaseSha] as String; for (final String pubspecPath in changedPubspecs) { try { final File pubspecFile = fileSystem.file(pubspecPath); @@ -150,7 +126,8 @@ class VersionCheckCommand extends PluginCommand { printErrorAndExit(errorMessage: error); } - bool isPlatformInterface = pubspec.name.endsWith("_platform_interface"); + final bool isPlatformInterface = + pubspec.name.endsWith('_platform_interface'); if (isPlatformInterface && allowedNextVersions[headVersion] == NextVersionType.BREAKING_MAJOR) { @@ -164,7 +141,7 @@ class VersionCheckCommand extends PluginCommand { } } - await for (Directory plugin in getPlugins()) { + await for (final Directory plugin in getPlugins()) { await _checkVersionsMatch(plugin); } @@ -180,7 +157,7 @@ class VersionCheckCommand extends PluginCommand { final Pubspec pubspec = _tryParsePubspec(plugin); if (pubspec == null) { - final String error = 'Cannot parse version from pubspec.yaml'; + const String error = 'Cannot parse version from pubspec.yaml'; printErrorAndExit(errorMessage: error); } final Version fromPubspec = pubspec.version; @@ -189,16 +166,16 @@ class VersionCheckCommand extends PluginCommand { final File changelog = plugin.childFile('CHANGELOG.md'); final List lines = changelog.readAsLinesSync(); String firstLineWithText; - final Iterator iterator = lines.iterator; + final Iterator iterator = lines.iterator; while (iterator.moveNext()) { - if ((iterator.current as String).trim().isNotEmpty) { + if (iterator.current.trim().isNotEmpty) { firstLineWithText = iterator.current; break; } } // Remove all leading mark down syntax from the version line. final String versionString = firstLineWithText.split(' ').last; - Version fromChangeLog = Version.parse(versionString); + final Version fromChangeLog = Version.parse(versionString); if (fromChangeLog == null) { final String error = 'Cannot find version on the first line of ${plugin.path}/CHANGELOG.md'; @@ -213,14 +190,14 @@ The first version listed in CHANGELOG.md is $fromChangeLog. '''; printErrorAndExit(errorMessage: error); } - print('${packageName} passed version check'); + print('$packageName passed version check'); } Pubspec _tryParsePubspec(Directory package) { final File pubspecFile = package.childFile('pubspec.yaml'); try { - Pubspec pubspec = Pubspec.parse(pubspecFile.readAsStringSync()); + final Pubspec pubspec = Pubspec.parse(pubspecFile.readAsStringSync()); if (pubspec == null) { final String error = 'Failed to parse `pubspec.yaml` at ${pubspecFile.path}'; diff --git a/script/tool/lib/src/xctest_command.dart b/script/tool/lib/src/xctest_command.dart index 41974713f9..64f85577db 100644 --- a/script/tool/lib/src/xctest_command.dart +++ b/script/tool/lib/src/xctest_command.dart @@ -22,6 +22,7 @@ const String _kFoundNoSimulatorsMessage = /// The tests target have to be added to the xcode project of the example app. Usually at "example/ios/Runner.xcworkspace". /// The static analyzer is also run. class XCTestCommand extends PluginCommand { + /// Creates an instance of the test command. XCTestCommand( Directory packagesDir, FileSystem fileSystem, { @@ -46,10 +47,10 @@ class XCTestCommand extends PluginCommand { 'This command requires "flutter" and "xcrun" to be in your path.'; @override - Future run() async { - String destination = argResults[_kiOSDestination]; + Future run() async { + String destination = argResults[_kiOSDestination] as String; if (destination == null) { - String simulatorId = await _findAvailableIphoneSimulator(); + final String simulatorId = await _findAvailableIphoneSimulator(); if (simulatorId == null) { print(_kFoundNoSimulatorsMessage); throw ToolExit(1); @@ -57,12 +58,10 @@ class XCTestCommand extends PluginCommand { destination = 'id=$simulatorId'; } - checkSharding(); + final List skipped = argResults[_kSkip] as List; - final List skipped = argResults[_kSkip]; - - List failingPackages = []; - await for (Directory plugin in getPlugins()) { + final List failingPackages = []; + await for (final Directory plugin in getPlugins()) { // Start running for package. final String packageName = p.relative(plugin.path, from: packagesDir.path); @@ -77,7 +76,7 @@ class XCTestCommand extends PluginCommand { print('\n\n'); continue; } - for (Directory example in getExamplesForPlugin(plugin)) { + for (final Directory example in getExamplesForPlugin(plugin)) { // Running tests and static analyzer. print('Running tests and analyzer for $packageName ...'); int exitCode = await _runTests(true, destination, example); @@ -96,11 +95,11 @@ class XCTestCommand extends PluginCommand { // Command end, print reports. if (failingPackages.isEmpty) { - print("All XCTests have passed!"); + print('All XCTests have passed!'); } else { print( 'The following packages are failing XCTests (see above for details):'); - for (String package in failingPackages) { + for (final String package in failingPackages) { print(' * $package'); } throw ToolExit(1); @@ -110,8 +109,7 @@ class XCTestCommand extends PluginCommand { Future _runTests(bool runTests, String destination, Directory example) { final List xctestArgs = [ _kXcodeBuildCommand, - if (runTests) - 'test', + if (runTests) 'test', 'analyze', '-workspace', 'ios/Runner.xcworkspace', @@ -128,8 +126,8 @@ class XCTestCommand extends PluginCommand { final String completeTestCommand = '$_kXCRunCommand ${xctestArgs.join(' ')}'; print(completeTestCommand); - return processRunner - .runAndStream(_kXCRunCommand, xctestArgs, workingDir: example, exitOnError: false); + return processRunner.runAndStream(_kXCRunCommand, xctestArgs, + workingDir: example, exitOnError: false); } Future _findAvailableIphoneSimulator() async { @@ -151,30 +149,35 @@ class XCTestCommand extends PluginCommand { throw ToolExit(1); } final Map simulatorListJson = - jsonDecode(findSimulatorsResult.stdout); - final List runtimes = simulatorListJson['runtimes']; - final Map devices = simulatorListJson['devices']; + jsonDecode(findSimulatorsResult.stdout as String) + as Map; + final List> runtimes = + (simulatorListJson['runtimes'] as List) + .cast>(); + final Map devices = + simulatorListJson['devices'] as Map; if (runtimes.isEmpty || devices.isEmpty) { return null; } String id; // Looking for runtimes, trying to find one with highest OS version. - for (Map runtimeMap in runtimes.reversed) { - if (!runtimeMap['name'].contains('iOS')) { + for (final Map runtimeMap in runtimes.reversed) { + if (!(runtimeMap['name'] as String).contains('iOS')) { continue; } - final String runtimeID = runtimeMap['identifier']; - final List devicesForRuntime = devices[runtimeID]; + final String runtimeID = runtimeMap['identifier'] as String; + final List> devicesForRuntime = + (devices[runtimeID] as List).cast>(); if (devicesForRuntime.isEmpty) { continue; } // Looking for runtimes, trying to find latest version of device. - for (Map device in devicesForRuntime.reversed) { + for (final Map device in devicesForRuntime.reversed) { if (device['availabilityError'] != null || (device['isAvailable'] as bool == false)) { continue; } - id = device['udid']; + id = device['udid'] as String; print('device selected: $device'); return id; } diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart index 636d4794a4..7b23ea9778 100644 --- a/script/tool/test/analyze_command_test.dart +++ b/script/tool/test/analyze_command_test.dart @@ -13,7 +13,7 @@ import 'util.dart'; void main() { RecordingProcessRunner processRunner; - CommandRunner runner; + CommandRunner runner; setUp(() { initializeFakePackages(); @@ -22,7 +22,7 @@ void main() { mockPackagesDir, mockFileSystem, processRunner: processRunner); - runner = CommandRunner('analyze_command', 'Test for analyze_command'); + runner = CommandRunner('analyze_command', 'Test for analyze_command'); runner.addCommand(analyzeCommand); }); @@ -31,8 +31,8 @@ void main() { }); test('analyzes all packages', () async { - final Directory plugin1Dir = await createFakePlugin('a'); - final Directory plugin2Dir = await createFakePlugin('b'); + final Directory plugin1Dir = createFakePlugin('a'); + final Directory plugin2Dir = createFakePlugin('b'); final MockProcess mockProcess = MockProcess(); mockProcess.exitCodeCompleter.complete(0); @@ -42,20 +42,22 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall('pub', ['global', 'activate', 'tuneup'], + ProcessCall('pub', const ['global', 'activate', 'tuneup'], mockPackagesDir.path), - ProcessCall('flutter', ['packages', 'get'], plugin1Dir.path), - ProcessCall('flutter', ['packages', 'get'], plugin2Dir.path), - ProcessCall('pub', ['global', 'run', 'tuneup', 'check'], + ProcessCall( + 'flutter', const ['packages', 'get'], plugin1Dir.path), + ProcessCall( + 'flutter', const ['packages', 'get'], plugin2Dir.path), + ProcessCall('pub', const ['global', 'run', 'tuneup', 'check'], plugin1Dir.path), - ProcessCall('pub', ['global', 'run', 'tuneup', 'check'], + ProcessCall('pub', const ['global', 'run', 'tuneup', 'check'], plugin2Dir.path), ])); }); group('verifies analysis settings', () { test('fails analysis_options.yaml', () async { - await createFakePlugin('foo', withExtraFiles: >[ + createFakePlugin('foo', withExtraFiles: >[ ['analysis_options.yaml'] ]); @@ -64,7 +66,7 @@ void main() { }); test('fails .analysis_options', () async { - await createFakePlugin('foo', withExtraFiles: >[ + createFakePlugin('foo', withExtraFiles: >[ ['.analysis_options'] ]); @@ -74,7 +76,7 @@ void main() { test('takes an allow list', () async { final Directory pluginDir = - await createFakePlugin('foo', withExtraFiles: >[ + createFakePlugin('foo', withExtraFiles: >[ ['analysis_options.yaml'] ]); @@ -86,17 +88,20 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall('pub', ['global', 'activate', 'tuneup'], + ProcessCall('pub', const ['global', 'activate', 'tuneup'], mockPackagesDir.path), - ProcessCall('flutter', ['packages', 'get'], pluginDir.path), - ProcessCall('pub', ['global', 'run', 'tuneup', 'check'], + ProcessCall( + 'flutter', const ['packages', 'get'], pluginDir.path), + ProcessCall( + 'pub', + const ['global', 'run', 'tuneup', 'check'], pluginDir.path), ])); }); // See: https://github.com/flutter/flutter/issues/78994 test('takes an empty allow list', () async { - await createFakePlugin('foo', withExtraFiles: >[ + createFakePlugin('foo', withExtraFiles: >[ ['analysis_options.yaml'] ]); diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart index f9ee6dcf25..40da27d449 100644 --- a/script/tool/test/build_examples_command_test.dart +++ b/script/tool/test/build_examples_command_test.dart @@ -13,10 +13,10 @@ import 'util.dart'; void main() { group('test build_example_command', () { - CommandRunner runner; + CommandRunner runner; RecordingProcessRunner processRunner; final String flutterCommand = - LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; + const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; setUp(() { initializeFakePackages(); @@ -25,7 +25,7 @@ void main() { mockPackagesDir, mockFileSystem, processRunner: processRunner); - runner = CommandRunner( + runner = CommandRunner( 'build_examples_command', 'Test for build_example_command'); runner.addCommand(command); cleanupPackages(); @@ -102,7 +102,7 @@ void main() { orderedEquals([ ProcessCall( flutterCommand, - [ + const [ 'build', 'ios', '--no-codesign', @@ -179,7 +179,7 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, ['build', 'linux'], + ProcessCall(flutterCommand, const ['build', 'linux'], pluginExampleDirectory.path), ])); cleanupPackages(); @@ -249,7 +249,7 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, ['build', 'macos'], + ProcessCall(flutterCommand, const ['build', 'macos'], pluginExampleDirectory.path), ])); cleanupPackages(); @@ -318,7 +318,7 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, ['build', 'web'], + ProcessCall(flutterCommand, const ['build', 'web'], pluginExampleDirectory.path), ])); cleanupPackages(); @@ -390,7 +390,7 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, ['build', 'windows'], + ProcessCall(flutterCommand, const ['build', 'windows'], pluginExampleDirectory.path), ])); cleanupPackages(); @@ -466,7 +466,7 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, ['build', 'apk'], + ProcessCall(flutterCommand, const ['build', 'apk'], pluginExampleDirectory.path), ])); cleanupPackages(); @@ -498,7 +498,7 @@ void main() { orderedEquals([ ProcessCall( flutterCommand, - ['build', 'apk', '--enable-experiment=exp1'], + const ['build', 'apk', '--enable-experiment=exp1'], pluginExampleDirectory.path), ])); cleanupPackages(); @@ -528,7 +528,7 @@ void main() { orderedEquals([ ProcessCall( flutterCommand, - [ + const [ 'build', 'ios', '--no-codesign', diff --git a/script/tool/test/common_test.dart b/script/tool/test/common_test.dart index 6f51ade64e..57bc1e20f9 100644 --- a/script/tool/test/common_test.dart +++ b/script/tool/test/common_test.dart @@ -15,7 +15,7 @@ import 'util.dart'; void main() { RecordingProcessRunner processRunner; - CommandRunner runner; + CommandRunner runner; List plugins; List> gitDirCommands; String gitDiffResponse; @@ -25,16 +25,17 @@ void main() { gitDiffResponse = ''; final MockGitDir gitDir = MockGitDir(); when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { - gitDirCommands.add(invocation.positionalArguments[0]); + gitDirCommands.add(invocation.positionalArguments[0] as List); final MockProcessResult mockProcessResult = MockProcessResult(); if (invocation.positionalArguments[0][0] == 'diff') { - when(mockProcessResult.stdout).thenReturn(gitDiffResponse); + when(mockProcessResult.stdout as String) + .thenReturn(gitDiffResponse); } return Future.value(mockProcessResult); }); initializeFakePackages(); processRunner = RecordingProcessRunner(); - plugins = []; + plugins = []; final SamplePluginCommand samplePluginCommand = SamplePluginCommand( plugins, mockPackagesDir, @@ -43,7 +44,7 @@ void main() { gitDir: gitDir, ); runner = - CommandRunner('common_command', 'Test for common functionality'); + CommandRunner('common_command', 'Test for common functionality'); runner.addCommand(samplePluginCommand); }); @@ -108,7 +109,7 @@ void main() { test('all plugins should be tested if there are no plugin related changes.', () async { - gitDiffResponse = ".cirrus"; + gitDiffResponse = '.cirrus'; final Directory plugin1 = createFakePlugin('plugin1'); final Directory plugin2 = createFakePlugin('plugin2'); await runner.run( @@ -118,7 +119,7 @@ void main() { }); test('Only changed plugin should be tested.', () async { - gitDiffResponse = "packages/plugin1/plugin1.dart"; + gitDiffResponse = 'packages/plugin1/plugin1.dart'; final Directory plugin1 = createFakePlugin('plugin1'); createFakePlugin('plugin2'); await runner.run( @@ -226,12 +227,14 @@ packages/plugin3/plugin3.dart gitDiffResponse = ''; gitDir = MockGitDir(); when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { - gitDirCommands.add(invocation.positionalArguments[0]); + gitDirCommands.add(invocation.positionalArguments[0] as List); final MockProcessResult mockProcessResult = MockProcessResult(); if (invocation.positionalArguments[0][0] == 'diff') { - when(mockProcessResult.stdout).thenReturn(gitDiffResponse); + when(mockProcessResult.stdout as String) + .thenReturn(gitDiffResponse); } else if (invocation.positionalArguments[0][0] == 'merge-base') { - when(mockProcessResult.stdout).thenReturn(mergeBaseResponse); + when(mockProcessResult.stdout as String) + .thenReturn(mergeBaseResponse); } return Future.value(mockProcessResult); }); @@ -245,7 +248,7 @@ packages/plugin3/plugin3.dart test('No git diff should result no files changed', () async { final GitVersionFinder finder = GitVersionFinder(gitDir, 'some base sha'); - List changedFiles = await finder.getChangedFiles(); + final List changedFiles = await finder.getChangedFiles(); expect(changedFiles, isEmpty); }); @@ -256,7 +259,7 @@ file1/file1.cc file2/file2.cc '''; final GitVersionFinder finder = GitVersionFinder(gitDir, 'some base sha'); - List changedFiles = await finder.getChangedFiles(); + final List changedFiles = await finder.getChangedFiles(); expect( changedFiles, equals(['file1/file1.cc', 'file2/file2.cc'])); @@ -268,7 +271,7 @@ file1/pubspec.yaml file2/file2.cc '''; final GitVersionFinder finder = GitVersionFinder(gitDir, 'some base sha'); - List changedFiles = await finder.getChangedPubSpecs(); + final List changedFiles = await finder.getChangedPubSpecs(); expect(changedFiles, equals(['file1/pubspec.yaml'])); }); @@ -281,26 +284,27 @@ file2/file2.cc '''; final GitVersionFinder finder = GitVersionFinder(gitDir, null); await finder.getChangedFiles(); - verify(gitDir - .runCommand(['diff', '--name-only', mergeBaseResponse, 'HEAD'])); + verify(gitDir.runCommand( + ['diff', '--name-only', mergeBaseResponse, 'HEAD'])); }); test('use correct base sha if specified', () async { - final String customBaseSha = 'aklsjdcaskf12312'; + const String customBaseSha = 'aklsjdcaskf12312'; gitDiffResponse = ''' file1/pubspec.yaml file2/file2.cc '''; final GitVersionFinder finder = GitVersionFinder(gitDir, customBaseSha); await finder.getChangedFiles(); - verify(gitDir.runCommand(['diff', '--name-only', customBaseSha, 'HEAD'])); + verify(gitDir + .runCommand(['diff', '--name-only', customBaseSha, 'HEAD'])); }); }); } class SamplePluginCommand extends PluginCommand { SamplePluginCommand( - this.plugins_, + this._plugins, Directory packagesDir, FileSystem fileSystem, { ProcessRunner processRunner = const ProcessRunner(), @@ -308,7 +312,7 @@ class SamplePluginCommand extends PluginCommand { }) : super(packagesDir, fileSystem, processRunner: processRunner, gitDir: gitDir); - List plugins_; + final List _plugins; @override final String name = 'sample'; @@ -317,9 +321,9 @@ class SamplePluginCommand extends PluginCommand { final String description = 'sample command'; @override - Future run() async { - await for (Directory package in getPlugins()) { - this.plugins_.add(package.path); + Future run() async { + await for (final Directory package in getPlugins()) { + _plugins.add(package.path); } } } diff --git a/script/tool/test/create_all_plugins_app_command_test.dart b/script/tool/test/create_all_plugins_app_command_test.dart index 58f24c9a3d..fedc046846 100644 --- a/script/tool/test/create_all_plugins_app_command_test.dart +++ b/script/tool/test/create_all_plugins_app_command_test.dart @@ -12,7 +12,7 @@ import 'util.dart'; void main() { group('$CreateAllPluginsAppCommand', () { - CommandRunner runner; + CommandRunner runner; FileSystem fileSystem; Directory testRoot; Directory packagesDir; @@ -22,7 +22,7 @@ void main() { // Since the core of this command is a call to 'flutter create', the test // has to use the real filesystem. Put everything possible in a unique // temporary to minimize affect on the host system. - fileSystem = LocalFileSystem(); + fileSystem = const LocalFileSystem(); testRoot = fileSystem.systemTempDirectory.createTempSync(); packagesDir = testRoot.childDirectory('packages'); @@ -32,7 +32,7 @@ void main() { pluginsRoot: testRoot, ); appDir = command.appDirectory; - runner = CommandRunner( + runner = CommandRunner( 'create_all_test', 'Test for $CreateAllPluginsAppCommand'); runner.addCommand(command); }); diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index 58b8fb0d08..c5960b2c34 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -14,10 +14,10 @@ import 'util.dart'; void main() { group('test drive_example_command', () { - CommandRunner runner; + CommandRunner runner; RecordingProcessRunner processRunner; final String flutterCommand = - LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; + const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; setUp(() { initializeFakePackages(); processRunner = RecordingProcessRunner(); @@ -25,7 +25,7 @@ void main() { mockPackagesDir, mockFileSystem, processRunner: processRunner); - runner = CommandRunner( + runner = CommandRunner( 'drive_examples_command', 'Test for drive_example_command'); runner.addCommand(command); }); @@ -60,8 +60,8 @@ void main() { ]), ); - String deviceTestPath = p.join('test', 'plugin.dart'); - String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + final String deviceTestPath = p.join('test', 'plugin.dart'); + final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); print(processRunner.recordedCalls); expect( processRunner.recordedCalls, @@ -105,8 +105,8 @@ void main() { ]), ); - String deviceTestPath = p.join('test_driver', 'plugin.dart'); - String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + final String deviceTestPath = p.join('test_driver', 'plugin.dart'); + final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); print(processRunner.recordedCalls); expect( processRunner.recordedCalls, @@ -173,7 +173,8 @@ void main() { ]), ); - String driverTestPath = p.join('test_driver', 'integration_test.dart'); + final String driverTestPath = + p.join('test_driver', 'integration_test.dart'); print(processRunner.recordedCalls); expect( processRunner.recordedCalls, @@ -259,8 +260,8 @@ void main() { ]), ); - String deviceTestPath = p.join('test_driver', 'plugin.dart'); - String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + final String deviceTestPath = p.join('test_driver', 'plugin.dart'); + final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); print(processRunner.recordedCalls); expect( processRunner.recordedCalls, @@ -336,8 +337,8 @@ void main() { ]), ); - String deviceTestPath = p.join('test_driver', 'plugin.dart'); - String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + final String deviceTestPath = p.join('test_driver', 'plugin.dart'); + final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); print(processRunner.recordedCalls); expect( processRunner.recordedCalls, @@ -415,8 +416,8 @@ void main() { ]), ); - String deviceTestPath = p.join('test_driver', 'plugin.dart'); - String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + final String deviceTestPath = p.join('test_driver', 'plugin.dart'); + final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); print(processRunner.recordedCalls); expect( processRunner.recordedCalls, @@ -496,8 +497,8 @@ void main() { ]), ); - String deviceTestPath = p.join('test_driver', 'plugin.dart'); - String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + final String deviceTestPath = p.join('test_driver', 'plugin.dart'); + final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); print(processRunner.recordedCalls); expect( processRunner.recordedCalls, @@ -567,8 +568,8 @@ void main() { '--enable-experiment=exp1', ]); - String deviceTestPath = p.join('test', 'plugin.dart'); - String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + final String deviceTestPath = p.join('test', 'plugin.dart'); + final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); print(processRunner.recordedCalls); expect( processRunner.recordedCalls, diff --git a/script/tool/test/firebase_test_lab_test.dart b/script/tool/test/firebase_test_lab_test.dart index f1141ae19d..d6068691d5 100644 --- a/script/tool/test/firebase_test_lab_test.dart +++ b/script/tool/test/firebase_test_lab_test.dart @@ -15,7 +15,7 @@ import 'util.dart'; void main() { group('$FirebaseTestLabCommand', () { final List printedMessages = []; - CommandRunner runner; + CommandRunner runner; RecordingProcessRunner processRunner; setUp(() { @@ -26,7 +26,7 @@ void main() { processRunner: processRunner, print: (Object message) => printedMessages.add(message.toString())); - runner = CommandRunner( + runner = CommandRunner( 'firebase_test_lab_command', 'Test for $FirebaseTestLabCommand'); runner.addCommand(command); }); @@ -60,7 +60,7 @@ void main() { expect( printedMessages, contains( - "\nWarning: gcloud config set returned a non-zero exit code. Continuing anyway.")); + '\nWarning: gcloud config set returned a non-zero exit code. Continuing anyway.')); }); test('runs e2e tests', () async { @@ -86,7 +86,7 @@ void main() { ], ]); - final List output = await runCapturingPrint(runner, [ + await runCapturingPrint(runner, [ 'firebase-test-lab', '--device', 'model=flame,version=29', diff --git a/script/tool/test/java_test_command_test.dart b/script/tool/test/java_test_command_test.dart index b036d7ec0c..ba01691522 100644 --- a/script/tool/test/java_test_command_test.dart +++ b/script/tool/test/java_test_command_test.dart @@ -12,7 +12,7 @@ import 'util.dart'; void main() { group('$JavaTestCommand', () { - CommandRunner runner; + CommandRunner runner; final RecordingProcessRunner processRunner = RecordingProcessRunner(); setUp(() { @@ -22,7 +22,7 @@ void main() { processRunner: processRunner); runner = - CommandRunner('java_test_test', 'Test for $JavaTestCommand'); + CommandRunner('java_test_test', 'Test for $JavaTestCommand'); runner.addCommand(command); }); @@ -50,7 +50,7 @@ void main() { orderedEquals([ ProcessCall( p.join(plugin.path, 'example/android/gradlew'), - ['testDebugUnitTest', '--info'], + const ['testDebugUnitTest', '--info'], p.join(plugin.path, 'example/android'), ), ]), @@ -76,7 +76,7 @@ void main() { orderedEquals([ ProcessCall( p.join(plugin.path, 'example/android/gradlew'), - ['testDebugUnitTest', '--info'], + const ['testDebugUnitTest', '--info'], p.join(plugin.path, 'example/android'), ), ]), diff --git a/script/tool/test/license_check_command_test.dart b/script/tool/test/license_check_command_test.dart index f8646da5d8..94606f54b7 100644 --- a/script/tool/test/license_check_command_test.dart +++ b/script/tool/test/license_check_command_test.dart @@ -11,7 +11,7 @@ import 'package:test/test.dart'; void main() { group('$LicenseCheckCommand', () { - CommandRunner runner; + CommandRunner runner; FileSystem fileSystem; List printedMessages; Directory root; @@ -29,7 +29,7 @@ void main() { print: (Object message) => printedMessages.add(message.toString()), ); runner = - CommandRunner('license_test', 'Test for $LicenseCheckCommand'); + CommandRunner('license_test', 'Test for $LicenseCheckCommand'); runner.addCommand(command); }); @@ -51,15 +51,15 @@ void main() { 'found in the LICENSE file.', ], }) { - List lines = ['$prefix$comment$copyright']; - for (String line in license) { + final List lines = ['$prefix$comment$copyright']; + for (final String line in license) { lines.add('$comment$line'); } file.writeAsStringSync(lines.join('\n') + suffix + '\n'); } test('looks at only expected extensions', () async { - Map extensions = { + final Map extensions = { 'c': true, 'cc': true, 'cpp': true, @@ -98,7 +98,7 @@ void main() { }); test('ignore list overrides extension matches', () async { - List ignoredFiles = [ + final List ignoredFiles = [ // Ignored base names. 'flutter_export_environment.sh', 'GeneratedPluginRegistrant.java', @@ -124,11 +124,11 @@ void main() { }); test('passes if all checked files have license blocks', () async { - File checked = root.childFile('checked.cc'); + final File checked = root.childFile('checked.cc'); checked.createSync(); _writeLicense(checked); - File not_checked = root.childFile('not_checked.md'); - not_checked.createSync(); + final File notChecked = root.childFile('not_checked.md'); + notChecked.createSync(); await runner.run(['license-check']); @@ -138,15 +138,15 @@ void main() { }); test('handles the comment styles for all supported languages', () async { - File file_a = root.childFile('file_a.cc'); - file_a.createSync(); - _writeLicense(file_a, comment: '// '); - File file_b = root.childFile('file_b.sh'); - file_b.createSync(); - _writeLicense(file_b, comment: '# '); - File file_c = root.childFile('file_c.html'); - file_c.createSync(); - _writeLicense(file_c, comment: '', prefix: ''); + final File fileA = root.childFile('file_a.cc'); + fileA.createSync(); + _writeLicense(fileA, comment: '// '); + final File fileB = root.childFile('file_b.sh'); + fileB.createSync(); + _writeLicense(fileB, comment: '# '); + final File fileC = root.childFile('file_c.html'); + fileC.createSync(); + _writeLicense(fileC, comment: '', prefix: ''); await runner.run(['license-check']); @@ -158,12 +158,12 @@ void main() { }); test('fails if any checked files are missing license blocks', () async { - File good_a = root.childFile('good.cc'); - good_a.createSync(); - _writeLicense(good_a); - File good_b = root.childFile('good.h'); - good_b.createSync(); - _writeLicense(good_b); + final File goodA = root.childFile('good.cc'); + goodA.createSync(); + _writeLicense(goodA); + final File goodB = root.childFile('good.h'); + goodB.createSync(); + _writeLicense(goodB); root.childFile('bad.cc').createSync(); root.childFile('bad.h').createSync(); @@ -183,10 +183,10 @@ void main() { }); test('fails if any checked files are missing just the copyright', () async { - File good = root.childFile('good.cc'); + final File good = root.childFile('good.cc'); good.createSync(); _writeLicense(good); - File bad = root.childFile('bad.cc'); + final File bad = root.childFile('bad.cc'); bad.createSync(); _writeLicense(bad, copyright: ''); @@ -205,10 +205,10 @@ void main() { }); test('fails if any checked files are missing just the license', () async { - File good = root.childFile('good.cc'); + final File good = root.childFile('good.cc'); good.createSync(); _writeLicense(good); - File bad = root.childFile('bad.cc'); + final File bad = root.childFile('bad.cc'); bad.createSync(); _writeLicense(bad, license: []); @@ -228,7 +228,7 @@ void main() { test('fails if any third-party code is not in a third_party directory', () async { - File thirdPartyFile = root.childFile('third_party.cc'); + final File thirdPartyFile = root.childFile('third_party.cc'); thirdPartyFile.createSync(); _writeLicense(thirdPartyFile, copyright: 'Copyright 2017 Someone Else'); @@ -247,7 +247,7 @@ void main() { }); test('succeeds for third-party code in a third_party directory', () async { - File thirdPartyFile = root + final File thirdPartyFile = root .childDirectory('a_plugin') .childDirectory('lib') .childDirectory('src') @@ -270,10 +270,10 @@ void main() { }); test('fails for licenses that the tool does not expect', () async { - File good = root.childFile('good.cc'); + final File good = root.childFile('good.cc'); good.createSync(); _writeLicense(good); - File bad = root.childDirectory('third_party').childFile('bad.cc'); + final File bad = root.childDirectory('third_party').childFile('bad.cc'); bad.createSync(recursive: true); _writeLicense(bad, license: [ 'This program is free software: you can redistribute it and/or modify', @@ -296,26 +296,28 @@ void main() { test('Apache is not recognized for new authors without validation changes', () async { - File good = root.childFile('good.cc'); + final File good = root.childFile('good.cc'); good.createSync(); _writeLicense(good); - File bad = root.childDirectory('third_party').childFile('bad.cc'); + final File bad = root.childDirectory('third_party').childFile('bad.cc'); bad.createSync(recursive: true); _writeLicense( bad, copyright: 'Copyright 2017 Some New Authors.', - license: [ - 'Licensed under the Apache License, Version 2.0 (the "License");', - 'you may not use this file except in compliance with the License.' - ], + license: [ + 'Licensed under the Apache License, Version 2.0 (the "License");', + 'you may not use this file except in compliance with the License.' + ], ); await expectLater(() => runner.run(['license-check']), throwsA(const TypeMatcher())); // Failure should give information about the problematic files. - expect(printedMessages, - contains('No recognized license was found for the following third-party files:')); + expect( + printedMessages, + contains( + 'No recognized license was found for the following third-party files:')); expect(printedMessages, contains(' third_party/bad.cc')); // Failure shouldn't print the success message. expect(printedMessages, @@ -324,7 +326,7 @@ void main() { test('passes if all first-party LICENSE files are correctly formatted', () async { - File license = root.childFile('LICENSE'); + final File license = root.childFile('LICENSE'); license.createSync(); license.writeAsStringSync(_correctLicenseFileText); @@ -337,7 +339,7 @@ void main() { test('fails if any first-party LICENSE files are incorrectly formatted', () async { - File license = root.childFile('LICENSE'); + final File license = root.childFile('LICENSE'); license.createSync(); license.writeAsStringSync(_incorrectLicenseFileText); @@ -349,7 +351,8 @@ void main() { }); test('ignores third-party LICENSE format', () async { - File license = root.childDirectory('third_party').childFile('LICENSE'); + final File license = + root.childDirectory('third_party').childFile('LICENSE'); license.createSync(recursive: true); license.writeAsStringSync(_incorrectLicenseFileText); @@ -362,8 +365,8 @@ void main() { }); } -const String _correctLicenseFileText = - '''Copyright 2013 The Flutter Authors. All rights reserved. +const String _correctLicenseFileText = ''' +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -392,8 +395,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A common incorrect version created by copying text intended for a code file, // with comment markers. -const String _incorrectLicenseFileText = - '''// Copyright 2013 The Flutter Authors. All rights reserved. +const String _incorrectLicenseFileText = ''' +// Copyright 2013 The Flutter Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart index 5475641cba..a1fa1f7c77 100644 --- a/script/tool/test/lint_podspecs_command_test.dart +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -2,8 +2,6 @@ // 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:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/lint_podspecs_command.dart'; @@ -17,7 +15,7 @@ import 'util.dart'; void main() { group('$LintPodspecsCommand', () { - CommandRunner runner; + CommandRunner runner; MockPlatform mockPlatform; final RecordingProcessRunner processRunner = RecordingProcessRunner(); List printedMessages; @@ -37,7 +35,7 @@ void main() { ); runner = - CommandRunner('podspec_test', 'Test for $LintPodspecsCommand'); + CommandRunner('podspec_test', 'Test for $LintPodspecsCommand'); runner.addCommand(command); final MockProcess mockLintProcess = MockProcess(); mockLintProcess.exitCodeCompleter.complete(0); @@ -64,7 +62,7 @@ void main() { }); test('runs pod lib lint on a podspec', () async { - Directory plugin1Dir = + final Directory plugin1Dir = createFakePlugin('plugin1', withExtraFiles: >[ ['ios', 'plugin1.podspec'], ['bogus.dart'], // Ignore non-podspecs. @@ -78,7 +76,7 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall('which', ['pod'], mockPackagesDir.path), + ProcessCall('which', const ['pod'], mockPackagesDir.path), ProcessCall( 'pod', [ @@ -103,8 +101,7 @@ void main() { ]), ); - expect( - printedMessages, contains('Linting plugin1.podspec')); + expect(printedMessages, contains('Linting plugin1.podspec')); expect(printedMessages, contains('Foo')); expect(printedMessages, contains('Bar')); }); @@ -123,13 +120,13 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall('which', ['pod'], mockPackagesDir.path), + ProcessCall('which', const ['pod'], mockPackagesDir.path), ]), ); }); test('allow warnings for podspecs with known warnings', () async { - Directory plugin1Dir = + final Directory plugin1Dir = createFakePlugin('plugin1', withExtraFiles: >[ ['plugin1.podspec'], ]); @@ -139,7 +136,7 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall('which', ['pod'], mockPackagesDir.path), + ProcessCall('which', const ['pod'], mockPackagesDir.path), ProcessCall( 'pod', [ @@ -166,8 +163,7 @@ void main() { ]), ); - expect( - printedMessages, contains('Linting plugin1.podspec')); + expect(printedMessages, contains('Linting plugin1.podspec')); }); }); } diff --git a/script/tool/test/list_command_test.dart b/script/tool/test/list_command_test.dart index 19e9df0dd3..e7fcfe7a7c 100644 --- a/script/tool/test/list_command_test.dart +++ b/script/tool/test/list_command_test.dart @@ -11,13 +11,13 @@ import 'util.dart'; void main() { group('$ListCommand', () { - CommandRunner runner; + CommandRunner runner; setUp(() { initializeFakePackages(); final ListCommand command = ListCommand(mockPackagesDir, mockFileSystem); - runner = CommandRunner('list_test', 'Test for $ListCommand'); + runner = CommandRunner('list_test', 'Test for $ListCommand'); runner.addCommand(command); }); diff --git a/script/tool/test/mocks.dart b/script/tool/test/mocks.dart index 2ef9d72e36..ad1f357fb4 100644 --- a/script/tool/test/mocks.dart +++ b/script/tool/test/mocks.dart @@ -33,5 +33,5 @@ class MockIOSink extends Mock implements IOSink { List lines = []; @override - void writeln([Object obj = ""]) => lines.add(obj); + void writeln([Object obj = '']) => lines.add(obj.toString()); } diff --git a/script/tool/test/publish_check_command_test.dart b/script/tool/test/publish_check_command_test.dart index dbe6e2cfe5..568d35eeff 100644 --- a/script/tool/test/publish_check_command_test.dart +++ b/script/tool/test/publish_check_command_test.dart @@ -17,7 +17,7 @@ import 'util.dart'; void main() { group('$PublishCheckProcessRunner tests', () { PublishCheckProcessRunner processRunner; - CommandRunner runner; + CommandRunner runner; setUp(() { initializeFakePackages(); @@ -26,7 +26,7 @@ void main() { mockPackagesDir, mockFileSystem, processRunner: processRunner); - runner = CommandRunner( + runner = CommandRunner( 'publish_check_command', 'Test for publish-check command.', ); @@ -38,8 +38,8 @@ void main() { }); test('publish check all packages', () async { - final Directory plugin1Dir = await createFakePlugin('a'); - final Directory plugin2Dir = await createFakePlugin('b'); + final Directory plugin1Dir = createFakePlugin('a'); + final Directory plugin2Dir = createFakePlugin('b'); processRunner.processesToReturn.add( MockProcess()..exitCodeCompleter.complete(0), @@ -52,15 +52,19 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall('flutter', - ['pub', 'publish', '--', '--dry-run'], plugin1Dir.path), - ProcessCall('flutter', - ['pub', 'publish', '--', '--dry-run'], plugin2Dir.path), + ProcessCall( + 'flutter', + const ['pub', 'publish', '--', '--dry-run'], + plugin1Dir.path), + ProcessCall( + 'flutter', + const ['pub', 'publish', '--', '--dry-run'], + plugin2Dir.path), ])); }); test('fail on negative test', () async { - await createFakePlugin('a'); + createFakePlugin('a'); final MockProcess process = MockProcess(); process.stdoutController.close(); // ignore: unawaited_futures @@ -76,7 +80,7 @@ void main() { }); test('fail on bad pubspec', () async { - final Directory dir = await createFakePlugin('c'); + final Directory dir = createFakePlugin('c'); await dir.childFile('pubspec.yaml').writeAsString('bad-yaml'); final MockProcess process = MockProcess(); @@ -87,9 +91,9 @@ void main() { }); test('pass on prerelease', () async { - await createFakePlugin('d'); + createFakePlugin('d'); - final String preReleaseOutput = 'Package has 1 warning.' + const String preReleaseOutput = 'Package has 1 warning.' 'Packages with an SDK constraint on a pre-release of the Dart SDK should themselves be published as a pre-release version.'; final MockProcess process = MockProcess(); diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index cfa40b9dc0..03e7858d3b 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -27,7 +27,7 @@ void main() { Directory pluginDir; GitDir gitDir; TestProcessRunner processRunner; - CommandRunner commandRunner; + CommandRunner commandRunner; MockStdin mockStdin; setUp(() async { @@ -48,7 +48,7 @@ void main() { await gitDir.runCommand(['commit', '-m', 'Initial commit']); processRunner = TestProcessRunner(); mockStdin = MockStdin(); - commandRunner = CommandRunner('tester', '') + commandRunner = CommandRunner('tester', '') ..addCommand(PublishPluginCommand( mockPackagesDir, mockPackagesDir.fileSystem, processRunner: processRunner, @@ -66,13 +66,17 @@ void main() { await expectLater(() => commandRunner.run(['publish-plugin']), throwsA(const TypeMatcher())); expect( - printedMessages.last, contains("Must specify a package to publish.")); + printedMessages.last, contains('Must specify a package to publish.')); }); test('requires an existing flag', () async { await expectLater( - () => commandRunner - .run(['publish-plugin', '--package', 'iamerror', '--no-push-tags']), + () => commandRunner.run([ + 'publish-plugin', + '--package', + 'iamerror', + '--no-push-tags' + ]), throwsA(const TypeMatcher())); expect(printedMessages.last, contains('iamerror does not exist')); @@ -82,8 +86,12 @@ void main() { pluginDir.childFile('tmp').createSync(); await expectLater( - () => commandRunner - .run(['publish-plugin', '--package', testPluginName, '--no-push-tags']), + () => commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--no-push-tags' + ]), throwsA(const TypeMatcher())); expect( @@ -97,7 +105,7 @@ void main() { () => commandRunner .run(['publish-plugin', '--package', testPluginName]), throwsA(const TypeMatcher())); - expect(processRunner.results.last.stderr, contains("No such remote")); + expect(processRunner.results.last.stderr, contains('No such remote')); }); test("doesn't validate the remote if it's not pushing tags", () async { @@ -202,7 +210,7 @@ void main() { ]), throwsA(const TypeMatcher())); - expect(printedMessages, contains("Publish failed. Exiting.")); + expect(printedMessages, contains('Publish failed. Exiting.')); }); }); @@ -218,7 +226,7 @@ void main() { final String tag = (await gitDir.runCommand(['show-ref', 'fake_package-v0.0.1'])) - .stdout; + .stdout as String; expect(tag, isNotEmpty); }); @@ -233,11 +241,11 @@ void main() { ]), throwsA(const TypeMatcher())); - expect(printedMessages, contains("Publish failed. Exiting.")); + expect(printedMessages, contains('Publish failed. Exiting.')); final String tag = (await gitDir.runCommand( ['show-ref', 'fake_package-v0.0.1'], throwOnError: false)) - .stdout; + .stdout as String; expect(tag, isEmpty); }); }); @@ -359,7 +367,7 @@ class MockStdin extends Mock implements io.Stdin { String readLineOutput; @override - Stream transform(StreamTransformer streamTransformer) { + Stream transform(StreamTransformer, S> streamTransformer) { return controller.stream.transform(streamTransformer); } diff --git a/script/tool/test/test_command_test.dart b/script/tool/test/test_command_test.dart index 66471263f6..1dd0c15829 100644 --- a/script/tool/test/test_command_test.dart +++ b/script/tool/test/test_command_test.dart @@ -11,7 +11,7 @@ import 'util.dart'; void main() { group('$TestCommand', () { - CommandRunner runner; + CommandRunner runner; final RecordingProcessRunner processRunner = RecordingProcessRunner(); setUp(() { @@ -19,7 +19,7 @@ void main() { final TestCommand command = TestCommand(mockPackagesDir, mockFileSystem, processRunner: processRunner); - runner = CommandRunner('test_test', 'Test for $TestCommand'); + runner = CommandRunner('test_test', 'Test for $TestCommand'); runner.addCommand(command); }); @@ -43,8 +43,10 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall('flutter', ['test', '--color'], plugin1Dir.path), - ProcessCall('flutter', ['test', '--color'], plugin2Dir.path), + ProcessCall( + 'flutter', const ['test', '--color'], plugin1Dir.path), + ProcessCall( + 'flutter', const ['test', '--color'], plugin2Dir.path), ]), ); @@ -63,7 +65,8 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall('flutter', ['test', '--color'], plugin2Dir.path), + ProcessCall( + 'flutter', const ['test', '--color'], plugin2Dir.path), ]), ); @@ -89,12 +92,12 @@ void main() { orderedEquals([ ProcessCall( 'flutter', - ['test', '--color', '--enable-experiment=exp1'], + const ['test', '--color', '--enable-experiment=exp1'], plugin1Dir.path), - ProcessCall('pub', ['get'], plugin2Dir.path), + ProcessCall('pub', const ['get'], plugin2Dir.path), ProcessCall( 'pub', - ['run', '--enable-experiment=exp1', 'test'], + const ['run', '--enable-experiment=exp1', 'test'], plugin2Dir.path), ]), ); @@ -117,8 +120,10 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall('flutter', - ['test', '--color', '--platform=chrome'], pluginDir.path), + ProcessCall( + 'flutter', + const ['test', '--color', '--platform=chrome'], + pluginDir.path), ]), ); }); @@ -142,12 +147,12 @@ void main() { orderedEquals([ ProcessCall( 'flutter', - ['test', '--color', '--enable-experiment=exp1'], + const ['test', '--color', '--enable-experiment=exp1'], plugin1Dir.path), - ProcessCall('pub', ['get'], plugin2Dir.path), + ProcessCall('pub', const ['get'], plugin2Dir.path), ProcessCall( 'pub', - ['run', '--enable-experiment=exp1', 'test'], + const ['run', '--enable-experiment=exp1', 'test'], plugin2Dir.path), ]), ); diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index d02b756ee9..5a2c42bd31 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -3,11 +3,13 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io' as io; import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:file/memory.dart'; +import 'package:meta/meta.dart'; import 'package:platform/platform.dart'; import 'package:flutter_plugin_tools/src/common.dart'; import 'package:quiver/collection.dart'; @@ -16,7 +18,7 @@ import 'package:quiver/collection.dart'; // for each test, to eliminate the chance of files from one test interfering // with another test. FileSystem mockFileSystem = MemoryFileSystem( - style: LocalPlatform().isWindows + style: const LocalPlatform().isWindows ? FileSystemStyle.windows : FileSystemStyle.posix); Directory mockPackagesDir; @@ -83,20 +85,19 @@ Directory createFakePlugin( final Directory exampleDir = pluginDirectory.childDirectory('example') ..createSync(); createFakePubspec(exampleDir, - name: "${name}_example", isFlutter: isFlutter); + name: '${name}_example', isFlutter: isFlutter); } else if (withExamples.isNotEmpty) { final Directory exampleDir = pluginDirectory.childDirectory('example') ..createSync(); - for (String example in withExamples) { + for (final String example in withExamples) { final Directory currentExample = exampleDir.childDirectory(example) ..createSync(); createFakePubspec(currentExample, name: example, isFlutter: isFlutter); } } - for (List file in withExtraFiles) { - final List newFilePath = [pluginDirectory.path] - ..addAll(file); + for (final List file in withExtraFiles) { + final List newFilePath = [pluginDirectory.path, ...file]; final File newFile = mockFileSystem.file(mockFileSystem.path.joinAll(newFilePath)); newFile.createSync(recursive: true); @@ -195,7 +196,7 @@ void cleanupPackages() { /// Run the command [runner] with the given [args] and return /// what was printed. Future> runCapturingPrint( - CommandRunner runner, List args) async { + CommandRunner runner, List args) async { final List prints = []; final ZoneSpecification spec = ZoneSpecification( print: (_, __, ___, String message) { @@ -237,8 +238,8 @@ class RecordingProcessRunner extends ProcessRunner { Future run(String executable, List args, {Directory workingDir, bool exitOnError = false, - stdoutEncoding = io.systemEncoding, - stderrEncoding = io.systemEncoding}) async { + Encoding stdoutEncoding = io.systemEncoding, + Encoding stderrEncoding = io.systemEncoding}) async { recordedCalls.add(ProcessCall(executable, args, workingDir?.path)); io.ProcessResult result; @@ -279,6 +280,7 @@ class RecordingProcessRunner extends ProcessRunner { } /// A recorded process call. +@immutable class ProcessCall { const ProcessCall(this.executable, this.args, this.workingDir); @@ -293,13 +295,10 @@ class ProcessCall { @override bool operator ==(dynamic other) { - if (other is! ProcessCall) { - return false; - } - final ProcessCall otherCall = other; - return executable == otherCall.executable && - listsEqual(args, otherCall.args) && - workingDir == otherCall.workingDir; + return other is ProcessCall && + executable == other.executable && + listsEqual(args, other.args) && + workingDir == other.workingDir; } @override @@ -311,7 +310,7 @@ class ProcessCall { @override String toString() { - final List command = [executable]..addAll(args); + final List command = [executable, ...args]; return '"${command.join(' ')}" in $workingDir'; } } diff --git a/script/tool/test/version_check_test.dart b/script/tool/test/version_check_test.dart index dc36c6c322..96a460d7e7 100644 --- a/script/tool/test/version_check_test.dart +++ b/script/tool/test/version_check_test.dart @@ -3,14 +3,15 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:io'; +import 'dart:io' as io; import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/common.dart'; import 'package:git/git.dart'; import 'package:mockito/mockito.dart'; -import "package:test/test.dart"; -import "package:flutter_plugin_tools/src/version_check_command.dart"; +import 'package:test/test.dart'; +import 'package:flutter_plugin_tools/src/version_check_command.dart'; import 'package:pub_semver/pub_semver.dart'; import 'util.dart'; @@ -36,11 +37,11 @@ void testAllowedVersion( class MockGitDir extends Mock implements GitDir {} -class MockProcessResult extends Mock implements ProcessResult {} +class MockProcessResult extends Mock implements io.ProcessResult {} void main() { group('$VersionCheckCommand', () { - CommandRunner runner; + CommandRunner runner; RecordingProcessRunner processRunner; List> gitDirCommands; String gitDiffResponse; @@ -52,16 +53,17 @@ void main() { gitShowResponses = {}; final MockGitDir gitDir = MockGitDir(); when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { - gitDirCommands.add(invocation.positionalArguments[0]); + gitDirCommands.add(invocation.positionalArguments[0] as List); final MockProcessResult mockProcessResult = MockProcessResult(); if (invocation.positionalArguments[0][0] == 'diff') { - when(mockProcessResult.stdout).thenReturn(gitDiffResponse); + when(mockProcessResult.stdout as String) + .thenReturn(gitDiffResponse); } else if (invocation.positionalArguments[0][0] == 'show') { final String response = gitShowResponses[invocation.positionalArguments[0][1]]; - when(mockProcessResult.stdout).thenReturn(response); + when(mockProcessResult.stdout as String).thenReturn(response); } - return Future.value(mockProcessResult); + return Future.value(mockProcessResult); }); initializeFakePackages(); processRunner = RecordingProcessRunner(); @@ -69,7 +71,7 @@ void main() { mockPackagesDir, mockFileSystem, processRunner: processRunner, gitDir: gitDir); - runner = CommandRunner( + runner = CommandRunner( 'version_check_command', 'Test for $VersionCheckCommand'); runner.addCommand(command); }); @@ -80,7 +82,7 @@ void main() { test('allows valid version', () async { createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); - gitDiffResponse = "packages/plugin/pubspec.yaml"; + gitDiffResponse = 'packages/plugin/pubspec.yaml'; gitShowResponses = { 'master:packages/plugin/pubspec.yaml': 'version: 1.0.0', 'HEAD:packages/plugin/pubspec.yaml': 'version: 2.0.0', @@ -105,7 +107,7 @@ void main() { test('denies invalid version', () async { createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); - gitDiffResponse = "packages/plugin/pubspec.yaml"; + gitDiffResponse = 'packages/plugin/pubspec.yaml'; gitShowResponses = { 'master:packages/plugin/pubspec.yaml': 'version: 0.0.1', 'HEAD:packages/plugin/pubspec.yaml': 'version: 0.2.0', @@ -128,7 +130,7 @@ void main() { test('gracefully handles missing pubspec.yaml', () async { createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); - gitDiffResponse = "packages/plugin/pubspec.yaml"; + gitDiffResponse = 'packages/plugin/pubspec.yaml'; mockFileSystem.currentDirectory .childDirectory('packages') .childDirectory('plugin') @@ -152,7 +154,7 @@ void main() { test('allows minor changes to platform interfaces', () async { createFakePlugin('plugin_platform_interface', includeChangeLog: true, includeVersion: true); - gitDiffResponse = "packages/plugin_platform_interface/pubspec.yaml"; + gitDiffResponse = 'packages/plugin_platform_interface/pubspec.yaml'; gitShowResponses = { 'master:packages/plugin_platform_interface/pubspec.yaml': 'version: 1.0.0', @@ -181,7 +183,7 @@ void main() { test('disallows breaking changes to platform interfaces', () async { createFakePlugin('plugin_platform_interface', includeChangeLog: true, includeVersion: true); - gitDiffResponse = "packages/plugin_platform_interface/pubspec.yaml"; + gitDiffResponse = 'packages/plugin_platform_interface/pubspec.yaml'; gitShowResponses = { 'master:packages/plugin_platform_interface/pubspec.yaml': 'version: 1.0.0', @@ -214,7 +216,7 @@ void main() { createFakePubspec(pluginDirectory, isFlutter: true, includeVersion: true, version: '1.0.1'); - String changelog = ''' + const String changelog = ''' @@ -225,9 +227,9 @@ void main() { createFakeCHANGELOG(pluginDirectory, changelog); final List output = await runCapturingPrint( runner, ['version-check', '--base-sha=master']); - await expect( + expect( output, - containsAllInOrder([ + containsAllInOrder([ 'Checking the first version listed in CHANGELOG.MD matches the version in pubspec.yaml for plugin.', 'plugin passed version check', 'No version check errors found!' @@ -243,7 +245,7 @@ void main() { createFakePubspec(pluginDirectory, isFlutter: true, includeVersion: true, version: '1.0.1'); - String changelog = ''' + const String changelog = ''' ## 1.0.2 * Some changes. @@ -256,10 +258,10 @@ void main() { throwsA(const TypeMatcher()), ); try { - List outputValue = await output; + final List outputValue = await output; await expectLater( outputValue, - containsAllInOrder([ + containsAllInOrder([ ''' versions for plugin in CHANGELOG.md and pubspec.yaml do not match. The version in pubspec.yaml is 1.0.1. @@ -278,7 +280,7 @@ void main() { createFakePubspec(pluginDirectory, isFlutter: true, includeVersion: true, version: '1.0.1'); - String changelog = ''' + const String changelog = ''' ## 1.0.1 * Some changes. @@ -286,9 +288,9 @@ void main() { createFakeCHANGELOG(pluginDirectory, changelog); final List output = await runCapturingPrint( runner, ['version-check', '--base-sha=master']); - await expect( + expect( output, - containsAllInOrder([ + containsAllInOrder([ 'Checking the first version listed in CHANGELOG.MD matches the version in pubspec.yaml for plugin.', 'plugin passed version check', 'No version check errors found!' @@ -306,7 +308,7 @@ void main() { createFakePubspec(pluginDirectory, isFlutter: true, includeVersion: true, version: '1.0.0'); - String changelog = ''' + const String changelog = ''' ## 1.0.1 * Some changes. @@ -316,17 +318,17 @@ void main() { * Some other changes. '''; createFakeCHANGELOG(pluginDirectory, changelog); - Future> output = runCapturingPrint( + final Future> output = runCapturingPrint( runner, ['version-check', '--base-sha=master']); await expectLater( output, throwsA(const TypeMatcher()), ); try { - List outputValue = await output; + final List outputValue = await output; await expectLater( outputValue, - containsAllInOrder([ + containsAllInOrder([ ''' versions for plugin in CHANGELOG.md and pubspec.yaml do not match. The version in pubspec.yaml is 1.0.0. @@ -338,122 +340,97 @@ void main() { }); }); - group("Pre 1.0", () { - test("nextVersion allows patch version", () { - testAllowedVersion("0.12.0", "0.12.0+1", + group('Pre 1.0', () { + test('nextVersion allows patch version', () { + testAllowedVersion('0.12.0', '0.12.0+1', nextVersionType: NextVersionType.PATCH); - testAllowedVersion("0.12.0+4", "0.12.0+5", + testAllowedVersion('0.12.0+4', '0.12.0+5', nextVersionType: NextVersionType.PATCH); }); - test("nextVersion does not allow jumping patch", () { - testAllowedVersion("0.12.0", "0.12.0+2", allowed: false); - testAllowedVersion("0.12.0+2", "0.12.0+4", allowed: false); + test('nextVersion does not allow jumping patch', () { + testAllowedVersion('0.12.0', '0.12.0+2', allowed: false); + testAllowedVersion('0.12.0+2', '0.12.0+4', allowed: false); }); - test("nextVersion does not allow going back", () { - testAllowedVersion("0.12.0", "0.11.0", allowed: false); - testAllowedVersion("0.12.0+2", "0.12.0+1", allowed: false); - testAllowedVersion("0.12.0+1", "0.12.0", allowed: false); + test('nextVersion does not allow going back', () { + testAllowedVersion('0.12.0', '0.11.0', allowed: false); + testAllowedVersion('0.12.0+2', '0.12.0+1', allowed: false); + testAllowedVersion('0.12.0+1', '0.12.0', allowed: false); }); - test("nextVersion allows minor version", () { - testAllowedVersion("0.12.0", "0.12.1", + test('nextVersion allows minor version', () { + testAllowedVersion('0.12.0', '0.12.1', nextVersionType: NextVersionType.MINOR); - testAllowedVersion("0.12.0+4", "0.12.1", + testAllowedVersion('0.12.0+4', '0.12.1', nextVersionType: NextVersionType.MINOR); }); - test("nextVersion does not allow jumping minor", () { - testAllowedVersion("0.12.0", "0.12.2", allowed: false); - testAllowedVersion("0.12.0+2", "0.12.3", allowed: false); + test('nextVersion does not allow jumping minor', () { + testAllowedVersion('0.12.0', '0.12.2', allowed: false); + testAllowedVersion('0.12.0+2', '0.12.3', allowed: false); }); }); - group("Releasing 1.0", () { - test("nextVersion allows releasing 1.0", () { - testAllowedVersion("0.12.0", "1.0.0", + group('Releasing 1.0', () { + test('nextVersion allows releasing 1.0', () { + testAllowedVersion('0.12.0', '1.0.0', nextVersionType: NextVersionType.BREAKING_MAJOR); - testAllowedVersion("0.12.0+4", "1.0.0", + testAllowedVersion('0.12.0+4', '1.0.0', nextVersionType: NextVersionType.BREAKING_MAJOR); }); - test("nextVersion does not allow jumping major", () { - testAllowedVersion("0.12.0", "2.0.0", allowed: false); - testAllowedVersion("0.12.0+4", "2.0.0", allowed: false); + test('nextVersion does not allow jumping major', () { + testAllowedVersion('0.12.0', '2.0.0', allowed: false); + testAllowedVersion('0.12.0+4', '2.0.0', allowed: false); }); - test("nextVersion does not allow un-releasing", () { - testAllowedVersion("1.0.0", "0.12.0+4", allowed: false); - testAllowedVersion("1.0.0", "0.12.0", allowed: false); + test('nextVersion does not allow un-releasing', () { + testAllowedVersion('1.0.0', '0.12.0+4', allowed: false); + testAllowedVersion('1.0.0', '0.12.0', allowed: false); }); }); - group("Post 1.0", () { - test("nextVersion allows patch jumps", () { - testAllowedVersion("1.0.1", "1.0.2", + group('Post 1.0', () { + test('nextVersion allows patch jumps', () { + testAllowedVersion('1.0.1', '1.0.2', nextVersionType: NextVersionType.PATCH); - testAllowedVersion("1.0.0", "1.0.1", + testAllowedVersion('1.0.0', '1.0.1', nextVersionType: NextVersionType.PATCH); }); - test("nextVersion does not allow build jumps", () { - testAllowedVersion("1.0.1", "1.0.1+1", allowed: false); - testAllowedVersion("1.0.0+5", "1.0.0+6", allowed: false); + test('nextVersion does not allow build jumps', () { + testAllowedVersion('1.0.1', '1.0.1+1', allowed: false); + testAllowedVersion('1.0.0+5', '1.0.0+6', allowed: false); }); - test("nextVersion does not allow skipping patches", () { - testAllowedVersion("1.0.1", "1.0.3", allowed: false); - testAllowedVersion("1.0.0", "1.0.6", allowed: false); + test('nextVersion does not allow skipping patches', () { + testAllowedVersion('1.0.1', '1.0.3', allowed: false); + testAllowedVersion('1.0.0', '1.0.6', allowed: false); }); - test("nextVersion allows minor version jumps", () { - testAllowedVersion("1.0.1", "1.1.0", + test('nextVersion allows minor version jumps', () { + testAllowedVersion('1.0.1', '1.1.0', nextVersionType: NextVersionType.MINOR); - testAllowedVersion("1.0.0", "1.1.0", + testAllowedVersion('1.0.0', '1.1.0', nextVersionType: NextVersionType.MINOR); }); - test("nextVersion does not allow skipping minor versions", () { - testAllowedVersion("1.0.1", "1.2.0", allowed: false); - testAllowedVersion("1.1.0", "1.3.0", allowed: false); + test('nextVersion does not allow skipping minor versions', () { + testAllowedVersion('1.0.1', '1.2.0', allowed: false); + testAllowedVersion('1.1.0', '1.3.0', allowed: false); }); - test("nextVersion allows breaking changes", () { - testAllowedVersion("1.0.1", "2.0.0", + test('nextVersion allows breaking changes', () { + testAllowedVersion('1.0.1', '2.0.0', nextVersionType: NextVersionType.BREAKING_MAJOR); - testAllowedVersion("1.0.0", "2.0.0", + testAllowedVersion('1.0.0', '2.0.0', nextVersionType: NextVersionType.BREAKING_MAJOR); }); - test("nextVersion allows null safety pre prelease", () { - testAllowedVersion("1.0.1", "2.0.0-nullsafety", - nextVersionType: NextVersionType.MAJOR_NULLSAFETY_PRE_RELEASE); - testAllowedVersion("1.0.0", "2.0.0-nullsafety", - nextVersionType: NextVersionType.MAJOR_NULLSAFETY_PRE_RELEASE); - testAllowedVersion("1.0.0-nullsafety", "1.0.0-nullsafety.1", - nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); - testAllowedVersion("1.0.0-nullsafety.1", "1.0.0-nullsafety.2", - nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); - testAllowedVersion("0.1.0", "0.2.0-nullsafety", - nextVersionType: NextVersionType.MAJOR_NULLSAFETY_PRE_RELEASE); - testAllowedVersion("0.1.0-nullsafety", "0.1.0-nullsafety.1", - nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); - testAllowedVersion("0.1.0-nullsafety.1", "0.1.0-nullsafety.2", - nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); - testAllowedVersion("1.0.0", "1.1.0-nullsafety", - nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); - testAllowedVersion("1.1.0-nullsafety", "1.1.0-nullsafety.1", - nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); - testAllowedVersion("0.1.0", "0.1.1-nullsafety", - nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); - testAllowedVersion("0.1.1-nullsafety", "0.1.1-nullsafety.1", - nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); - }); - - test("nextVersion does not allow skipping major versions", () { - testAllowedVersion("1.0.1", "3.0.0", allowed: false); - testAllowedVersion("1.1.0", "2.3.0", allowed: false); + test('nextVersion does not allow skipping major versions', () { + testAllowedVersion('1.0.1', '3.0.0', allowed: false); + testAllowedVersion('1.1.0', '2.3.0', allowed: false); }); }); } diff --git a/script/tool/test/xctest_command_test.dart b/script/tool/test/xctest_command_test.dart index aa71c25835..1707dc8cfb 100644 --- a/script/tool/test/xctest_command_test.dart +++ b/script/tool/test/xctest_command_test.dart @@ -12,67 +12,67 @@ import 'package:test/test.dart'; import 'mocks.dart'; import 'util.dart'; -final _kDeviceListMap = { - "runtimes": [ - { - "bundlePath": - "/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.0.simruntime", - "buildversion": "17A577", - "runtimeRoot": - "/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.0.simruntime/Contents/Resources/RuntimeRoot", - "identifier": "com.apple.CoreSimulator.SimRuntime.iOS-13-0", - "version": "13.0", - "isAvailable": true, - "name": "iOS 13.0" +final Map _kDeviceListMap = { + 'runtimes': >[ + { + 'bundlePath': + '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.0.simruntime', + 'buildversion': '17A577', + 'runtimeRoot': + '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.0.simruntime/Contents/Resources/RuntimeRoot', + 'identifier': 'com.apple.CoreSimulator.SimRuntime.iOS-13-0', + 'version': '13.0', + 'isAvailable': true, + 'name': 'iOS 13.0' }, - { - "bundlePath": - "/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime", - "buildversion": "17L255", - "runtimeRoot": - "/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime/Contents/Resources/RuntimeRoot", - "identifier": "com.apple.CoreSimulator.SimRuntime.iOS-13-4", - "version": "13.4", - "isAvailable": true, - "name": "iOS 13.4" + { + 'bundlePath': + '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime', + 'buildversion': '17L255', + 'runtimeRoot': + '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime/Contents/Resources/RuntimeRoot', + 'identifier': 'com.apple.CoreSimulator.SimRuntime.iOS-13-4', + 'version': '13.4', + 'isAvailable': true, + 'name': 'iOS 13.4' }, - { - "bundlePath": - "/Applications/Xcode_11_7.app/Contents/Developer/Platforms/WatchOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/watchOS.simruntime", - "buildversion": "17T531", - "runtimeRoot": - "/Applications/Xcode_11_7.app/Contents/Developer/Platforms/WatchOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/watchOS.simruntime/Contents/Resources/RuntimeRoot", - "identifier": "com.apple.CoreSimulator.SimRuntime.watchOS-6-2", - "version": "6.2.1", - "isAvailable": true, - "name": "watchOS 6.2" + { + 'bundlePath': + '/Applications/Xcode_11_7.app/Contents/Developer/Platforms/WatchOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/watchOS.simruntime', + 'buildversion': '17T531', + 'runtimeRoot': + '/Applications/Xcode_11_7.app/Contents/Developer/Platforms/WatchOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/watchOS.simruntime/Contents/Resources/RuntimeRoot', + 'identifier': 'com.apple.CoreSimulator.SimRuntime.watchOS-6-2', + 'version': '6.2.1', + 'isAvailable': true, + 'name': 'watchOS 6.2' } ], - "devices": { - "com.apple.CoreSimulator.SimRuntime.iOS-13-4": [ - { - "dataPath": - "/Users/xxx/Library/Developer/CoreSimulator/Devices/2706BBEB-1E01-403E-A8E9-70E8E5A24774/data", - "logPath": - "/Users/xxx/Library/Logs/CoreSimulator/2706BBEB-1E01-403E-A8E9-70E8E5A24774", - "udid": "2706BBEB-1E01-403E-A8E9-70E8E5A24774", - "isAvailable": true, - "deviceTypeIdentifier": - "com.apple.CoreSimulator.SimDeviceType.iPhone-8", - "state": "Shutdown", - "name": "iPhone 8" + 'devices': { + 'com.apple.CoreSimulator.SimRuntime.iOS-13-4': >[ + { + 'dataPath': + '/Users/xxx/Library/Developer/CoreSimulator/Devices/2706BBEB-1E01-403E-A8E9-70E8E5A24774/data', + 'logPath': + '/Users/xxx/Library/Logs/CoreSimulator/2706BBEB-1E01-403E-A8E9-70E8E5A24774', + 'udid': '2706BBEB-1E01-403E-A8E9-70E8E5A24774', + 'isAvailable': true, + 'deviceTypeIdentifier': + 'com.apple.CoreSimulator.SimDeviceType.iPhone-8', + 'state': 'Shutdown', + 'name': 'iPhone 8' }, - { - "dataPath": - "/Users/xxx/Library/Developer/CoreSimulator/Devices/1E76A0FD-38AC-4537-A989-EA639D7D012A/data", - "logPath": - "/Users/xxx/Library/Logs/CoreSimulator/1E76A0FD-38AC-4537-A989-EA639D7D012A", - "udid": "1E76A0FD-38AC-4537-A989-EA639D7D012A", - "isAvailable": true, - "deviceTypeIdentifier": - "com.apple.CoreSimulator.SimDeviceType.iPhone-8-Plus", - "state": "Shutdown", - "name": "iPhone 8 Plus" + { + 'dataPath': + '/Users/xxx/Library/Developer/CoreSimulator/Devices/1E76A0FD-38AC-4537-A989-EA639D7D012A/data', + 'logPath': + '/Users/xxx/Library/Logs/CoreSimulator/1E76A0FD-38AC-4537-A989-EA639D7D012A', + 'udid': '1E76A0FD-38AC-4537-A989-EA639D7D012A', + 'isAvailable': true, + 'deviceTypeIdentifier': + 'com.apple.CoreSimulator.SimDeviceType.iPhone-8-Plus', + 'state': 'Shutdown', + 'name': 'iPhone 8 Plus' } ] } @@ -83,7 +83,7 @@ void main() { const String _kSkip = '--skip'; group('test xctest_command', () { - CommandRunner runner; + CommandRunner runner; RecordingProcessRunner processRunner; setUp(() { @@ -93,7 +93,7 @@ void main() { mockPackagesDir, mockFileSystem, processRunner: processRunner); - runner = CommandRunner('xctest_command', 'Test for xctest_command'); + runner = CommandRunner('xctest_command', 'Test for xctest_command'); runner.addCommand(command); cleanupPackages(); }); @@ -113,19 +113,15 @@ void main() { final MockProcess mockProcess = MockProcess(); mockProcess.exitCodeCompleter.complete(0); processRunner.processToReturn = mockProcess; - final List output = await runCapturingPrint(runner, [ - 'xctest', - _kDestination, - 'foo_destination' - ]); + final List output = await runCapturingPrint( + runner, ['xctest', _kDestination, 'foo_destination']); expect(output, contains('iOS is not supported by this plugin.')); expect(processRunner.recordedCalls, orderedEquals([])); cleanupPackages(); }); - test('running with correct destination, skip 1 plugin', - () async { + test('running with correct destination, skip 1 plugin', () async { createFakePlugin('plugin1', withExtraFiles: >[ ['example', 'test'], @@ -149,7 +145,7 @@ void main() { processRunner.processToReturn = mockProcess; processRunner.resultStdout = '{"project":{"targets":["bar_scheme", "foo_scheme"]}}'; - List output = await runCapturingPrint(runner, [ + final List output = await runCapturingPrint(runner, [ 'xctest', _kDestination, 'foo_destination', @@ -165,7 +161,7 @@ void main() { orderedEquals([ ProcessCall( 'xcrun', - [ + const [ 'xcodebuild', 'test', 'analyze', @@ -203,9 +199,9 @@ void main() { final MockProcess mockProcess = MockProcess(); mockProcess.exitCodeCompleter.complete(0); processRunner.processToReturn = mockProcess; - final Map schemeCommandResult = { - "project": { - "targets": ["bar_scheme", "foo_scheme"] + final Map schemeCommandResult = { + 'project': { + 'targets': ['bar_scheme', 'foo_scheme'] } }; // For simplicity of the test, we combine all the mock results into a single mock result, each internal command @@ -219,10 +215,11 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall('xcrun', ['simctl', 'list', '--json'], null), + const ProcessCall( + 'xcrun', ['simctl', 'list', '--json'], null), ProcessCall( 'xcrun', - [ + const [ 'xcodebuild', 'test', 'analyze',