diff --git a/.cirrus.yml b/.cirrus.yml index e3d6f7881382..2598bfe7e426 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -194,6 +194,12 @@ task: << : *MACOS_TEMPLATE << : *FLUTTER_UPGRADE_TEMPLATE matrix: + ### iOS+macOS tasks *** + - name: lint_darwin_plugins + script: + # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. + - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm + - ./script/tool_runner.sh podspecs ### iOS tasks ### - name: build_all_plugins_ipa env: @@ -251,14 +257,3 @@ task: - ./script/tool_runner.sh build-examples --macos --no-ipa drive_script: - ./script/tool_runner.sh drive-examples --macos - -task: - # Don't use FLUTTER_UPGRADE_TEMPLATE, Flutter tooling not needed. - << : *MACOS_TEMPLATE - << : *TOOL_SETUP_TEMPLATE - matrix: - - name: lint_darwin_plugins - script: - # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. - - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm - - ./script/tool_runner.sh podspecs diff --git a/script/tool/bin/flutter_plugin_tools.dart b/script/tool/bin/flutter_plugin_tools.dart index 0f30bee0d258..eea0db5a7f01 100644 --- a/script/tool/bin/flutter_plugin_tools.dart +++ b/script/tool/bin/flutter_plugin_tools.dart @@ -2,4 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + export 'package:flutter_plugin_tools/src/main.dart'; diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart index 61be5f98a620..ec22e0683924 100644 --- a/script/tool/lib/src/analyze_command.dart +++ b/script/tool/lib/src/analyze_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; @@ -42,8 +44,8 @@ class AnalyzeCommand extends PluginCommand { continue; } - final bool allowed = (argResults[_customAnalysisFlag] as List) - .any((String directory) => + final bool allowed = (getStringListArg(_customAnalysisFlag)).any( + (String directory) => directory != null && directory.isNotEmpty && p.isWithin(p.join(packagesDir.path, directory), file.path)); diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart index 0069c0586810..f7129865630d 100644 --- a/script/tool/lib/src/build_examples_command.dart +++ b/script/tool/lib/src/build_examples_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:io' as io; @@ -52,7 +54,7 @@ class BuildExamplesCommand extends PluginCommand { ]; final Map platforms = { for (final String platform in platformSwitches) - platform: argResults[platform] as bool + platform: getBoolArg(platform) }; if (!platforms.values.any((bool enabled) => enabled)) { print( @@ -63,7 +65,7 @@ class BuildExamplesCommand extends PluginCommand { final String flutterCommand = const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; - final String enableExperiment = argResults[kEnableExperiment] as String; + final String enableExperiment = getStringArg(kEnableExperiment); final List failingPackages = []; await for (final Directory plugin in getPlugins()) { diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index 1e864fcbc38a..e975ec1ebeb5 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -12,14 +12,13 @@ import 'package:colorize/colorize.dart'; import 'package:file/file.dart'; import 'package:git/git.dart'; import 'package:http/http.dart' as http; -import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; import 'package:pub_semver/pub_semver.dart'; import 'package:yaml/yaml.dart'; /// The signature for a print handler for commands that allow overriding the /// print destination. -typedef Print = void Function(Object object); +typedef Print = void Function(Object? object); /// Key for windows platform. const String kWindows = 'windows'; @@ -50,7 +49,7 @@ const String kEnableExperiment = 'enable-experiment'; /// Returns whether the given directory contains a Flutter package. bool isFlutterPackage(FileSystemEntity entity, FileSystem fileSystem) { - if (entity == null || entity is! Directory) { + if (entity is! Directory) { return false; } @@ -59,7 +58,7 @@ bool isFlutterPackage(FileSystemEntity entity, FileSystem fileSystem) { fileSystem.file(p.join(entity.path, 'pubspec.yaml')); final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()) as YamlMap; - final YamlMap dependencies = pubspecYaml['dependencies'] as YamlMap; + final YamlMap? dependencies = pubspecYaml['dependencies'] as YamlMap?; if (dependencies == null) { return false; } @@ -87,7 +86,7 @@ bool pluginSupportsPlatform( platform == kMacos || platform == kWindows || platform == kLinux); - if (entity == null || entity is! Directory) { + if (entity is! Directory) { return false; } @@ -96,15 +95,15 @@ bool pluginSupportsPlatform( fileSystem.file(p.join(entity.path, 'pubspec.yaml')); final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()) as YamlMap; - final YamlMap flutterSection = pubspecYaml['flutter'] as YamlMap; + final YamlMap? flutterSection = pubspecYaml['flutter'] as YamlMap?; if (flutterSection == null) { return false; } - final YamlMap pluginSection = flutterSection['plugin'] as YamlMap; + final YamlMap? pluginSection = flutterSection['plugin'] as YamlMap?; if (pluginSection == null) { return false; } - final YamlMap platforms = pluginSection['platforms'] as YamlMap; + final YamlMap? platforms = pluginSection['platforms'] as YamlMap?; if (platforms == null) { // Legacy plugin specs are assumed to support iOS and Android. if (!pluginSection.containsKey('platforms')) { @@ -151,7 +150,7 @@ bool isLinuxPlugin(FileSystemEntity entity, FileSystem fileSystem) { } /// Throws a [ToolExit] with `exitCode` and log the `errorMessage` in red. -void printErrorAndExit({@required String errorMessage, int exitCode = 1}) { +void printErrorAndExit({required String errorMessage, int exitCode = 1}) { final Colorize redError = Colorize(errorMessage)..red(); print(redError); throw ToolExit(exitCode); @@ -236,17 +235,17 @@ abstract class PluginCommand extends Command { /// The git directory to use. By default it uses the parent directory. /// /// This can be mocked for testing. - final GitDir gitDir; + final GitDir? gitDir; - int _shardIndex; - int _shardCount; + int? _shardIndex; + int? _shardCount; /// The shard of the overall command execution that this instance should run. int get shardIndex { if (_shardIndex == null) { _checkSharding(); } - return _shardIndex; + return _shardIndex!; } /// The number of shards this command is divided into. @@ -254,12 +253,27 @@ abstract class PluginCommand extends Command { if (_shardCount == null) { _checkSharding(); } - return _shardCount; + return _shardCount!; + } + + /// Convenience accessor for boolean arguments. + bool getBoolArg(String key) { + return (argResults![key] as bool?) ?? false; + } + + /// Convenience accessor for String arguments. + String getStringArg(String key) { + return (argResults![key] as String?) ?? ''; + } + + /// Convenience accessor for List arguments. + List getStringListArg(String key) { + return (argResults![key] as List?) ?? []; } void _checkSharding() { - final int shardIndex = int.tryParse(argResults[_shardIndexArg] as String); - final int shardCount = int.tryParse(argResults[_shardCountArg] as String); + final int? shardIndex = int.tryParse(getStringArg(_shardIndexArg)); + final int? shardCount = int.tryParse(getStringArg(_shardCountArg)); if (shardIndex == null) { usageException('$_shardIndexArg must be an integer'); } @@ -317,12 +331,10 @@ abstract class PluginCommand extends Command { /// is a sibling of the packages directory. This is used for a small number /// of packages in the flutter/packages repository. Stream _getAllPlugins() async* { - Set plugins = - Set.from(argResults[_pluginsArg] as List); + Set plugins = Set.from(getStringListArg(_pluginsArg)); final Set excludedPlugins = - Set.from(argResults[_excludeArg] as List); - final bool runOnChangedPackages = - argResults[_runOnChangedPackagesArg] as bool; + Set.from(getStringListArg(_excludeArg)); + final bool runOnChangedPackages = getBoolArg(_runOnChangedPackagesArg); if (plugins.isEmpty && runOnChangedPackages) { plugins = await _getChangedPackages(); } @@ -429,9 +441,9 @@ 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; - final String baseSha = argResults[_kBaseSha] as String; + final String baseSha = getStringArg(_kBaseSha); - GitDir baseGitDir = gitDir; + GitDir? baseGitDir = gitDir; if (baseGitDir == null) { if (!await GitDir.isGitDir(rootDir)) { printErrorAndExit( @@ -490,7 +502,7 @@ class ProcessRunner { Future runAndStream( String executable, List args, { - Directory workingDir, + Directory? workingDir, bool exitOnError = false, }) async { print( @@ -522,7 +534,7 @@ class ProcessRunner { /// /// Returns the [io.ProcessResult] of the [executable]. Future run(String executable, List args, - {Directory workingDir, + {Directory? workingDir, bool exitOnError = false, bool logOnError = false, Encoding stdoutEncoding = io.systemEncoding, @@ -550,15 +562,15 @@ class ProcessRunner { /// passing [workingDir]. /// /// Returns the started [io.Process]. - Future start(String executable, List args, - {Directory workingDirectory}) async { + Future start(String executable, List args, + {Directory? workingDirectory}) async { final io.Process process = await io.Process.start(executable, args, workingDirectory: workingDirectory?.path); return process; } String _getErrorString(String executable, List args, - {Directory workingDir}) { + {Directory? workingDir}) { final String workdir = workingDir == null ? '' : ' in ${workingDir.path}'; return 'ERROR: Unable to execute "$executable ${args.join(' ')}"$workdir.'; } @@ -569,7 +581,7 @@ class PubVersionFinder { /// Constructor. /// /// Note: you should manually close the [httpClient] when done using the finder. - PubVersionFinder({this.pubHost = defaultPubHost, @required this.httpClient}); + PubVersionFinder({this.pubHost = defaultPubHost, required this.httpClient}); /// The default pub host to use. static const String defaultPubHost = 'https://pub.dev'; @@ -584,8 +596,8 @@ class PubVersionFinder { /// Get the package version on pub. Future getPackageVersion( - {@required String package}) async { - assert(package != null && package.isNotEmpty); + {required String package}) async { + assert(package.isNotEmpty); final Uri pubHostUri = Uri.parse(pubHost); final Uri url = pubHostUri.replace(path: '/packages/$package.json'); final http.Response response = await httpClient.get(url); @@ -618,8 +630,8 @@ class PubVersionFinder { class PubVersionFinderResponse { /// Constructor. PubVersionFinderResponse({this.versions, this.result, this.httpResponse}) { - if (versions != null && versions.isNotEmpty) { - versions.sort((Version a, Version b) { + if (versions != null && versions!.isNotEmpty) { + versions!.sort((Version a, Version b) { // TODO(cyanglaz): Think about how to handle pre-release version with [Version.prioritize]. // https://github.com/flutter/flutter/issues/82222 return b.compareTo(a); @@ -631,13 +643,13 @@ class PubVersionFinderResponse { /// /// This is sorted by largest to smallest, so the first element in the list is the largest version. /// Might be `null` if the [result] is not [PubVersionFinderResult.success]. - final List versions; + final List? versions; /// The result of the version finder. - final PubVersionFinderResult result; + final PubVersionFinderResult? result; /// The response object of the http request. - final http.Response httpResponse; + final http.Response? httpResponse; } /// An enum representing the result of [PubVersionFinder]. @@ -667,7 +679,7 @@ class GitVersionFinder { final GitDir baseGitDir; /// The base sha used to get diff. - final String baseSha; + final String? baseSha; static bool _isPubspec(String file) { return file.trim().endsWith('pubspec.yaml'); @@ -684,8 +696,7 @@ class GitVersionFinder { final io.ProcessResult changedFilesCommand = await baseGitDir .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 []; } @@ -696,7 +707,8 @@ class GitVersionFinder { /// Get the package version specified in the pubspec file in `pubspecPath` and /// at the revision of `gitRef` (defaulting to the base if not provided). - Future getPackageVersion(String pubspecPath, {String gitRef}) async { + Future getPackageVersion(String pubspecPath, + {String? gitRef}) async { final String ref = gitRef ?? (await _getBaseSha()); io.ProcessResult gitShow; @@ -707,20 +719,19 @@ class GitVersionFinder { return null; } final String fileContent = gitShow.stdout as String; - final String versionString = loadYaml(fileContent)['version'] as String; + final String? versionString = loadYaml(fileContent)['version'] as String?; return versionString == null ? null : Version.parse(versionString); } Future _getBaseSha() async { - if (baseSha != null && baseSha.isNotEmpty) { - return baseSha; + if (baseSha != null && baseSha!.isNotEmpty) { + return baseSha!; } io.ProcessResult baseShaFromMergeBase = await baseGitDir.runCommand( ['merge-base', '--fork-point', 'FETCH_HEAD', 'HEAD'], throwOnError: false); - if (baseShaFromMergeBase == null || - baseShaFromMergeBase.stderr != null || + if (baseShaFromMergeBase.stderr != null || baseShaFromMergeBase.stdout == null) { baseShaFromMergeBase = await baseGitDir .runCommand(['merge-base', 'FETCH_HEAD', 'HEAD']); 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 4b5b4c6b8df4..d825703f1731 100644 --- a/script/tool/lib/src/create_all_plugins_app_command.dart +++ b/script/tool/lib/src/create_all_plugins_app_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:io' as io; diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index 1572b941078e..76ba8205e177 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; import 'package:path/path.dart' as p; @@ -53,10 +55,10 @@ class DriveExamplesCommand extends PluginCommand { Future run() async { final List failingTests = []; final List pluginsWithoutTests = []; - final bool isLinux = argResults[kLinux] == true; - final bool isMacos = argResults[kMacos] == true; - final bool isWeb = argResults[kWeb] == true; - final bool isWindows = argResults[kWindows] == true; + final bool isLinux = getBoolArg(kLinux); + final bool isMacos = getBoolArg(kMacos); + final bool isWeb = getBoolArg(kWeb); + final bool isWindows = getBoolArg(kWindows); await for (final Directory plugin in getPlugins()) { final String pluginName = plugin.basename; if (pluginName.endsWith('_platform_interface') && @@ -140,8 +142,7 @@ Tried searching for the following: final List driveArgs = ['drive']; - final String enableExperiment = - argResults[kEnableExperiment] as String; + final String enableExperiment = getStringArg(kEnableExperiment); if (enableExperiment.isNotEmpty) { driveArgs.add('--enable-experiment=$enableExperiment'); } @@ -222,12 +223,12 @@ Tried searching for the following: Future _pluginSupportedOnCurrentPlatform( FileSystemEntity plugin, FileSystem fileSystem) async { - 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; + final bool isAndroid = getBoolArg(kAndroid); + final bool isIOS = getBoolArg(kIos); + final bool isLinux = getBoolArg(kLinux); + final bool isMacos = getBoolArg(kMacos); + final bool isWeb = getBoolArg(kWeb); + final bool isWindows = getBoolArg(kWindows); if (isAndroid) { 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 ff7d05bf4e89..2d91deffa2c4 100644 --- a/script/tool/lib/src/firebase_test_lab_command.dart +++ b/script/tool/lib/src/firebase_test_lab_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:io' as io; @@ -30,7 +32,7 @@ class FirebaseTestLabCommand extends PluginCommand { defaultsTo: p.join(io.Platform.environment['HOME'], 'gcloud-service-key.json')); argParser.addOption('test-run-id', - defaultsTo: Uuid().v4(), + defaultsTo: const Uuid().v4(), help: 'Optional string to append to the results path, to avoid conflicts. ' 'Randomly chosen on each invocation if none is provided. ' @@ -78,7 +80,7 @@ class FirebaseTestLabCommand extends PluginCommand { [ 'auth', 'activate-service-account', - '--key-file=${argResults['service-key']}', + '--key-file=${getStringArg('service-key')}', ], exitOnError: true, logOnError: true, @@ -87,7 +89,7 @@ class FirebaseTestLabCommand extends PluginCommand { 'config', 'set', 'project', - argResults['project'] as String, + getStringArg('project'), ]); if (exitCode == 0) { _print('\nFirebase project configured.'); @@ -125,7 +127,7 @@ class FirebaseTestLabCommand extends PluginCommand { final Directory androidDirectory = fileSystem.directory(p.join(exampleDirectory.path, 'android')); - final String enableExperiment = argResults[kEnableExperiment] as String; + final String enableExperiment = getStringArg(kEnableExperiment); final String encodedEnableExperiment = Uri.encodeComponent('--enable-experiment=$enableExperiment'); @@ -213,7 +215,7 @@ class FirebaseTestLabCommand extends PluginCommand { continue; } final String buildId = io.Platform.environment['CIRRUS_BUILD_ID']; - final String testRunId = argResults['test-run-id'] as String; + final String testRunId = getStringArg('test-run-id'); final String resultsDir = 'plugins_android_test/$packageName/$buildId/$testRunId/${resultsCounter++}/'; final List args = [ @@ -229,10 +231,10 @@ class FirebaseTestLabCommand extends PluginCommand { 'build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk', '--timeout', '5m', - '--results-bucket=${argResults['results-bucket']}', + '--results-bucket=${getStringArg('results-bucket')}', '--results-dir=$resultsDir', ]; - for (final String device in argResults['device'] as List) { + for (final String device in getStringListArg('device')) { args.addAll(['--device', device]); } exitCode = await processRunner.runAndStream('gcloud', args, diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index 9c29f0f8c684..b3a8bd04edb5 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; @@ -13,8 +15,8 @@ import 'package:quiver/iterables.dart'; 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'; +final Uri _googleFormatterUrl = Uri.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 { @@ -47,7 +49,7 @@ class FormatCommand extends PluginCommand { await _formatJava(googleFormatterPath); await _formatCppAndObjectiveC(); - if (argResults['fail-on-change'] == true) { + if (getBoolArg('fail-on-change')) { final bool modified = await _didModifyAnything(); if (modified) { throw ToolExit(1); @@ -105,7 +107,7 @@ class FormatCommand extends PluginCommand { // 'ProcessException: Argument list too long'. final Iterable> batches = partition(allFiles, 100); for (final List batch in batches) { - await processRunner.runAndStream(argResults['clang-format'] as String, + await processRunner.runAndStream(getStringArg('clang-format'), ['-i', '--style=Google', ...batch], 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 5df97627cecd..dff83d37315f 100644 --- a/script/tool/lib/src/java_test_command.dart +++ b/script/tool/lib/src/java_test_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; diff --git a/script/tool/lib/src/license_check_command.dart b/script/tool/lib/src/license_check_command.dart index a6528640b828..cc4eb96fac39 100644 --- a/script/tool/lib/src/license_check_command.dart +++ b/script/tool/lib/src/license_check_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart index ebcefd6c2343..0bf4c69b24f4 100644 --- a/script/tool/lib/src/lint_podspecs_command.dart +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -89,7 +91,7 @@ class LintPodspecsCommand extends PluginCommand { final List podspecs = await getFiles().where((File entity) { final String filePath = entity.path; return p.extension(filePath) == '.podspec' && - !(argResults['skip'] as List) + !getStringListArg('skip') .contains(p.basenameWithoutExtension(filePath)); }).toList(); @@ -122,7 +124,7 @@ class LintPodspecsCommand extends PluginCommand { Future _runPodLint(String podspecPath, {bool libraryLint}) async { - final bool allowWarnings = (argResults['ignore-warnings'] as List) + final bool allowWarnings = (getStringListArg('ignore-warnings')) .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 49302a91ad27..cac6cfcf352e 100644 --- a/script/tool/lib/src/list_command.dart +++ b/script/tool/lib/src/list_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; @@ -36,7 +38,7 @@ class ListCommand extends PluginCommand { @override Future run() async { - switch (argResults[_type] as String) { + switch (getStringArg(_type)) { case _plugin: await for (final Directory package in getPlugins()) { print(package.path); diff --git a/script/tool/lib/src/main.dart b/script/tool/lib/src/main.dart index 6fba3b34b955..4b0e85704b24 100644 --- a/script/tool/lib/src/main.dart +++ b/script/tool/lib/src/main.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:io' as io; import 'package:args/command_runner.dart'; diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index 84503f4540c6..3f90465d4f7d 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; @@ -78,7 +80,7 @@ class PublishCheckCommand extends PluginCommand { Future run() async { final ZoneSpecification logSwitchSpecification = ZoneSpecification( print: (Zone self, ZoneDelegate parent, Zone zone, String message) { - final bool logMachineMessage = argResults[_machineFlag] as bool; + final bool logMachineMessage = getBoolArg(_machineFlag); if (logMachineMessage && message != _prettyJson(_machineOutput)) { _humanMessages.add(message); } else { @@ -123,7 +125,7 @@ class PublishCheckCommand extends PluginCommand { isError: false); } - if (argResults[_machineFlag] as bool) { + if (getBoolArg(_machineFlag)) { _setStatus(status); _machineOutput[_humanMessageKey] = _humanMessages; print(_prettyJson(_machineOutput)); @@ -184,7 +186,7 @@ class PublishCheckCommand extends PluginCommand { return true; } - if (!(argResults[_allowPrereleaseFlag] as bool)) { + if (!getBoolArg(_allowPrereleaseFlag)) { return false; } @@ -270,7 +272,7 @@ HTTP response: ${pubVersionFinderResponse.httpResponse.body} void _printImportantStatusMessage(String message, {@required bool isError}) { final String statusMessage = '${isError ? 'ERROR' : 'SUCCESS'}: $message'; - if (argResults[_machineFlag] as bool) { + if (getBoolArg(_machineFlag)) { print(statusMessage); } else { final Colorize colorizedMessage = Colorize(statusMessage); diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index 1c8a2dc57525..cb72c1897215 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; @@ -122,9 +124,9 @@ class PublishPluginCommand extends PluginCommand { @override Future run() async { - final String package = argResults[_packageOption] as String; - final bool publishAllChanged = argResults[_allChangedFlag] as bool; - if (package == null && !publishAllChanged) { + final String package = getStringArg(_packageOption); + final bool publishAllChanged = getBoolArg(_allChangedFlag); + if (package.isEmpty && !publishAllChanged) { _print( 'Must specify a package to publish. See `plugin_tools help publish-plugin`.'); throw ToolExit(1); @@ -138,14 +140,14 @@ class PublishPluginCommand extends PluginCommand { final GitDir baseGitDir = await GitDir.fromExisting(packagesDir.path, allowSubdirectory: true); - final bool shouldPushTag = argResults[_pushTagsOption] == true; - final String remote = argResults[_remoteOption] as String; + final bool shouldPushTag = getBoolArg(_pushTagsOption); + final String remote = getStringArg(_remoteOption); String remoteUrl; if (shouldPushTag) { remoteUrl = await _verifyRemote(remote); } _print('Local repo is ready!'); - if (argResults[_dryRunFlag] as bool) { + if (getBoolArg(_dryRunFlag)) { _print('=============== DRY RUN ==============='); } @@ -244,7 +246,7 @@ class PublishPluginCommand extends PluginCommand { if (!await _publishPlugin(packageDir: packageDir)) { return false; } - if (argResults[_tagReleaseOption] as bool) { + if (getBoolArg(_tagReleaseOption)) { if (!await _tagRelease( packageDir: packageDir, remote: remote, @@ -333,7 +335,7 @@ Safe to ignore if the package is deleted in this commit. }) async { final String tag = _getTag(packageDir); _print('Tagging release $tag...'); - if (!(argResults[_dryRunFlag] as bool)) { + if (!getBoolArg(_dryRunFlag)) { final io.ProcessResult result = await processRunner.run( 'git', ['tag', tag], @@ -416,15 +418,14 @@ Safe to ignore if the package is deleted in this commit. } Future _publish(Directory packageDir) async { - final List publishFlags = - argResults[_pubFlagsOption] as List; + final List publishFlags = getStringListArg(_pubFlagsOption); _print( 'Running `pub publish ${publishFlags.join(' ')}` in ${packageDir.absolute.path}...\n'); - if (argResults[_dryRunFlag] as bool) { + if (getBoolArg(_dryRunFlag)) { return true; } - if (argResults[_skipConfirmationFlag] as bool) { + if (getBoolArg(_skipConfirmationFlag)) { publishFlags.add('--force'); } if (publishFlags.contains('--force')) { @@ -474,7 +475,7 @@ Safe to ignore if the package is deleted in this commit. @required String remoteUrl, }) async { assert(remote != null && tag != null && remoteUrl != null); - if (!(argResults[_skipConfirmationFlag] as bool)) { + if (!getBoolArg(_skipConfirmationFlag)) { _print('Ready to push $tag to $remoteUrl (y/n)?'); final String input = _stdin.readLineSync(); if (input.toLowerCase() != 'y') { @@ -482,7 +483,7 @@ Safe to ignore if the package is deleted in this commit. return false; } } - if (!(argResults[_dryRunFlag] as bool)) { + if (!getBoolArg(_dryRunFlag)) { final io.ProcessResult result = await processRunner.run( 'git', ['push', remote, tag], diff --git a/script/tool/lib/src/test_command.dart b/script/tool/lib/src/test_command.dart index bb4f9c12a77f..c4aeab7022b8 100644 --- a/script/tool/lib/src/test_command.dart +++ b/script/tool/lib/src/test_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; @@ -44,7 +46,7 @@ class TestCommand extends PluginCommand { print('RUNNING $packageName tests...'); - final String enableExperiment = argResults[kEnableExperiment] as String; + final String enableExperiment = getStringArg(kEnableExperiment); // `flutter test` automatically gets packages. `pub run test` does not. :( int exitCode = 0; diff --git a/script/tool/lib/src/version_check_command.dart b/script/tool/lib/src/version_check_command.dart index 475caf5d285d..a802c4d425ee 100644 --- a/script/tool/lib/src/version_check_command.dart +++ b/script/tool/lib/src/version_check_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; @@ -135,7 +137,7 @@ class VersionCheckCommand extends PluginCommand { '"publish_to: none".'); } Version sourceVersion; - if (argResults[_againstPubFlag] as bool) { + if (getBoolArg(_againstPubFlag)) { final String packageName = pubspecFile.parent.basename; final PubVersionFinderResponse pubVersionFinderResponse = await _pubVersionFinder.getPackageVersion(package: packageName); @@ -161,7 +163,7 @@ ${indentation}HTTP response: ${pubVersionFinderResponse.httpResponse.body} } if (sourceVersion == null) { String safeToIgnoreMessage; - if (argResults[_againstPubFlag] as bool) { + if (getBoolArg(_againstPubFlag)) { safeToIgnoreMessage = '${indentation}Unable to find package on pub server.'; } else { @@ -181,8 +183,7 @@ ${indentation}HTTP response: ${pubVersionFinderResponse.httpResponse.body} getAllowedNextVersions(sourceVersion, headVersion); if (!allowedNextVersions.containsKey(headVersion)) { - final String source = - (argResults[_againstPubFlag] as bool) ? 'pub' : 'master'; + final String source = (getBoolArg(_againstPubFlag)) ? 'pub' : 'master'; final String error = '${indentation}Incorrectly updated version.\n' '${indentation}HEAD: $headVersion, $source: $sourceVersion.\n' '${indentation}Allowed versions: $allowedNextVersions'; diff --git a/script/tool/lib/src/xctest_command.dart b/script/tool/lib/src/xctest_command.dart index 64f85577dbce..335e0054fc05 100644 --- a/script/tool/lib/src/xctest_command.dart +++ b/script/tool/lib/src/xctest_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; @@ -48,8 +50,8 @@ class XCTestCommand extends PluginCommand { @override Future run() async { - String destination = argResults[_kiOSDestination] as String; - if (destination == null) { + String destination = getStringArg(_kiOSDestination); + if (destination.isEmpty) { final String simulatorId = await _findAvailableIphoneSimulator(); if (simulatorId == null) { print(_kFoundNoSimulatorsMessage); @@ -58,7 +60,7 @@ class XCTestCommand extends PluginCommand { destination = 'id=$simulatorId'; } - final List skipped = argResults[_kSkip] as List; + final List skipped = getStringListArg(_kSkip); final List failingPackages = []; await for (final Directory plugin in getPlugins()) { diff --git a/script/tool/pubspec.yaml b/script/tool/pubspec.yaml index 58dfc9fbd8b6..725c8395b819 100644 --- a/script/tool/pubspec.yaml +++ b/script/tool/pubspec.yaml @@ -4,28 +4,29 @@ repository: https://github.com/flutter/plugins/tree/master/script/tool version: 0.1.1 dependencies: - args: "^1.4.3" - path: "^1.6.1" - http: "^0.12.1" - async: "^2.0.7" - yaml: "^2.1.15" - quiver: "^2.0.2" - pub_semver: ^1.4.2 - colorize: ^2.0.0 - git: ^1.0.0 - platform: ^2.2.0 - pubspec_parse: "^0.1.4" - test: ^1.6.4 - meta: ^1.1.7 - file: ^5.0.10 - uuid: ^2.0.4 - http_multi_server: ^2.2.0 - collection: ^1.14.13 + args: ^2.1.0 + async: ^2.6.1 + collection: ^1.15.0 + colorize: ^3.0.0 + file: ^6.1.0 + git: ^2.0.0 + http: ^0.13.3 + http_multi_server: ^3.0.1 + meta: ^1.3.0 + path: ^1.8.0 + platform: ^3.0.0 + pub_semver: ^2.0.0 + pubspec_parse: ^1.0.0 + quiver: ^3.0.1 + test: ^1.17.3 + uuid: ^3.0.4 + yaml: ^3.1.0 dev_dependencies: - matcher: ^0.12.6 - mockito: ^4.1.1 - pedantic: ^1.8.0 + build_runner: ^2.0.3 + matcher: ^0.12.10 + mockito: ^5.0.7 + pedantic: ^1.11.0 environment: - sdk: ">=2.3.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart index 11acb59a474d..1e656b4f75e4 100644 --- a/script/tool/test/analyze_command_test.dart +++ b/script/tool/test/analyze_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/analyze_command.dart'; diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart index 40da27d44923..7b488879f3be 100644 --- a/script/tool/test/build_examples_command_test.dart +++ b/script/tool/test/build_examples_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/build_examples_command.dart'; diff --git a/script/tool/test/common_test.dart b/script/tool/test/common_test.dart index d6ac449e7fd3..477e186aa24b 100644 --- a/script/tool/test/common_test.dart +++ b/script/tool/test/common_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -12,21 +13,24 @@ import 'package:flutter_plugin_tools/src/common.dart'; import 'package:git/git.dart'; import 'package:http/http.dart' as http; import 'package:http/testing.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; +import 'common_test.mocks.dart'; import 'util.dart'; +@GenerateMocks([GitDir]) void main() { - RecordingProcessRunner processRunner; - CommandRunner runner; - FileSystem fileSystem; - Directory packagesDir; - Directory thirdPartyPackagesDir; - List plugins; - List> gitDirCommands; - String gitDiffResponse; + late RecordingProcessRunner processRunner; + late CommandRunner runner; + late FileSystem fileSystem; + late Directory packagesDir; + late Directory thirdPartyPackagesDir; + late List plugins; + late List?> gitDirCommands; + late String gitDiffResponse; setUp(() { fileSystem = MemoryFileSystem(); @@ -35,14 +39,15 @@ void main() { .childDirectory('third_party') .childDirectory('packages'); - gitDirCommands = >[]; + gitDirCommands = ?>[]; gitDiffResponse = ''; final MockGitDir gitDir = MockGitDir(); - when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { - gitDirCommands.add(invocation.positionalArguments[0] as List); + when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError'))) + .thenAnswer((Invocation invocation) { + gitDirCommands.add(invocation.positionalArguments[0] as List?); final MockProcessResult mockProcessResult = MockProcessResult(); if (invocation.positionalArguments[0][0] == 'diff') { - when(mockProcessResult.stdout as String) + when(mockProcessResult.stdout as String?) .thenReturn(gitDiffResponse); } return Future.value(mockProcessResult); @@ -255,23 +260,24 @@ packages/plugin3/plugin3.dart }); group('$GitVersionFinder', () { - List> gitDirCommands; - String gitDiffResponse; - String mergeBaseResponse; - MockGitDir gitDir; + late List?> gitDirCommands; + late String gitDiffResponse; + String? mergeBaseResponse; + late MockGitDir gitDir; setUp(() { - gitDirCommands = >[]; + gitDirCommands = ?>[]; gitDiffResponse = ''; gitDir = MockGitDir(); - when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { - gitDirCommands.add(invocation.positionalArguments[0] as List); + when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError'))) + .thenAnswer((Invocation invocation) { + gitDirCommands.add(invocation.positionalArguments[0] as List?); final MockProcessResult mockProcessResult = MockProcessResult(); if (invocation.positionalArguments[0][0] == 'diff') { - when(mockProcessResult.stdout as String) + when(mockProcessResult.stdout as String?) .thenReturn(gitDiffResponse); } else if (invocation.positionalArguments[0][0] == 'merge-base') { - when(mockProcessResult.stdout as String) + when(mockProcessResult.stdout as String?) .thenReturn(mergeBaseResponse); } return Future.value(mockProcessResult); @@ -320,10 +326,11 @@ file2/file2.cc file1/pubspec.yaml file2/file2.cc '''; + final GitVersionFinder finder = GitVersionFinder(gitDir, null); await finder.getChangedFiles(); verify(gitDir.runCommand( - ['diff', '--name-only', mergeBaseResponse, 'HEAD'])); + ['diff', '--name-only', mergeBaseResponse!, 'HEAD'])); }); test('use correct base sha if specified', () async { @@ -350,8 +357,8 @@ file2/file2.cc expect(response.versions, isNull); expect(response.result, PubVersionFinderResult.noPackageFound); - expect(response.httpResponse.statusCode, 404); - expect(response.httpResponse.body, ''); + expect(response.httpResponse!.statusCode, 404); + expect(response.httpResponse!.body, ''); }); test('HTTP error when getting versions from pub', () async { @@ -364,8 +371,8 @@ file2/file2.cc expect(response.versions, isNull); expect(response.result, PubVersionFinderResult.fail); - expect(response.httpResponse.statusCode, 400); - expect(response.httpResponse.body, ''); + expect(response.httpResponse!.statusCode, 400); + expect(response.httpResponse!.body, ''); }); test('Get a correct list of versions when http response is OK.', () async { @@ -408,8 +415,8 @@ file2/file2.cc Version.parse('0.0.1'), ]); expect(response.result, PubVersionFinderResult.success); - expect(response.httpResponse.statusCode, 200); - expect(response.httpResponse.body, json.encode(httpResponse)); + expect(response.httpResponse!.statusCode, 200); + expect(response.httpResponse!.body, json.encode(httpResponse)); }); }); } @@ -420,7 +427,7 @@ class SamplePluginCommand extends PluginCommand { Directory packagesDir, FileSystem fileSystem, { ProcessRunner processRunner = const ProcessRunner(), - GitDir gitDir, + GitDir? gitDir, }) : super(packagesDir, fileSystem, processRunner: processRunner, gitDir: gitDir); @@ -440,6 +447,4 @@ class SamplePluginCommand extends PluginCommand { } } -class MockGitDir extends Mock implements GitDir {} - class MockProcessResult extends Mock implements ProcessResult {} diff --git a/script/tool/test/common_test.mocks.dart b/script/tool/test/common_test.mocks.dart new file mode 100644 index 000000000000..b7f7807b3b05 --- /dev/null +++ b/script/tool/test/common_test.mocks.dart @@ -0,0 +1,143 @@ +// Mocks generated by Mockito 5.0.7 from annotations +// in flutter_plugin_tools/test/common_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i6; +import 'dart:io' as _i4; + +import 'package:git/src/branch_reference.dart' as _i3; +import 'package:git/src/commit.dart' as _i2; +import 'package:git/src/commit_reference.dart' as _i8; +import 'package:git/src/git_dir.dart' as _i5; +import 'package:git/src/tag.dart' as _i7; +import 'package:git/src/tree_entry.dart' as _i9; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: comment_references +// ignore_for_file: unnecessary_parenthesis + +// ignore_for_file: prefer_const_constructors + +// ignore_for_file: avoid_redundant_argument_values + +class _FakeCommit extends _i1.Fake implements _i2.Commit {} + +class _FakeBranchReference extends _i1.Fake implements _i3.BranchReference {} + +class _FakeProcessResult extends _i1.Fake implements _i4.ProcessResult {} + +/// A class which mocks [GitDir]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockGitDir extends _i1.Mock implements _i5.GitDir { + MockGitDir() { + _i1.throwOnMissingStub(this); + } + + @override + String get path => + (super.noSuchMethod(Invocation.getter(#path), returnValue: '') as String); + @override + _i6.Future commitCount([String? branchName = r'HEAD']) => + (super.noSuchMethod(Invocation.method(#commitCount, [branchName]), + returnValue: Future.value(0)) as _i6.Future); + @override + _i6.Future<_i2.Commit> commitFromRevision(String? revision) => + (super.noSuchMethod(Invocation.method(#commitFromRevision, [revision]), + returnValue: Future<_i2.Commit>.value(_FakeCommit())) + as _i6.Future<_i2.Commit>); + @override + _i6.Future> commits([String? branchName = r'HEAD']) => + (super.noSuchMethod(Invocation.method(#commits, [branchName]), + returnValue: + Future>.value({})) + as _i6.Future>); + @override + _i6.Future<_i3.BranchReference?> branchReference(String? branchName) => + (super.noSuchMethod(Invocation.method(#branchReference, [branchName]), + returnValue: + Future<_i3.BranchReference?>.value(_FakeBranchReference())) + as _i6.Future<_i3.BranchReference?>); + @override + _i6.Future> branches() => (super.noSuchMethod( + Invocation.method(#branches, []), + returnValue: + Future>.value(<_i3.BranchReference>[])) + as _i6.Future>); + @override + _i6.Stream<_i7.Tag> tags() => + (super.noSuchMethod(Invocation.method(#tags, []), + returnValue: Stream<_i7.Tag>.empty()) as _i6.Stream<_i7.Tag>); + @override + _i6.Future> showRef( + {bool? heads = false, bool? tags = false}) => + (super.noSuchMethod( + Invocation.method(#showRef, [], {#heads: heads, #tags: tags}), + returnValue: Future>.value( + <_i8.CommitReference>[])) + as _i6.Future>); + @override + _i6.Future<_i3.BranchReference> currentBranch() => + (super.noSuchMethod(Invocation.method(#currentBranch, []), + returnValue: + Future<_i3.BranchReference>.value(_FakeBranchReference())) + as _i6.Future<_i3.BranchReference>); + @override + _i6.Future> lsTree(String? treeish, + {bool? subTreesOnly = false, String? path}) => + (super.noSuchMethod( + Invocation.method(#lsTree, [treeish], + {#subTreesOnly: subTreesOnly, #path: path}), + returnValue: Future>.value(<_i9.TreeEntry>[])) + as _i6.Future>); + @override + _i6.Future createOrUpdateBranch( + String? branchName, String? treeSha, String? commitMessage) => + (super.noSuchMethod( + Invocation.method( + #createOrUpdateBranch, [branchName, treeSha, commitMessage]), + returnValue: Future.value('')) as _i6.Future); + @override + _i6.Future commitTree(String? treeSha, String? commitMessage, + {List? parentCommitShas}) => + (super.noSuchMethod( + Invocation.method(#commitTree, [treeSha, commitMessage], + {#parentCommitShas: parentCommitShas}), + returnValue: Future.value('')) as _i6.Future); + @override + _i6.Future> writeObjects(List? paths) => + (super.noSuchMethod(Invocation.method(#writeObjects, [paths]), + returnValue: + Future>.value({})) + as _i6.Future>); + @override + _i6.Future<_i4.ProcessResult> runCommand(Iterable? args, + {bool? throwOnError = true}) => + (super.noSuchMethod( + Invocation.method(#runCommand, [args], {#throwOnError: throwOnError}), + returnValue: + Future<_i4.ProcessResult>.value(_FakeProcessResult())) as _i6 + .Future<_i4.ProcessResult>); + @override + _i6.Future isWorkingTreeClean() => + (super.noSuchMethod(Invocation.method(#isWorkingTreeClean, []), + returnValue: Future.value(false)) as _i6.Future); + @override + _i6.Future<_i2.Commit?> updateBranch( + String? branchName, + _i6.Future Function(_i4.Directory)? populater, + String? commitMessage) => + (super.noSuchMethod( + Invocation.method( + #updateBranch, [branchName, populater, commitMessage]), + returnValue: Future<_i2.Commit?>.value(_FakeCommit())) + as _i6.Future<_i2.Commit?>); + @override + _i6.Future<_i2.Commit?> updateBranchWithDirectoryContents(String? branchName, + String? sourceDirectoryPath, String? commitMessage) => + (super.noSuchMethod( + Invocation.method(#updateBranchWithDirectoryContents, + [branchName, sourceDirectoryPath, commitMessage]), + returnValue: Future<_i2.Commit?>.value(_FakeCommit())) + as _i6.Future<_i2.Commit?>); +} 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 fedc04684631..caf4218dc161 100644 --- a/script/tool/test/create_all_plugins_app_command_test.dart +++ b/script/tool/test/create_all_plugins_app_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:file/local.dart'; diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index 5ba8d8af25ff..7905bb279f4a 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/common.dart'; diff --git a/script/tool/test/firebase_test_lab_test.dart b/script/tool/test/firebase_test_lab_test.dart index d6068691d549..b4e5b5b8c723 100644 --- a/script/tool/test/firebase_test_lab_test.dart +++ b/script/tool/test/firebase_test_lab_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:io'; import 'package:args/command_runner.dart'; diff --git a/script/tool/test/java_test_command_test.dart b/script/tool/test/java_test_command_test.dart index ba016915223d..cfa8d448f374 100644 --- a/script/tool/test/java_test_command_test.dart +++ b/script/tool/test/java_test_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/java_test_command.dart'; diff --git a/script/tool/test/license_check_command_test.dart b/script/tool/test/license_check_command_test.dart index 23de2581b9be..a0c74fc6acd6 100644 --- a/script/tool/test/license_check_command_test.dart +++ b/script/tool/test/license_check_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:file/memory.dart'; diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart index a1fa1f7c7743..13bb1cc8d32f 100644 --- a/script/tool/test/lint_podspecs_command_test.dart +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/lint_podspecs_command.dart'; diff --git a/script/tool/test/list_command_test.dart b/script/tool/test/list_command_test.dart index e7fcfe7a7c4b..a767671be5c2 100644 --- a/script/tool/test/list_command_test.dart +++ b/script/tool/test/list_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/list_command.dart'; diff --git a/script/tool/test/mocks.dart b/script/tool/test/mocks.dart index ad1f357fb472..a83ca754380f 100644 --- a/script/tool/test/mocks.dart +++ b/script/tool/test/mocks.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:io' as io; diff --git a/script/tool/test/publish_check_command_test.dart b/script/tool/test/publish_check_command_test.dart index eca7caf53403..8c34b3313a07 100644 --- a/script/tool/test/publish_check_command_test.dart +++ b/script/tool/test/publish_check_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:collection'; import 'dart:convert'; import 'dart:io' as io; diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index b622e05861fa..357e72efa004 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; diff --git a/script/tool/test/test_command_test.dart b/script/tool/test/test_command_test.dart index 1dd0c158293a..550249169b9b 100644 --- a/script/tool/test/test_command_test.dart +++ b/script/tool/test/test_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/test_command.dart'; diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index d708dc71bef7..7d4278f68cc9 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -21,13 +21,13 @@ FileSystem mockFileSystem = MemoryFileSystem( style: const LocalPlatform().isWindows ? FileSystemStyle.windows : FileSystemStyle.posix); -Directory mockPackagesDir; +late Directory mockPackagesDir; /// Creates a mock packages directory in the mock file system. /// /// If [parentDir] is set the mock packages dir will be creates as a child of /// it. If not [mockFileSystem] will be used instead. -void initializeFakePackages({Directory parentDir}) { +void initializeFakePackages({Directory? parentDir}) { mockPackagesDir = (parentDir ?? mockFileSystem.currentDirectory).childDirectory('packages'); mockPackagesDir.createSync(); @@ -51,7 +51,7 @@ Directory createFakePlugin( bool includeVersion = false, String version = '0.0.1', String parentDirectoryName = '', - Directory packagesDirectory, + Directory? packagesDirectory, }) { assert(!(withSingleExample && withExamples.isNotEmpty), 'cannot pass withSingleExample and withExamples simultaneously'); @@ -211,7 +211,8 @@ typedef _ErrorHandler = void Function(Error error); /// what was printed. /// A custom [errorHandler] can be used to handle the runner error as desired without throwing. Future> runCapturingPrint( - CommandRunner runner, List args, {_ErrorHandler errorHandler}) async { + CommandRunner runner, List args, + {_ErrorHandler? errorHandler}) async { final List prints = []; final ZoneSpecification spec = ZoneSpecification( print: (_, __, ___, String message) { @@ -220,8 +221,8 @@ Future> runCapturingPrint( ); try { await Zone.current - .fork(specification: spec) - .run>(() => runner.run(args)); + .fork(specification: spec) + .run>(() => runner.run(args)); } on Error catch (e) { if (errorHandler == null) { rethrow; @@ -234,25 +235,25 @@ Future> runCapturingPrint( /// A mock [ProcessRunner] which records process calls. class RecordingProcessRunner extends ProcessRunner { - io.Process processToReturn; + io.Process? processToReturn; final List recordedCalls = []; /// Populate for [io.ProcessResult] to use a String [stdout] instead of a [List] of [int]. - String resultStdout; + String? resultStdout; /// Populate for [io.ProcessResult] to use a String [stderr] instead of a [List] of [int]. - String resultStderr; + String? resultStderr; @override Future runAndStream( String executable, List args, { - Directory workingDir, + Directory? workingDir, bool exitOnError = false, }) async { recordedCalls.add(ProcessCall(executable, args, workingDir?.path)); return Future.value( - processToReturn == null ? 0 : await processToReturn.exitCode); + processToReturn == null ? 0 : await processToReturn!.exitCode); } /// Returns [io.ProcessResult] created from [processToReturn], [resultStdout], and [resultStderr]. @@ -260,28 +261,26 @@ class RecordingProcessRunner extends ProcessRunner { Future run( String executable, List args, { - Directory workingDir, + Directory? workingDir, bool exitOnError = false, bool logOnError = false, Encoding stdoutEncoding = io.systemEncoding, Encoding stderrEncoding = io.systemEncoding, }) async { recordedCalls.add(ProcessCall(executable, args, workingDir?.path)); - io.ProcessResult result; + io.ProcessResult? result; - if (processToReturn != null) { - result = io.ProcessResult( - processToReturn.pid, - await processToReturn.exitCode, - resultStdout ?? processToReturn.stdout, - resultStderr ?? processToReturn.stderr); + final io.Process? process = processToReturn; + if (process != null) { + result = io.ProcessResult(process.pid, await process.exitCode, + resultStdout ?? process.stdout, resultStderr ?? process.stderr); } return Future.value(result); } @override Future start(String executable, List args, - {Directory workingDirectory}) async { + {Directory? workingDirectory}) async { recordedCalls.add(ProcessCall(executable, args, workingDirectory?.path)); return Future.value(processToReturn); } @@ -299,7 +298,7 @@ class ProcessCall { final List args; /// The working directory this process was called from. - final String workingDir; + final String? workingDir; @override bool operator ==(dynamic other) { @@ -311,10 +310,7 @@ class ProcessCall { @override int get hashCode => - executable?.hashCode ?? - 0 ^ args?.hashCode ?? - 0 ^ workingDir?.hashCode ?? - 0; + (executable.hashCode) ^ (args.hashCode) ^ (workingDir?.hashCode ?? 0); @override String toString() { diff --git a/script/tool/test/version_check_test.dart b/script/tool/test/version_check_test.dart index d67103f716a1..cef2ab1cfad3 100644 --- a/script/tool/test/version_check_test.dart +++ b/script/tool/test/version_check_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; @@ -65,7 +67,8 @@ void main() { gitDiffResponse = ''; gitShowResponses = {}; gitDir = MockGitDir(); - when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { + when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError'))) + .thenAnswer((Invocation invocation) { gitDirCommands.add(invocation.positionalArguments[0] as List); final MockProcessResult mockProcessResult = MockProcessResult(); if (invocation.positionalArguments[0][0] == 'diff') { diff --git a/script/tool/test/xctest_command_test.dart b/script/tool/test/xctest_command_test.dart index 1707dc8cfb8d..53e82ac623e8 100644 --- a/script/tool/test/xctest_command_test.dart +++ b/script/tool/test/xctest_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:convert'; import 'package:args/command_runner.dart';