diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart index 2c4fc1b8376e..e56b95d88eb0 100644 --- a/script/tool/lib/src/analyze_command.dart +++ b/script/tool/lib/src/analyze_command.dart @@ -5,7 +5,7 @@ import 'dart:async'; import 'package:file/file.dart'; -import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'common/core.dart'; import 'common/package_looping_command.dart'; @@ -19,7 +19,8 @@ class AnalyzeCommand extends PackageLoopingCommand { AnalyzeCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), - }) : super(packagesDir, processRunner: processRunner) { + Platform platform = const LocalPlatform(), + }) : super(packagesDir, processRunner: processRunner, platform: platform) { argParser.addMultiOption(_customAnalysisFlag, help: 'Directories (comma separated) that are allowed to have their own analysis options.', @@ -57,9 +58,8 @@ class AnalyzeCommand extends PackageLoopingCommand { final bool allowed = (getStringListArg(_customAnalysisFlag)).any( (String directory) => - directory != null && directory.isNotEmpty && - p.isWithin( + path.isWithin( packagesDir.childDirectory(directory).path, file.path)); if (allowed) { continue; @@ -90,7 +90,7 @@ class AnalyzeCommand extends PackageLoopingCommand { }); for (final Directory package in packageDirectories) { final int exitCode = await processRunner.runAndStream( - 'flutter', ['packages', 'get'], + flutterCommand, ['packages', 'get'], workingDir: package); if (exitCode != 0) { return false; @@ -109,7 +109,8 @@ class AnalyzeCommand extends PackageLoopingCommand { // Use the Dart SDK override if one was passed in. final String? dartSdk = argResults![_analysisSdk] as String?; - _dartBinaryPath = dartSdk == null ? 'dart' : p.join(dartSdk, 'bin', 'dart'); + _dartBinaryPath = + dartSdk == null ? 'dart' : path.join(dartSdk, 'bin', 'dart'); } @override diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart index 32905c83db91..0cac09980c94 100644 --- a/script/tool/lib/src/build_examples_command.dart +++ b/script/tool/lib/src/build_examples_command.dart @@ -5,7 +5,7 @@ import 'dart:async'; import 'package:file/file.dart'; -import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'common/core.dart'; import 'common/package_looping_command.dart'; @@ -23,7 +23,8 @@ class BuildExamplesCommand extends PackageLoopingCommand { BuildExamplesCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), - }) : super(packagesDir, processRunner: processRunner) { + Platform platform = const LocalPlatform(), + }) : super(packagesDir, processRunner: processRunner, platform: platform) { argParser.addFlag(kPlatformLinux); argParser.addFlag(kPlatformMacos); argParser.addFlag(kPlatformWeb); @@ -127,7 +128,7 @@ class BuildExamplesCommand extends PackageLoopingCommand { for (final Directory example in getExamplesForPlugin(package)) { final String packageName = - p.relative(example.path, from: packagesDir.path); + getRelativePosixPath(example, from: packagesDir); for (final _PlatformDetails platform in buildPlatforms) { String buildPlatform = platform.label; diff --git a/script/tool/lib/src/common/package_looping_command.dart b/script/tool/lib/src/common/package_looping_command.dart index de1e3b861f59..9f4039ec7074 100644 --- a/script/tool/lib/src/common/package_looping_command.dart +++ b/script/tool/lib/src/common/package_looping_command.dart @@ -8,6 +8,7 @@ import 'package:colorize/colorize.dart'; import 'package:file/file.dart'; import 'package:git/git.dart'; import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'core.dart'; import 'plugin_command.dart'; @@ -63,8 +64,10 @@ abstract class PackageLoopingCommand extends PluginCommand { PackageLoopingCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), + Platform platform = const LocalPlatform(), GitDir? gitDir, - }) : super(packagesDir, processRunner: processRunner, gitDir: gitDir); + }) : super(packagesDir, + processRunner: processRunner, platform: platform, gitDir: gitDir); /// Packages that had at least one [logWarning] call. final Set _packagesWithWarnings = {}; @@ -158,8 +161,8 @@ abstract class PackageLoopingCommand extends PluginCommand { /// an exact format (e.g., published name, or basename) is required, that /// should be used instead. String getPackageDescription(Directory package) { - String packageName = p.relative(package.path, from: packagesDir.path); - final List components = p.split(packageName); + String packageName = getRelativePosixPath(package, from: packagesDir); + final List components = p.posix.split(packageName); // For the common federated plugin pattern of `foo/foo_subpackage`, drop // the first part since it's not useful. if (components.length == 2 && @@ -169,6 +172,16 @@ abstract class PackageLoopingCommand extends PluginCommand { return packageName; } + /// Returns the relative path from [from] to [entity] in Posix style. + /// + /// This should be used when, for example, printing package-relative paths in + /// status or error messages. + String getRelativePosixPath( + FileSystemEntity entity, { + required Directory from, + }) => + p.posix.joinAll(path.split(path.relative(entity.path, from: from.path))); + /// The suggested indentation for printed output. String get indentation => hasLongOutput ? '' : ' '; diff --git a/script/tool/lib/src/common/plugin_command.dart b/script/tool/lib/src/common/plugin_command.dart index 74f607dde7cf..ecdcb0565d35 100644 --- a/script/tool/lib/src/common/plugin_command.dart +++ b/script/tool/lib/src/common/plugin_command.dart @@ -21,6 +21,7 @@ abstract class PluginCommand extends Command { PluginCommand( this.packagesDir, { this.processRunner = const ProcessRunner(), + this.platform = const LocalPlatform(), GitDir? gitDir, }) : _gitDir = gitDir { argParser.addMultiOption( @@ -79,6 +80,11 @@ abstract class PluginCommand extends Command { /// This can be overridden for testing. final ProcessRunner processRunner; + /// The current platform. + /// + /// This can be overridden for testing. + final Platform platform; + /// The git directory to use. If unset, [gitDir] populates it from the /// packages directory's enclosing repository. /// @@ -88,9 +94,11 @@ abstract class PluginCommand extends Command { int? _shardIndex; int? _shardCount; + /// A context that matches the default for [platform]. + p.Context get path => platform.isWindows ? p.windows : p.posix; + /// The command to use when running `flutter`. - String get flutterCommand => - const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; + String get flutterCommand => platform.isWindows ? 'flutter.bat' : 'flutter'; /// The shard of the overall command execution that this instance should run. int get shardIndex { @@ -240,9 +248,9 @@ abstract class PluginCommand extends Command { // plugins under 'my_plugin'. Also match if the exact plugin is // passed. final String relativePath = - p.relative(subdir.path, from: dir.path); - final String packageName = p.basename(subdir.path); - final String basenamePath = p.basename(entity.path); + path.relative(subdir.path, from: dir.path); + final String packageName = path.basename(subdir.path); + final String basenamePath = path.basename(entity.path); if (!excludedPlugins.contains(basenamePath) && !excludedPlugins.contains(packageName) && !excludedPlugins.contains(relativePath) && 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 fab41bcf4ec4..ed7014456086 100644 --- a/script/tool/lib/src/create_all_plugins_app_command.dart +++ b/script/tool/lib/src/create_all_plugins_app_command.dart @@ -5,6 +5,7 @@ import 'dart:io' as io; import 'package:file/file.dart'; +import 'package:path/path.dart' as p; import 'package:pub_semver/pub_semver.dart'; import 'package:pubspec_parse/pubspec_parse.dart'; @@ -51,7 +52,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { Future _createApp() async { final io.ProcessResult result = io.Process.runSync( - 'flutter', + flutterCommand, [ 'create', '--template=app', @@ -156,7 +157,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { {}; await for (final Directory package in getPlugins()) { - final String pluginName = package.path.split('/').last; + final String pluginName = package.basename; final File pubspecFile = package.childFile('pubspec.yaml'); final Pubspec pubspec = Pubspec.parse(pubspecFile.readAsStringSync()); @@ -172,6 +173,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { ### Generated file. Do not edit. Run `pub global run flutter_plugin_tools gen-pubspec` to update. name: ${pubspec.name} description: ${pubspec.description} +publish_to: none version: ${pubspec.version} @@ -197,7 +199,21 @@ dev_dependencies:${_pubspecMapString(pubspec.devDependencies)} buffer.write(' ${entry.key}: \n sdk: ${dep.sdk}'); } else if (entry.value is PathDependency) { final PathDependency dep = entry.value as PathDependency; - buffer.write(' ${entry.key}: \n path: ${dep.path}'); + String depPath = dep.path; + if (path.style == p.Style.windows) { + // Posix-style path separators are preferred in pubspec.yaml (and + // using a consistent format makes unit testing simpler), so convert. + final List components = path.split(depPath); + final String firstComponent = components.first; + // path.split leaves a \ on drive components that isn't necessary, + // and confuses pub, so remove it. + if (firstComponent.endsWith(r':\')) { + components[0] = + firstComponent.substring(0, firstComponent.length - 1); + } + depPath = p.posix.joinAll(components); + } + buffer.write(' ${entry.key}: \n path: $depPath'); } else { throw UnimplementedError( 'Not available for type: ${entry.value.runtimeType}', diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index df74119e4019..7e800ed54866 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -6,7 +6,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:file/file.dart'; -import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'common/core.dart'; import 'common/package_looping_command.dart'; @@ -22,7 +22,8 @@ class DriveExamplesCommand extends PackageLoopingCommand { DriveExamplesCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), - }) : super(packagesDir, processRunner: processRunner) { + Platform platform = const LocalPlatform(), + }) : super(packagesDir, processRunner: processRunner, platform: platform) { argParser.addFlag(kPlatformAndroid, help: 'Runs the Android implementation of the examples'); argParser.addFlag(kPlatformIos, @@ -148,7 +149,7 @@ class DriveExamplesCommand extends PackageLoopingCommand { for (final Directory example in getExamplesForPlugin(package)) { ++examplesFound; final String exampleName = - p.relative(example.path, from: packagesDir.path); + getRelativePosixPath(example, from: packagesDir); final List drivers = await _getDrivers(example); if (drivers.isEmpty) { @@ -172,11 +173,10 @@ class DriveExamplesCommand extends PackageLoopingCommand { if (testTargets.isEmpty) { final String driverRelativePath = - p.relative(driver.path, from: package.path); + getRelativePosixPath(driver, from: package); printError( 'Found $driverRelativePath, but no integration_test/*_test.dart files.'); - errors.add( - 'No test files for ${p.relative(driver.path, from: package.path)}'); + errors.add('No test files for $driverRelativePath'); continue; } @@ -185,7 +185,7 @@ class DriveExamplesCommand extends PackageLoopingCommand { example, driver, testTargets, deviceFlags: deviceFlags); for (final File failingTarget in failingTargets) { - errors.add(p.relative(failingTarget.path, from: package.path)); + errors.add(getRelativePosixPath(failingTarget, from: package)); } } } @@ -296,9 +296,9 @@ class DriveExamplesCommand extends PackageLoopingCommand { if (enableExperiment.isNotEmpty) '--enable-experiment=$enableExperiment', '--driver', - p.relative(driver.path, from: example.path), + getRelativePosixPath(driver, from: example), '--target', - p.relative(target.path, from: example.path), + getRelativePosixPath(target, from: example), ], workingDir: example); if (exitCode != 0) { diff --git a/script/tool/lib/src/firebase_test_lab_command.dart b/script/tool/lib/src/firebase_test_lab_command.dart index 8253ceeda86b..5e4d9f080085 100644 --- a/script/tool/lib/src/firebase_test_lab_command.dart +++ b/script/tool/lib/src/firebase_test_lab_command.dart @@ -6,7 +6,7 @@ import 'dart:async'; import 'dart:io' as io; import 'package:file/file.dart'; -import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'package:uuid/uuid.dart'; import 'common/core.dart'; @@ -21,7 +21,8 @@ class FirebaseTestLabCommand extends PackageLoopingCommand { FirebaseTestLabCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), - }) : super(packagesDir, processRunner: processRunner) { + Platform platform = const LocalPlatform(), + }) : super(packagesDir, processRunner: processRunner, platform: platform) { argParser.addOption( 'project', defaultsTo: 'flutter-infra', @@ -29,8 +30,9 @@ class FirebaseTestLabCommand extends PackageLoopingCommand { ); final String? homeDir = io.Platform.environment['HOME']; argParser.addOption('service-key', - defaultsTo: - homeDir == null ? null : p.join(homeDir, 'gcloud-service-key.json'), + defaultsTo: homeDir == null + ? null + : path.join(homeDir, 'gcloud-service-key.json'), help: 'The path to the service key for gcloud authentication.\n' r'If not provided, \$HOME/gcloud-service-key.json will be ' r'assumed if $HOME is set.'); @@ -150,7 +152,7 @@ class FirebaseTestLabCommand extends PackageLoopingCommand { // test file's run. int resultsCounter = 0; for (final File test in _findIntegrationTestFiles(package)) { - final String testName = p.relative(test.path, from: package.path); + final String testName = getRelativePosixPath(test, from: package); print('Testing $testName...'); if (!await _runGradle(androidDirectory, 'app:assembleDebug', testFile: test)) { @@ -203,7 +205,7 @@ class FirebaseTestLabCommand extends PackageLoopingCommand { print('Running flutter build apk...'); final String experiment = getStringArg(kEnableExperiment); final int exitCode = await processRunner.runAndStream( - 'flutter', + flutterCommand, [ 'build', 'apk', diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index 9d39d93b9118..7954fd044ce4 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -7,7 +7,7 @@ import 'dart:io' as io; import 'package:file/file.dart'; import 'package:http/http.dart' as http; -import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'package:quiver/iterables.dart'; import 'common/core.dart'; @@ -28,7 +28,8 @@ class FormatCommand extends PluginCommand { FormatCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), - }) : super(packagesDir, processRunner: processRunner) { + Platform platform = const LocalPlatform(), + }) : super(packagesDir, processRunner: processRunner, platform: platform) { argParser.addFlag('fail-on-change', hide: true); argParser.addOption('clang-format', defaultsTo: 'clang-format', @@ -156,7 +157,7 @@ class FormatCommand extends PluginCommand { // `flutter format` doesn't require the project to actually be a Flutter // project. final int exitCode = await processRunner.runAndStream( - 'flutter', ['format', ...dartFiles], + flutterCommand, ['format', ...dartFiles], workingDir: packagesDir); if (exitCode != 0) { printError('Failed to format Dart files: exit code $exitCode.'); @@ -168,8 +169,12 @@ class FormatCommand extends PluginCommand { Future> _getFilteredFilePaths(Stream files) async { // Returns a pattern to check for [directories] as a subset of a file path. RegExp pathFragmentForDirectories(List directories) { - final String s = p.separator; - return RegExp('(?:^|$s)${p.joinAll(directories)}$s'); + String s = path.separator; + // Escape the separator for use in the regex. + if (s == r'\') { + s = r'\\'; + } + return RegExp('(?:^|$s)${path.joinAll(directories)}$s'); } return files @@ -188,12 +193,13 @@ class FormatCommand extends PluginCommand { Iterable _getPathsWithExtensions( Iterable files, Set extensions) { - return files.where((String path) => extensions.contains(p.extension(path))); + return files.where( + (String filePath) => extensions.contains(path.extension(filePath))); } Future _getGoogleFormatterPath() async { - final String javaFormatterPath = p.join( - p.dirname(p.fromUri(io.Platform.script)), + final String javaFormatterPath = path.join( + path.dirname(path.fromUri(platform.script)), 'google-java-format-1.3-all-deps.jar'); final File javaFormatterFile = packagesDir.fileSystem.file(javaFormatterPath); diff --git a/script/tool/lib/src/java_test_command.dart b/script/tool/lib/src/java_test_command.dart index 352197be3057..b36d1102f109 100644 --- a/script/tool/lib/src/java_test_command.dart +++ b/script/tool/lib/src/java_test_command.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:file/file.dart'; -import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'common/core.dart'; import 'common/package_looping_command.dart'; @@ -15,7 +15,8 @@ class JavaTestCommand extends PackageLoopingCommand { JavaTestCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), - }) : super(packagesDir, processRunner: processRunner); + Platform platform = const LocalPlatform(), + }) : super(packagesDir, processRunner: processRunner, platform: platform); static const String _gradleWrapper = 'gradlew'; @@ -50,7 +51,7 @@ class JavaTestCommand extends PackageLoopingCommand { final List errors = []; for (final Directory example in examplesWithTests) { - final String exampleName = p.relative(example.path, from: package.path); + final String exampleName = getRelativePosixPath(example, from: package); print('\nRUNNING JAVA TESTS for $exampleName'); final Directory androidDirectory = example.childDirectory('android'); diff --git a/script/tool/lib/src/license_check_command.dart b/script/tool/lib/src/license_check_command.dart index 1d3e49c6a7c6..093f8143df4f 100644 --- a/script/tool/lib/src/license_check_command.dart +++ b/script/tool/lib/src/license_check_command.dart @@ -112,7 +112,7 @@ class LicenseCheckCommand extends PluginCommand { !_shouldIgnoreFile(file)); final Iterable firstPartyLicenseFiles = (await _getAllFiles()).where( (File file) => - p.basename(file.basename) == 'LICENSE' && !_isThirdParty(file)); + path.basename(file.basename) == 'LICENSE' && !_isThirdParty(file)); final bool copyrightCheckSucceeded = await _checkCodeLicenses(codeFiles); print('\n=======================================\n'); @@ -246,7 +246,7 @@ class LicenseCheckCommand extends PluginCommand { } bool _isThirdParty(File file) { - return p.split(file.path).contains('third_party'); + return path.split(file.path).contains('third_party'); } Future> _getAllFiles() => packagesDir.parent diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart index 82cce0bd13e6..d0d93fcb79b1 100644 --- a/script/tool/lib/src/lint_podspecs_command.dart +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -25,8 +25,7 @@ class LintPodspecsCommand extends PackageLoopingCommand { Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), Platform platform = const LocalPlatform(), - }) : _platform = platform, - super(packagesDir, processRunner: processRunner) { + }) : super(packagesDir, processRunner: processRunner, platform: platform) { argParser.addMultiOption('ignore-warnings', help: 'Do not pass --allow-warnings flag to "pod lib lint" for podspecs ' @@ -45,11 +44,9 @@ class LintPodspecsCommand extends PackageLoopingCommand { '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; - @override Future initializeRun() async { - if (!_platform.isMacOS) { + if (!platform.isMacOS) { printError('This command is only supported on macOS'); throw ToolExit(_exitUnsupportedPlatform); } @@ -89,11 +86,10 @@ class LintPodspecsCommand extends PackageLoopingCommand { final List podspecs = await getFilesForPackage(package).where((File entity) { final String filePath = entity.path; - return p.extension(filePath) == '.podspec'; + return path.extension(filePath) == '.podspec'; }).toList(); - podspecs.sort( - (File a, File b) => p.basename(a.path).compareTo(p.basename(b.path))); + podspecs.sort((File a, File b) => a.basename.compareTo(b.basename)); return podspecs; } diff --git a/script/tool/lib/src/list_command.dart b/script/tool/lib/src/list_command.dart index 39515cf686b0..20f01ff98f0e 100644 --- a/script/tool/lib/src/list_command.dart +++ b/script/tool/lib/src/list_command.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:file/file.dart'; +import 'package:platform/platform.dart'; import 'common/plugin_command.dart'; @@ -10,7 +11,10 @@ import 'common/plugin_command.dart'; class ListCommand extends PluginCommand { /// Creates an instance of the list command, whose behavior depends on the /// 'type' argument it provides. - ListCommand(Directory packagesDir) : super(packagesDir) { + ListCommand( + Directory packagesDir, { + Platform platform = const LocalPlatform(), + }) : super(packagesDir, platform: platform) { argParser.addOption( _type, defaultsTo: _plugin, diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index ccafabfddd1d..fda68a6a74a4 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -8,6 +8,7 @@ import 'dart:io' as io; import 'package:file/file.dart'; import 'package:http/http.dart' as http; +import 'package:platform/platform.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:pubspec_parse/pubspec_parse.dart'; @@ -22,10 +23,11 @@ class PublishCheckCommand extends PackageLoopingCommand { PublishCheckCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), + Platform platform = const LocalPlatform(), http.Client? httpClient, }) : _pubVersionFinder = PubVersionFinder(httpClient: httpClient ?? http.Client()), - super(packagesDir, processRunner: processRunner) { + super(packagesDir, processRunner: processRunner, platform: platform) { argParser.addFlag( _allowPrereleaseFlag, help: 'Allows the pre-release SDK warning to pass.\n' @@ -128,7 +130,7 @@ class PublishCheckCommand extends PackageLoopingCommand { Future _hasValidPublishCheckRun(Directory package) async { print('Running pub publish --dry-run:'); final io.Process process = await processRunner.start( - 'flutter', + flutterCommand, ['pub', 'publish', '--', '--dry-run'], workingDirectory: package, ); diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index 6de53ba2690a..8bcb9e37e8ef 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -208,9 +208,13 @@ class PublishPluginCommand extends PluginCommand { final List packagesFailed = []; for (final String pubspecPath in changedPubspecs) { + // Convert git's Posix-style paths to a path that matches the current + // filesystem. + final String localStylePubspecPath = + path.joinAll(p.posix.split(pubspecPath)); final File pubspecFile = packagesDir.fileSystem .directory(baseGitDir.path) - .childFile(pubspecPath); + .childFile(localStylePubspecPath); final _CheckNeedsReleaseResult result = await _checkNeedsRelease( pubspecFile: pubspecFile, existingTags: existingTags, @@ -445,7 +449,7 @@ Safe to ignore if the package is deleted in this commit. } final io.Process publish = await processRunner.start( - 'flutter', ['pub', 'publish'] + publishFlags, + flutterCommand, ['pub', 'publish'] + publishFlags, workingDirectory: packageDir); publish.stdout .transform(utf8.decoder) diff --git a/script/tool/lib/src/pubspec_check_command.dart b/script/tool/lib/src/pubspec_check_command.dart index 7d39c7322b71..539b170dbea1 100644 --- a/script/tool/lib/src/pubspec_check_command.dart +++ b/script/tool/lib/src/pubspec_check_command.dart @@ -4,6 +4,7 @@ import 'package:file/file.dart'; import 'package:git/git.dart'; +import 'package:platform/platform.dart'; import 'package:pubspec_parse/pubspec_parse.dart'; import 'common/package_looping_command.dart'; @@ -19,8 +20,14 @@ class PubspecCheckCommand extends PackageLoopingCommand { PubspecCheckCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), + Platform platform = const LocalPlatform(), GitDir? gitDir, - }) : super(packagesDir, processRunner: processRunner, gitDir: gitDir); + }) : super( + packagesDir, + processRunner: processRunner, + platform: platform, + gitDir: gitDir, + ); // Section order for plugins. Because the 'flutter' section is critical // information for plugins, and usually small, it goes near the top unlike in diff --git a/script/tool/lib/src/test_command.dart b/script/tool/lib/src/test_command.dart index d06a2841812a..9dfe66b7926a 100644 --- a/script/tool/lib/src/test_command.dart +++ b/script/tool/lib/src/test_command.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:file/file.dart'; +import 'package:platform/platform.dart'; import 'common/core.dart'; import 'common/package_looping_command.dart'; @@ -15,7 +16,8 @@ class TestCommand extends PackageLoopingCommand { TestCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), - }) : super(packagesDir, processRunner: processRunner) { + Platform platform = const LocalPlatform(), + }) : super(packagesDir, processRunner: processRunner, platform: platform) { argParser.addOption( kEnableExperiment, defaultsTo: '', diff --git a/script/tool/lib/src/version_check_command.dart b/script/tool/lib/src/version_check_command.dart index f0902f016833..c08600c3f669 100644 --- a/script/tool/lib/src/version_check_command.dart +++ b/script/tool/lib/src/version_check_command.dart @@ -7,6 +7,7 @@ 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:platform/platform.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:pubspec_parse/pubspec_parse.dart'; @@ -77,11 +78,17 @@ class VersionCheckCommand extends PackageLoopingCommand { VersionCheckCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), + Platform platform = const LocalPlatform(), GitDir? gitDir, http.Client? httpClient, }) : _pubVersionFinder = PubVersionFinder(httpClient: httpClient ?? http.Client()), - super(packagesDir, processRunner: processRunner, gitDir: gitDir) { + super( + packagesDir, + processRunner: processRunner, + platform: platform, + gitDir: gitDir, + ) { argParser.addFlag( _againstPubFlag, help: 'Whether the version check should run against the version on pub.\n' @@ -179,8 +186,13 @@ ${indentation}HTTP response: ${pubVersionFinderResponse.httpResponse.body} required GitVersionFinder gitVersionFinder, }) async { final File pubspecFile = package.childFile('pubspec.yaml'); - return await gitVersionFinder.getPackageVersion( - p.relative(pubspecFile.absolute.path, from: (await gitDir).path)); + final String relativePath = + path.relative(pubspecFile.absolute.path, from: (await gitDir).path); + // Use Posix-style paths for git. + final String gitPath = path.style == p.Style.windows + ? p.posix.joinAll(path.split(relativePath)) + : relativePath; + return await gitVersionFinder.getPackageVersion(gitPath); } /// Returns true if the version of [package] is either unchanged relative to diff --git a/script/tool/lib/src/xctest_command.dart b/script/tool/lib/src/xctest_command.dart index cd3b674f8d3a..176adad39a09 100644 --- a/script/tool/lib/src/xctest_command.dart +++ b/script/tool/lib/src/xctest_command.dart @@ -6,7 +6,7 @@ import 'dart:convert'; import 'dart:io' as io; import 'package:file/file.dart'; -import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'common/core.dart'; import 'common/package_looping_command.dart'; @@ -32,7 +32,8 @@ class XCTestCommand extends PackageLoopingCommand { XCTestCommand( Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), - }) : super(packagesDir, processRunner: processRunner) { + Platform platform = const LocalPlatform(), + }) : super(packagesDir, processRunner: processRunner, platform: platform) { argParser.addOption( _kiOSDestination, help: @@ -142,7 +143,7 @@ class XCTestCommand extends PackageLoopingCommand { for (final Directory example in getExamplesForPlugin(plugin)) { // Running tests and static analyzer. final String examplePath = - p.relative(example.path, from: plugin.parent.path); + getRelativePosixPath(example, from: plugin.parent); print('Running $platform tests and analyzer for $examplePath...'); int exitCode = await _runTests(true, example, platform, extraFlags: extraXcrunFlags); diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart index adeaabaaca52..69a2c4f95523 100644 --- a/script/tool/test/analyze_command_test.dart +++ b/script/tool/test/analyze_command_test.dart @@ -16,16 +16,21 @@ import 'util.dart'; void main() { late FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; late RecordingProcessRunner processRunner; late CommandRunner runner; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = RecordingProcessRunner(); - final AnalyzeCommand analyzeCommand = - AnalyzeCommand(packagesDir, processRunner: processRunner); + final AnalyzeCommand analyzeCommand = AnalyzeCommand( + packagesDir, + processRunner: processRunner, + platform: mockPlatform, + ); runner = CommandRunner('analyze_command', 'Test for analyze_command'); runner.addCommand(analyzeCommand); diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart index c0c90a15c71c..27489a50228a 100644 --- a/script/tool/test/build_examples_command_test.dart +++ b/script/tool/test/build_examples_command_test.dart @@ -10,8 +10,6 @@ import 'package:file/memory.dart'; import 'package:flutter_plugin_tools/src/build_examples_command.dart'; import 'package:flutter_plugin_tools/src/common/core.dart'; import 'package:flutter_plugin_tools/src/common/plugin_utils.dart'; -import 'package:path/path.dart' as p; -import 'package:platform/platform.dart'; import 'package:test/test.dart'; import 'mocks.dart'; @@ -20,18 +18,21 @@ import 'util.dart'; void main() { group('build-example', () { late FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; late CommandRunner runner; late RecordingProcessRunner processRunner; - final String flutterCommand = - const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = RecordingProcessRunner(); - final BuildExamplesCommand command = - BuildExamplesCommand(packagesDir, processRunner: processRunner); + final BuildExamplesCommand command = BuildExamplesCommand( + packagesDir, + processRunner: processRunner, + platform: mockPlatform, + ); runner = CommandRunner( 'build_examples_command', 'Test for build_example_command'); @@ -59,7 +60,9 @@ void main() { kPlatformIos: PlatformSupport.inline }); - processRunner.mockProcessesForExecutable['flutter'] = [ + processRunner + .mockProcessesForExecutable[getFlutterCommand(mockPlatform)] = + [ MockProcess.failing() // flutter packages get ]; @@ -81,6 +84,7 @@ void main() { test('building for iOS when plugin is not set up for iOS results in no-op', () async { + mockPlatform.isMacOS = true; createFakePlugin('plugin', packagesDir); final List output = @@ -99,7 +103,8 @@ void main() { expect(processRunner.recordedCalls, orderedEquals([])); }); - test('building for ios', () async { + test('building for iOS', () async { + mockPlatform.isMacOS = true; final Directory pluginDirectory = createFakePlugin('plugin', packagesDir, platformSupport: { kPlatformIos: PlatformSupport.inline @@ -110,13 +115,11 @@ void main() { final List output = await runCapturingPrint(runner, ['build-examples', '--ios', '--enable-experiment=exp1']); - final String packageName = - p.relative(pluginExampleDirectory.path, from: packagesDir.path); expect( output, containsAllInOrder([ - '\nBUILDING $packageName for iOS', + '\nBUILDING plugin/example for iOS', ]), ); @@ -124,7 +127,7 @@ void main() { processRunner.recordedCalls, orderedEquals([ ProcessCall( - flutterCommand, + getFlutterCommand(mockPlatform), const [ 'build', 'ios', @@ -138,6 +141,7 @@ void main() { test( 'building for Linux when plugin is not set up for Linux results in no-op', () async { + mockPlatform.isLinux = true; createFakePlugin('plugin', packagesDir); final List output = await runCapturingPrint( @@ -157,6 +161,7 @@ void main() { }); test('building for Linux', () async { + mockPlatform.isLinux = true; final Directory pluginDirectory = createFakePlugin('plugin', packagesDir, platformSupport: { kPlatformLinux: PlatformSupport.inline, @@ -167,26 +172,25 @@ void main() { final List output = await runCapturingPrint( runner, ['build-examples', '--linux']); - final String packageName = - p.relative(pluginExampleDirectory.path, from: packagesDir.path); expect( output, containsAllInOrder([ - '\nBUILDING $packageName for Linux', + '\nBUILDING plugin/example for Linux', ]), ); expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, const ['build', 'linux'], - pluginExampleDirectory.path), + ProcessCall(getFlutterCommand(mockPlatform), + const ['build', 'linux'], pluginExampleDirectory.path), ])); }); - test('building for macos with no implementation results in no-op', + test('building for macOS with no implementation results in no-op', () async { + mockPlatform.isMacOS = true; createFakePlugin('plugin', packagesDir); final List output = await runCapturingPrint( @@ -205,7 +209,8 @@ void main() { expect(processRunner.recordedCalls, orderedEquals([])); }); - test('building for macos', () async { + test('building for macOS', () async { + mockPlatform.isMacOS = true; final Directory pluginDirectory = createFakePlugin('plugin', packagesDir, platformSupport: { kPlatformMacos: PlatformSupport.inline, @@ -216,21 +221,19 @@ void main() { final List output = await runCapturingPrint( runner, ['build-examples', '--macos']); - final String packageName = - p.relative(pluginExampleDirectory.path, from: packagesDir.path); expect( output, containsAllInOrder([ - '\nBUILDING $packageName for macOS', + '\nBUILDING plugin/example for macOS', ]), ); expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, const ['build', 'macos'], - pluginExampleDirectory.path), + ProcessCall(getFlutterCommand(mockPlatform), + const ['build', 'macos'], pluginExampleDirectory.path), ])); }); @@ -264,27 +267,26 @@ void main() { final List output = await runCapturingPrint(runner, ['build-examples', '--web']); - final String packageName = - p.relative(pluginExampleDirectory.path, from: packagesDir.path); expect( output, containsAllInOrder([ - '\nBUILDING $packageName for web', + '\nBUILDING plugin/example for web', ]), ); expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, const ['build', 'web'], - pluginExampleDirectory.path), + ProcessCall(getFlutterCommand(mockPlatform), + const ['build', 'web'], pluginExampleDirectory.path), ])); }); test( 'building for Windows when plugin is not set up for Windows results in no-op', () async { + mockPlatform.isWindows = true; createFakePlugin('plugin', packagesDir); final List output = await runCapturingPrint( @@ -303,7 +305,8 @@ void main() { expect(processRunner.recordedCalls, orderedEquals([])); }); - test('building for windows', () async { + test('building for Windows', () async { + mockPlatform.isWindows = true; final Directory pluginDirectory = createFakePlugin('plugin', packagesDir, platformSupport: { kPlatformWindows: PlatformSupport.inline @@ -314,20 +317,20 @@ void main() { final List output = await runCapturingPrint( runner, ['build-examples', '--windows']); - final String packageName = - p.relative(pluginExampleDirectory.path, from: packagesDir.path); expect( output, containsAllInOrder([ - '\nBUILDING $packageName for Windows', + '\nBUILDING plugin/example for Windows', ]), ); expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, const ['build', 'windows'], + ProcessCall( + getFlutterCommand(mockPlatform), + const ['build', 'windows'], pluginExampleDirectory.path), ])); }); @@ -353,7 +356,7 @@ void main() { expect(processRunner.recordedCalls, orderedEquals([])); }); - test('building for android', () async { + test('building for Android', () async { final Directory pluginDirectory = createFakePlugin('plugin', packagesDir, platformSupport: { kPlatformAndroid: PlatformSupport.inline @@ -366,21 +369,19 @@ void main() { 'build-examples', '--apk', ]); - final String packageName = - p.relative(pluginExampleDirectory.path, from: packagesDir.path); expect( output, containsAllInOrder([ - '\nBUILDING $packageName for Android (apk)', + '\nBUILDING plugin/example for Android (apk)', ]), ); expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, const ['build', 'apk'], - pluginExampleDirectory.path), + ProcessCall(getFlutterCommand(mockPlatform), + const ['build', 'apk'], pluginExampleDirectory.path), ])); }); @@ -400,7 +401,7 @@ void main() { processRunner.recordedCalls, orderedEquals([ ProcessCall( - flutterCommand, + getFlutterCommand(mockPlatform), const ['build', 'apk', '--enable-experiment=exp1'], pluginExampleDirectory.path), ])); @@ -421,7 +422,7 @@ void main() { processRunner.recordedCalls, orderedEquals([ ProcessCall( - flutterCommand, + getFlutterCommand(mockPlatform), const [ 'build', 'ios', diff --git a/script/tool/test/common/package_looping_command_test.dart b/script/tool/test/common/package_looping_command_test.dart index 917fbc0fd67a..542e91af6431 100644 --- a/script/tool/test/common/package_looping_command_test.dart +++ b/script/tool/test/common/package_looping_command_test.dart @@ -3,7 +3,7 @@ // 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'; @@ -13,8 +13,10 @@ import 'package:flutter_plugin_tools/src/common/package_looping_command.dart'; import 'package:flutter_plugin_tools/src/common/process_runner.dart'; import 'package:git/git.dart'; import 'package:mockito/mockito.dart'; +import 'package:platform/platform.dart'; import 'package:test/test.dart'; +import '../mocks.dart'; import '../util.dart'; import 'plugin_command_test.mocks.dart'; @@ -36,11 +38,13 @@ const String _warningFile = 'warnings'; void main() { late FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; late Directory thirdPartyPackagesDir; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); thirdPartyPackagesDir = packagesDir.parent .childDirectory('third_party') @@ -69,11 +73,12 @@ void main() { when(mockProcessResult.stdout as String?) .thenReturn(gitDiffResponse); } - return Future.value(mockProcessResult); + return Future.value(mockProcessResult); }); return TestPackageLoopingCommand( packagesDir, + platform: mockPlatform, hasLongOutput: hasLongOutput, includeSubpackages: includeSubpackages, failsDuringInit: failsDuringInit, @@ -502,7 +507,25 @@ void main() { test('getPackageDescription prints packageDir-relative paths by default', () async { final TestPackageLoopingCommand command = - TestPackageLoopingCommand(packagesDir); + TestPackageLoopingCommand(packagesDir, platform: mockPlatform); + + expect( + command.getPackageDescription(packagesDir.childDirectory('foo')), + 'foo', + ); + expect( + command.getPackageDescription(packagesDir + .childDirectory('foo') + .childDirectory('bar') + .childDirectory('baz')), + 'foo/bar/baz', + ); + }); + + test('getPackageDescription always uses Posix-style paths', () async { + mockPlatform.isWindows = true; + final TestPackageLoopingCommand command = + TestPackageLoopingCommand(packagesDir, platform: mockPlatform); expect( command.getPackageDescription(packagesDir.childDirectory('foo')), @@ -521,7 +544,7 @@ void main() { 'getPackageDescription elides group name in grouped federated plugin structure', () async { final TestPackageLoopingCommand command = - TestPackageLoopingCommand(packagesDir); + TestPackageLoopingCommand(packagesDir, platform: mockPlatform); expect( command.getPackageDescription(packagesDir @@ -542,6 +565,7 @@ void main() { class TestPackageLoopingCommand extends PackageLoopingCommand { TestPackageLoopingCommand( Directory packagesDir, { + required Platform platform, this.hasLongOutput = true, this.includeSubpackages = false, this.customFailureListHeader, @@ -552,7 +576,8 @@ class TestPackageLoopingCommand extends PackageLoopingCommand { this.captureOutput = false, ProcessRunner processRunner = const ProcessRunner(), GitDir? gitDir, - }) : super(packagesDir, processRunner: processRunner, gitDir: gitDir); + }) : super(packagesDir, + processRunner: processRunner, platform: platform, gitDir: gitDir); final List checkedPackages = []; final List capturedOutput = []; @@ -629,4 +654,4 @@ class TestPackageLoopingCommand extends PackageLoopingCommand { } } -class MockProcessResult extends Mock implements ProcessResult {} +class MockProcessResult extends Mock implements io.ProcessResult {} diff --git a/script/tool/test/common/plugin_command_test.dart b/script/tool/test/common/plugin_command_test.dart index 3f1f1adc4c19..fdab9612be3f 100644 --- a/script/tool/test/common/plugin_command_test.dart +++ b/script/tool/test/common/plugin_command_test.dart @@ -12,8 +12,10 @@ import 'package:flutter_plugin_tools/src/common/process_runner.dart'; import 'package:git/git.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import 'package:platform/platform.dart'; import 'package:test/test.dart'; +import '../mocks.dart'; import '../util.dart'; import 'plugin_command_test.mocks.dart'; @@ -22,6 +24,7 @@ void main() { late RecordingProcessRunner processRunner; late CommandRunner runner; late FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; late Directory thirdPartyPackagesDir; late List plugins; @@ -30,6 +33,7 @@ void main() { setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); thirdPartyPackagesDir = packagesDir.parent .childDirectory('third_party') @@ -54,6 +58,7 @@ void main() { plugins, packagesDir, processRunner: processRunner, + platform: mockPlatform, gitDir: gitDir, ); runner = @@ -414,8 +419,10 @@ class SamplePluginCommand extends PluginCommand { this._plugins, Directory packagesDir, { ProcessRunner processRunner = const ProcessRunner(), + Platform platform = const LocalPlatform(), GitDir? gitDir, - }) : super(packagesDir, processRunner: processRunner, gitDir: gitDir); + }) : super(packagesDir, + processRunner: processRunner, platform: platform, gitDir: gitDir); final List _plugins; diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index 681a9e0e5844..c6893181e286 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -10,7 +10,6 @@ import 'package:file/memory.dart'; import 'package:flutter_plugin_tools/src/common/core.dart'; import 'package:flutter_plugin_tools/src/common/plugin_utils.dart'; import 'package:flutter_plugin_tools/src/drive_examples_command.dart'; -import 'package:path/path.dart' as p; import 'package:platform/platform.dart'; import 'package:test/test.dart'; @@ -23,18 +22,18 @@ const String _fakeAndroidDevice = 'emulator-1234'; void main() { group('test drive_example_command', () { late FileSystem fileSystem; + late Platform mockPlatform; late Directory packagesDir; late CommandRunner runner; late RecordingProcessRunner processRunner; - final String flutterCommand = - const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = RecordingProcessRunner(); - final DriveExamplesCommand command = - DriveExamplesCommand(packagesDir, processRunner: processRunner); + final DriveExamplesCommand command = DriveExamplesCommand(packagesDir, + processRunner: processRunner, platform: mockPlatform); runner = CommandRunner( 'drive_examples_command', 'Test for drive_example_command'); @@ -63,9 +62,9 @@ void main() { final MockProcess mockDevicesProcess = MockProcess.succeeding(); mockDevicesProcess.stdoutController.close(); // ignore: unawaited_futures - processRunner.mockProcessesForExecutable['flutter'] = [ - mockDevicesProcess - ]; + processRunner + .mockProcessesForExecutable[getFlutterCommand(mockPlatform)] = + [mockDevicesProcess]; processRunner.resultStdout = output; } @@ -150,9 +149,9 @@ void main() { test('fails for iOS if getting devices fails', () async { // Simulate failure from `flutter devices`. - processRunner.mockProcessesForExecutable['flutter'] = [ - MockProcess.failing() - ]; + processRunner + .mockProcessesForExecutable[getFlutterCommand(mockPlatform)] = + [MockProcess.failing()]; Error? commandError; final List output = await runCapturingPrint( @@ -216,23 +215,21 @@ void main() { ]), ); - final String deviceTestPath = p.join('test_driver', 'plugin.dart'); - final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); expect( processRunner.recordedCalls, orderedEquals([ + ProcessCall(getFlutterCommand(mockPlatform), + const ['devices', '--machine'], null), ProcessCall( - flutterCommand, const ['devices', '--machine'], null), - ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', _fakeIosDevice, '--driver', - driverTestPath, + 'test_driver/plugin_test.dart', '--target', - deviceTestPath + 'test_driver/plugin.dart' ], pluginExampleDirectory.path), ])); @@ -337,35 +334,33 @@ void main() { ]), ); - final String driverTestPath = - p.join('test_driver', 'integration_test.dart'); expect( processRunner.recordedCalls, orderedEquals([ + ProcessCall(getFlutterCommand(mockPlatform), + const ['devices', '--machine'], null), ProcessCall( - flutterCommand, const ['devices', '--machine'], null), - ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', _fakeIosDevice, '--driver', - driverTestPath, + 'test_driver/integration_test.dart', '--target', - p.join('integration_test', 'bar_test.dart'), + 'integration_test/bar_test.dart', ], pluginExampleDirectory.path), ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', _fakeIosDevice, '--driver', - driverTestPath, + 'test_driver/integration_test.dart', '--target', - p.join('integration_test', 'foo_test.dart'), + 'integration_test/foo_test.dart', ], pluginExampleDirectory.path), ])); @@ -425,21 +420,19 @@ void main() { ]), ); - final String deviceTestPath = p.join('test_driver', 'plugin.dart'); - final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); expect( processRunner.recordedCalls, orderedEquals([ ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', 'linux', '--driver', - driverTestPath, + 'test_driver/plugin_test.dart', '--target', - deviceTestPath + 'test_driver/plugin.dart' ], pluginExampleDirectory.path), ])); @@ -500,21 +493,19 @@ void main() { ]), ); - final String deviceTestPath = p.join('test_driver', 'plugin.dart'); - final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); expect( processRunner.recordedCalls, orderedEquals([ ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', 'macos', '--driver', - driverTestPath, + 'test_driver/plugin_test.dart', '--target', - deviceTestPath + 'test_driver/plugin.dart' ], pluginExampleDirectory.path), ])); @@ -573,23 +564,21 @@ void main() { ]), ); - final String deviceTestPath = p.join('test_driver', 'plugin.dart'); - final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); expect( processRunner.recordedCalls, orderedEquals([ ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', 'web-server', '--web-port=7357', '--browser-name=chrome', '--driver', - driverTestPath, + 'test_driver/plugin_test.dart', '--target', - deviceTestPath + 'test_driver/plugin.dart' ], pluginExampleDirectory.path), ])); @@ -649,21 +638,19 @@ void main() { ]), ); - final String deviceTestPath = p.join('test_driver', 'plugin.dart'); - final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); expect( processRunner.recordedCalls, orderedEquals([ ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', 'windows', '--driver', - driverTestPath, + 'test_driver/plugin_test.dart', '--target', - deviceTestPath + 'test_driver/plugin.dart' ], pluginExampleDirectory.path), ])); @@ -699,23 +686,21 @@ void main() { ]), ); - final String deviceTestPath = p.join('test_driver', 'plugin.dart'); - final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); expect( processRunner.recordedCalls, orderedEquals([ + ProcessCall(getFlutterCommand(mockPlatform), + const ['devices', '--machine'], null), ProcessCall( - flutterCommand, const ['devices', '--machine'], null), - ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', _fakeAndroidDevice, '--driver', - driverTestPath, + 'test_driver/plugin_test.dart', '--target', - deviceTestPath + 'test_driver/plugin.dart' ], pluginExampleDirectory.path), ])); @@ -749,8 +734,8 @@ void main() { // Output should be empty other than the device query. expect(processRunner.recordedCalls, [ - ProcessCall( - flutterCommand, const ['devices', '--machine'], null), + ProcessCall(getFlutterCommand(mockPlatform), + const ['devices', '--machine'], null), ]); }); @@ -782,8 +767,8 @@ void main() { // Output should be empty other than the device query. expect(processRunner.recordedCalls, [ - ProcessCall( - flutterCommand, const ['devices', '--machine'], null), + ProcessCall(getFlutterCommand(mockPlatform), + const ['devices', '--machine'], null), ]); }); @@ -833,24 +818,22 @@ void main() { '--enable-experiment=exp1', ]); - final String deviceTestPath = p.join('test_driver', 'plugin.dart'); - final String driverTestPath = p.join('test_driver', 'plugin_test.dart'); expect( processRunner.recordedCalls, orderedEquals([ + ProcessCall(getFlutterCommand(mockPlatform), + const ['devices', '--machine'], null), ProcessCall( - flutterCommand, const ['devices', '--machine'], null), - ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', _fakeIosDevice, '--enable-experiment=exp1', '--driver', - driverTestPath, + 'test_driver/plugin_test.dart', '--target', - deviceTestPath + 'test_driver/plugin.dart' ], pluginExampleDirectory.path), ])); @@ -967,7 +950,9 @@ void main() { ); // Simulate failure from `flutter drive`. - processRunner.mockProcessesForExecutable['flutter'] = [ + processRunner + .mockProcessesForExecutable[getFlutterCommand(mockPlatform)] = + [ // No mock for 'devices', since it's running for macOS. MockProcess.failing(), // 'drive' #1 MockProcess.failing(), // 'drive' #2 @@ -994,33 +979,31 @@ void main() { final Directory pluginExampleDirectory = pluginDirectory.childDirectory('example'); - final String driverTestPath = - p.join('test_driver', 'integration_test.dart'); expect( processRunner.recordedCalls, orderedEquals([ ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', 'macos', '--driver', - driverTestPath, + 'test_driver/integration_test.dart', '--target', - p.join('integration_test', 'bar_test.dart'), + 'integration_test/bar_test.dart', ], pluginExampleDirectory.path), ProcessCall( - flutterCommand, - [ + getFlutterCommand(mockPlatform), + const [ 'drive', '-d', 'macos', '--driver', - driverTestPath, + 'test_driver/integration_test.dart', '--target', - p.join('integration_test', 'foo_test.dart'), + 'integration_test/foo_test.dart', ], pluginExampleDirectory.path), ])); diff --git a/script/tool/test/firebase_test_lab_command_test.dart b/script/tool/test/firebase_test_lab_command_test.dart index 0199eba95983..c265868bbf3e 100644 --- a/script/tool/test/firebase_test_lab_command_test.dart +++ b/script/tool/test/firebase_test_lab_command_test.dart @@ -17,16 +17,21 @@ import 'util.dart'; void main() { group('$FirebaseTestLabCommand', () { FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; late CommandRunner runner; late RecordingProcessRunner processRunner; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = RecordingProcessRunner(); - final FirebaseTestLabCommand command = - FirebaseTestLabCommand(packagesDir, processRunner: processRunner); + final FirebaseTestLabCommand command = FirebaseTestLabCommand( + packagesDir, + processRunner: processRunner, + platform: mockPlatform, + ); runner = CommandRunner( 'firebase_test_lab_command', 'Test for $FirebaseTestLabCommand'); diff --git a/script/tool/test/format_command_test.dart b/script/tool/test/format_command_test.dart index e7f4d795eb93..fabef31a1b64 100644 --- a/script/tool/test/format_command_test.dart +++ b/script/tool/test/format_command_test.dart @@ -17,21 +17,28 @@ import 'util.dart'; void main() { late FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; + late p.Context path; late RecordingProcessRunner processRunner; late CommandRunner runner; late String javaFormatPath; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = RecordingProcessRunner(); - final FormatCommand analyzeCommand = - FormatCommand(packagesDir, processRunner: processRunner); + final FormatCommand analyzeCommand = FormatCommand( + packagesDir, + processRunner: processRunner, + platform: mockPlatform, + ); // Create the java formatter file that the command checks for, to avoid // a download. - javaFormatPath = p.join(p.dirname(p.fromUri(io.Platform.script)), + path = analyzeCommand.path; + javaFormatPath = path.join(path.dirname(path.fromUri(mockPlatform.script)), 'google-java-format-1.3-all-deps.jar'); fileSystem.file(javaFormatPath).createSync(recursive: true); @@ -42,7 +49,7 @@ void main() { List _getAbsolutePaths( Directory package, List relativePaths) { return relativePaths - .map((String path) => p.join(package.path, path)) + .map((String relativePath) => path.join(package.path, relativePath)) .toList(); } diff --git a/script/tool/test/java_test_command_test.dart b/script/tool/test/java_test_command_test.dart index 9ae959710984..13e0e7fc0f40 100644 --- a/script/tool/test/java_test_command_test.dart +++ b/script/tool/test/java_test_command_test.dart @@ -10,7 +10,6 @@ import 'package:file/memory.dart'; import 'package:flutter_plugin_tools/src/common/core.dart'; import 'package:flutter_plugin_tools/src/common/plugin_utils.dart'; import 'package:flutter_plugin_tools/src/java_test_command.dart'; -import 'package:path/path.dart' as p; import 'package:test/test.dart'; import 'mocks.dart'; @@ -19,16 +18,21 @@ import 'util.dart'; void main() { group('$JavaTestCommand', () { late FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; late CommandRunner runner; late RecordingProcessRunner processRunner; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = RecordingProcessRunner(); - final JavaTestCommand command = - JavaTestCommand(packagesDir, processRunner: processRunner); + final JavaTestCommand command = JavaTestCommand( + packagesDir, + processRunner: processRunner, + platform: mockPlatform, + ); runner = CommandRunner('java_test_test', 'Test for $JavaTestCommand'); @@ -50,13 +54,16 @@ void main() { await runCapturingPrint(runner, ['java-test']); + final Directory androidFolder = + plugin.childDirectory('example').childDirectory('android'); + expect( processRunner.recordedCalls, orderedEquals([ ProcessCall( - p.join(plugin.path, 'example/android/gradlew'), + androidFolder.childFile('gradlew').path, const ['testDebugUnitTest', '--info'], - p.join(plugin.path, 'example/android'), + androidFolder.path, ), ]), ); @@ -77,13 +84,16 @@ void main() { await runCapturingPrint(runner, ['java-test']); + final Directory androidFolder = + plugin.childDirectory('example').childDirectory('android'); + expect( processRunner.recordedCalls, orderedEquals([ ProcessCall( - p.join(plugin.path, 'example/android/gradlew'), + androidFolder.childFile('gradlew').path, const ['testDebugUnitTest', '--info'], - p.join(plugin.path, 'example/android'), + androidFolder.path, ), ]), ); diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart index 1236ec0f5013..51a4e6267770 100644 --- a/script/tool/test/lint_podspecs_command_test.dart +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -9,7 +9,6 @@ import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:flutter_plugin_tools/src/common/core.dart'; import 'package:flutter_plugin_tools/src/lint_podspecs_command.dart'; -import 'package:path/path.dart' as p; import 'package:test/test.dart'; import 'mocks.dart'; @@ -24,7 +23,7 @@ void main() { late RecordingProcessRunner processRunner; setUp(() { - fileSystem = MemoryFileSystem(); + fileSystem = MemoryFileSystem(style: FileSystemStyle.posix); packagesDir = createPackagesDirectory(fileSystem: fileSystem); mockPlatform = MockPlatform(isMacOS: true); @@ -94,7 +93,10 @@ void main() { [ 'lib', 'lint', - p.join(plugin1Dir.path, 'ios', 'plugin1.podspec'), + plugin1Dir + .childDirectory('ios') + .childFile('plugin1.podspec') + .path, '--configuration=Debug', '--skip-tests', '--use-modular-headers', @@ -106,7 +108,10 @@ void main() { [ 'lib', 'lint', - p.join(plugin1Dir.path, 'ios', 'plugin1.podspec'), + plugin1Dir + .childDirectory('ios') + .childFile('plugin1.podspec') + .path, '--configuration=Debug', '--skip-tests', '--use-modular-headers', @@ -136,7 +141,7 @@ void main() { [ 'lib', 'lint', - p.join(plugin1Dir.path, 'plugin1.podspec'), + plugin1Dir.childFile('plugin1.podspec').path, '--configuration=Debug', '--skip-tests', '--use-modular-headers', @@ -149,7 +154,7 @@ void main() { [ 'lib', 'lint', - p.join(plugin1Dir.path, 'plugin1.podspec'), + plugin1Dir.childFile('plugin1.podspec').path, '--configuration=Debug', '--skip-tests', '--use-modular-headers', diff --git a/script/tool/test/list_command_test.dart b/script/tool/test/list_command_test.dart index 836d06671c24..488fc9bcb1e4 100644 --- a/script/tool/test/list_command_test.dart +++ b/script/tool/test/list_command_test.dart @@ -8,18 +8,22 @@ import 'package:file/memory.dart'; import 'package:flutter_plugin_tools/src/list_command.dart'; import 'package:test/test.dart'; +import 'mocks.dart'; import 'util.dart'; void main() { group('$ListCommand', () { late FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; late CommandRunner runner; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); - final ListCommand command = ListCommand(packagesDir); + final ListCommand command = + ListCommand(packagesDir, platform: mockPlatform); 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 02b00658398e..0dcdedd3db03 100644 --- a/script/tool/test/mocks.dart +++ b/script/tool/test/mocks.dart @@ -10,10 +10,25 @@ import 'package:mockito/mockito.dart'; import 'package:platform/platform.dart'; class MockPlatform extends Mock implements Platform { - MockPlatform({this.isMacOS = false}); + MockPlatform({ + this.isLinux = false, + this.isMacOS = false, + this.isWindows = false, + }); + + @override + bool isLinux; @override bool isMacOS; + + @override + bool isWindows; + + @override + Uri get script => isWindows + ? Uri.file(r'C:\foo\bar', windows: true) + : Uri.file('/foo/bar', windows: false); } class MockProcess extends Mock implements io.Process { diff --git a/script/tool/test/publish_check_command_test.dart b/script/tool/test/publish_check_command_test.dart index 5140316b4511..11de9f095481 100644 --- a/script/tool/test/publish_check_command_test.dart +++ b/script/tool/test/publish_check_command_test.dart @@ -21,16 +21,21 @@ import 'util.dart'; void main() { group('$PublishCheckProcessRunner tests', () { FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; late PublishCheckProcessRunner processRunner; late CommandRunner runner; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = PublishCheckProcessRunner(); - final PublishCheckCommand publishCheckCommand = - PublishCheckCommand(packagesDir, processRunner: processRunner); + final PublishCheckCommand publishCheckCommand = PublishCheckCommand( + packagesDir, + processRunner: processRunner, + platform: mockPlatform, + ); runner = CommandRunner( 'publish_check_command', @@ -339,12 +344,16 @@ void main() { }); expect(hasError, isTrue); - expect(output.first, r''' + expect(output.first, contains(r''' { "status": "error", "humanMessage": [ "\n============================================================\n|| Running for no_publish_a\n============================================================\n", - "Failed to parse `pubspec.yaml` at /packages/no_publish_a/pubspec.yaml: ParsedYamlException: line 1, column 1: Not a map\n ╷\n1 │ bad-yaml\n │ ^^^^^^^^\n ╵}", + "Failed to parse `pubspec.yaml` at /packages/no_publish_a/pubspec.yaml: ParsedYamlException:''')); + // This is split into two checks since the details of the YamlException + // aren't controlled by this package, so asserting its exact format would + // make the test fragile to irrelevant changes in those details. + expect(output.first, contains(r''' "no pubspec", "\n============================================================\n|| Running for no_publish_b\n============================================================\n", "url https://pub.dev/packages/no_publish_b.json", @@ -356,7 +365,7 @@ void main() { " no_publish_a", "See above for full details." ] -}'''); +}''')); }); }); } diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index 497579b02f89..c7df81952641 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -16,6 +16,7 @@ import 'package:git/git.dart'; import 'package:http/http.dart' as http; import 'package:http/testing.dart'; import 'package:mockito/mockito.dart'; +import 'package:platform/platform.dart'; import 'package:test/test.dart'; import 'mocks.dart'; @@ -1091,7 +1092,7 @@ class TestProcessRunner extends ProcessRunner { {Directory? workingDirectory}) async { /// Never actually publish anything. Start is always and only used for this /// since it returns something we can route stdin through. - assert(executable == 'flutter' && + assert(executable == getFlutterCommand(const LocalPlatform()) && args.isNotEmpty && args[0] == 'pub' && args[1] == 'publish'); diff --git a/script/tool/test/pubspec_check_command_test.dart b/script/tool/test/pubspec_check_command_test.dart index 9e633e21b4ab..177ed7f25b4e 100644 --- a/script/tool/test/pubspec_check_command_test.dart +++ b/script/tool/test/pubspec_check_command_test.dart @@ -9,6 +9,7 @@ import 'package:flutter_plugin_tools/src/common/core.dart'; import 'package:flutter_plugin_tools/src/pubspec_check_command.dart'; import 'package:test/test.dart'; +import 'mocks.dart'; import 'util.dart'; void main() { @@ -16,15 +17,20 @@ void main() { late CommandRunner runner; late RecordingProcessRunner processRunner; late FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = fileSystem.currentDirectory.childDirectory('packages'); createPackagesDirectory(parentDir: packagesDir.parent); processRunner = RecordingProcessRunner(); - final PubspecCheckCommand command = - PubspecCheckCommand(packagesDir, processRunner: processRunner); + final PubspecCheckCommand command = PubspecCheckCommand( + packagesDir, + processRunner: processRunner, + platform: mockPlatform, + ); runner = CommandRunner( 'pubspec_check_command', 'Test for pubspec_check_command'); diff --git a/script/tool/test/test_command_test.dart b/script/tool/test/test_command_test.dart index ac0ac4b3dd40..503e24d03056 100644 --- a/script/tool/test/test_command_test.dart +++ b/script/tool/test/test_command_test.dart @@ -10,6 +10,7 @@ import 'package:file/memory.dart'; import 'package:flutter_plugin_tools/src/common/core.dart'; import 'package:flutter_plugin_tools/src/common/plugin_utils.dart'; import 'package:flutter_plugin_tools/src/test_command.dart'; +import 'package:platform/platform.dart'; import 'package:test/test.dart'; import 'mocks.dart'; @@ -18,16 +19,21 @@ import 'util.dart'; void main() { group('$TestCommand', () { late FileSystem fileSystem; + late Platform mockPlatform; late Directory packagesDir; late CommandRunner runner; late RecordingProcessRunner processRunner; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = RecordingProcessRunner(); - final TestCommand command = - TestCommand(packagesDir, processRunner: processRunner); + final TestCommand command = TestCommand( + packagesDir, + processRunner: processRunner, + platform: mockPlatform, + ); runner = CommandRunner('test_test', 'Test for $TestCommand'); runner.addCommand(command); @@ -44,10 +50,10 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall( - 'flutter', const ['test', '--color'], plugin1Dir.path), - ProcessCall( - 'flutter', const ['test', '--color'], plugin2Dir.path), + ProcessCall(getFlutterCommand(mockPlatform), + const ['test', '--color'], plugin1Dir.path), + ProcessCall(getFlutterCommand(mockPlatform), + const ['test', '--color'], plugin2Dir.path), ]), ); }); @@ -58,7 +64,9 @@ void main() { createFakePlugin('plugin2', packagesDir, extraFiles: ['test/empty_test.dart']); - processRunner.mockProcessesForExecutable['flutter'] = [ + processRunner + .mockProcessesForExecutable[getFlutterCommand(mockPlatform)] = + [ MockProcess.failing(), // plugin 1 test MockProcess.succeeding(), // plugin 2 test ]; @@ -88,8 +96,8 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall( - 'flutter', const ['test', '--color'], plugin2Dir.path), + ProcessCall(getFlutterCommand(mockPlatform), + const ['test', '--color'], plugin2Dir.path), ]), ); }); @@ -107,7 +115,7 @@ void main() { processRunner.recordedCalls, orderedEquals([ ProcessCall( - 'flutter', + getFlutterCommand(mockPlatform), const ['test', '--color', '--enable-experiment=exp1'], pluginDir.path), ProcessCall('dart', const ['pub', 'get'], packageDir.path), @@ -183,7 +191,7 @@ void main() { processRunner.recordedCalls, orderedEquals([ ProcessCall( - 'flutter', + getFlutterCommand(mockPlatform), const ['test', '--color', '--platform=chrome'], pluginDir.path), ]), @@ -203,7 +211,7 @@ void main() { processRunner.recordedCalls, orderedEquals([ ProcessCall( - 'flutter', + getFlutterCommand(mockPlatform), const ['test', '--color', '--enable-experiment=exp1'], pluginDir.path), ProcessCall('dart', const ['pub', 'get'], packageDir.path), diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index b65b1fcaa84a..1984a25cc430 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -14,8 +14,14 @@ import 'package:flutter_plugin_tools/src/common/plugin_utils.dart'; import 'package:flutter_plugin_tools/src/common/process_runner.dart'; import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'package:quiver/collection.dart'; +/// Returns the exe name that command will use when running Flutter on +/// [platform]. +String getFlutterCommand(Platform platform) => + platform.isWindows ? 'flutter.bat' : 'flutter'; + /// Creates a packages directory in the given location. /// /// If [parentDir] is set the packages directory will be created there, diff --git a/script/tool/test/version_check_command_test.dart b/script/tool/test/version_check_command_test.dart index 6fbed9c691b3..587de1a58cd9 100644 --- a/script/tool/test/version_check_command_test.dart +++ b/script/tool/test/version_check_command_test.dart @@ -18,6 +18,7 @@ import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; import 'common/plugin_command_test.mocks.dart'; +import 'mocks.dart'; import 'util.dart'; void testAllowedVersion( @@ -46,6 +47,7 @@ void main() { const String indentation = ' '; group('$VersionCheckCommand', () { FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; late CommandRunner runner; late RecordingProcessRunner processRunner; @@ -55,6 +57,7 @@ void main() { setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); gitDirCommands = >[]; gitShowResponses = {}; @@ -80,7 +83,7 @@ void main() { }); processRunner = RecordingProcessRunner(); final VersionCheckCommand command = VersionCheckCommand(packagesDir, - processRunner: processRunner, gitDir: gitDir); + processRunner: processRunner, platform: mockPlatform, gitDir: gitDir); runner = CommandRunner( 'version_check_command', 'Test for $VersionCheckCommand'); diff --git a/script/tool/test/xctest_command_test.dart b/script/tool/test/xctest_command_test.dart index 10329b18980c..aa6d23fb56f5 100644 --- a/script/tool/test/xctest_command_test.dart +++ b/script/tool/test/xctest_command_test.dart @@ -90,16 +90,18 @@ void main() { group('test xctest_command', () { late FileSystem fileSystem; + late MockPlatform mockPlatform; late Directory packagesDir; late CommandRunner runner; late RecordingProcessRunner processRunner; setUp(() { fileSystem = MemoryFileSystem(); + mockPlatform = MockPlatform(isMacOS: true); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = RecordingProcessRunner(); - final XCTestCommand command = - XCTestCommand(packagesDir, processRunner: processRunner); + final XCTestCommand command = XCTestCommand(packagesDir, + processRunner: processRunner, platform: mockPlatform); runner = CommandRunner('xctest_command', 'Test for xctest_command'); runner.addCommand(command);