[flutter_plugin_tools] Simplify filesystem usage (#4014)

- Replaces most explicit use of `fileSystem` with path construction using the `child*` utility methods
- Removes explicit passing of a filesystem to the commands; we're already passing a `Directory` for the
  root where the tool operates, and we should never be using a different filesystem than that directory's
  filesystem, so passing it was both redundant, and a potential source of test bugs.
This commit is contained in:
stuartmorgan
2021-06-05 10:32:24 -07:00
committed by GitHub
parent 533596f798
commit bb0a1ea161
34 changed files with 177 additions and 231 deletions

View File

@ -13,10 +13,9 @@ import 'common.dart';
class AnalyzeCommand extends PluginCommand { class AnalyzeCommand extends PluginCommand {
/// Creates a analysis command instance. /// Creates a analysis command instance.
AnalyzeCommand( AnalyzeCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
}) : super(packagesDir, fileSystem, processRunner: processRunner) { }) : super(packagesDir, processRunner: processRunner) {
argParser.addMultiOption(_customAnalysisFlag, argParser.addMultiOption(_customAnalysisFlag,
help: help:
'Directories (comma separated) that are allowed to have their own analysis options.', 'Directories (comma separated) that are allowed to have their own analysis options.',

View File

@ -15,10 +15,9 @@ import 'common.dart';
class BuildExamplesCommand extends PluginCommand { class BuildExamplesCommand extends PluginCommand {
/// Creates an instance of the build command. /// Creates an instance of the build command.
BuildExamplesCommand( BuildExamplesCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
}) : super(packagesDir, fileSystem, processRunner: processRunner) { }) : super(packagesDir, processRunner: processRunner) {
argParser.addFlag(kLinux, defaultsTo: false); argParser.addFlag(kLinux, defaultsTo: false);
argParser.addFlag(kMacos, defaultsTo: false); argParser.addFlag(kMacos, defaultsTo: false);
argParser.addFlag(kWeb, defaultsTo: false); argParser.addFlag(kWeb, defaultsTo: false);
@ -69,7 +68,7 @@ class BuildExamplesCommand extends PluginCommand {
if (getBoolArg(kLinux)) { if (getBoolArg(kLinux)) {
print('\nBUILDING Linux for $packageName'); print('\nBUILDING Linux for $packageName');
if (isLinuxPlugin(plugin, fileSystem)) { if (isLinuxPlugin(plugin)) {
final int buildExitCode = await processRunner.runAndStream( final int buildExitCode = await processRunner.runAndStream(
flutterCommand, flutterCommand,
<String>[ <String>[
@ -89,7 +88,7 @@ class BuildExamplesCommand extends PluginCommand {
if (getBoolArg(kMacos)) { if (getBoolArg(kMacos)) {
print('\nBUILDING macOS for $packageName'); print('\nBUILDING macOS for $packageName');
if (isMacOsPlugin(plugin, fileSystem)) { if (isMacOsPlugin(plugin)) {
final int exitCode = await processRunner.runAndStream( final int exitCode = await processRunner.runAndStream(
flutterCommand, flutterCommand,
<String>[ <String>[
@ -109,7 +108,7 @@ class BuildExamplesCommand extends PluginCommand {
if (getBoolArg(kWeb)) { if (getBoolArg(kWeb)) {
print('\nBUILDING web for $packageName'); print('\nBUILDING web for $packageName');
if (isWebPlugin(plugin, fileSystem)) { if (isWebPlugin(plugin)) {
final int buildExitCode = await processRunner.runAndStream( final int buildExitCode = await processRunner.runAndStream(
flutterCommand, flutterCommand,
<String>[ <String>[
@ -129,7 +128,7 @@ class BuildExamplesCommand extends PluginCommand {
if (getBoolArg(kWindows)) { if (getBoolArg(kWindows)) {
print('\nBUILDING Windows for $packageName'); print('\nBUILDING Windows for $packageName');
if (isWindowsPlugin(plugin, fileSystem)) { if (isWindowsPlugin(plugin)) {
final int buildExitCode = await processRunner.runAndStream( final int buildExitCode = await processRunner.runAndStream(
flutterCommand, flutterCommand,
<String>[ <String>[
@ -149,7 +148,7 @@ class BuildExamplesCommand extends PluginCommand {
if (getBoolArg(kIpa)) { if (getBoolArg(kIpa)) {
print('\nBUILDING IPA for $packageName'); print('\nBUILDING IPA for $packageName');
if (isIosPlugin(plugin, fileSystem)) { if (isIosPlugin(plugin)) {
final int exitCode = await processRunner.runAndStream( final int exitCode = await processRunner.runAndStream(
flutterCommand, flutterCommand,
<String>[ <String>[
@ -170,7 +169,7 @@ class BuildExamplesCommand extends PluginCommand {
if (getBoolArg(kApk)) { if (getBoolArg(kApk)) {
print('\nBUILDING APK for $packageName'); print('\nBUILDING APK for $packageName');
if (isAndroidPlugin(plugin, fileSystem)) { if (isAndroidPlugin(plugin)) {
final int exitCode = await processRunner.runAndStream( final int exitCode = await processRunner.runAndStream(
flutterCommand, flutterCommand,
<String>[ <String>[

View File

@ -48,14 +48,13 @@ const String kApk = 'apk';
const String kEnableExperiment = 'enable-experiment'; const String kEnableExperiment = 'enable-experiment';
/// Returns whether the given directory contains a Flutter package. /// Returns whether the given directory contains a Flutter package.
bool isFlutterPackage(FileSystemEntity entity, FileSystem fileSystem) { bool isFlutterPackage(FileSystemEntity entity) {
if (entity is! Directory) { if (entity is! Directory) {
return false; return false;
} }
try { try {
final File pubspecFile = final File pubspecFile = entity.childFile('pubspec.yaml');
fileSystem.file(p.join(entity.path, 'pubspec.yaml'));
final YamlMap pubspecYaml = final YamlMap pubspecYaml =
loadYaml(pubspecFile.readAsStringSync()) as YamlMap; loadYaml(pubspecFile.readAsStringSync()) as YamlMap;
final YamlMap? dependencies = pubspecYaml['dependencies'] as YamlMap?; final YamlMap? dependencies = pubspecYaml['dependencies'] as YamlMap?;
@ -78,8 +77,7 @@ bool isFlutterPackage(FileSystemEntity entity, FileSystem fileSystem) {
/// plugin: /// plugin:
/// platforms: /// platforms:
/// [platform]: /// [platform]:
bool pluginSupportsPlatform( bool pluginSupportsPlatform(String platform, FileSystemEntity entity) {
String platform, FileSystemEntity entity, FileSystem fileSystem) {
assert(platform == kIos || assert(platform == kIos ||
platform == kAndroid || platform == kAndroid ||
platform == kWeb || platform == kWeb ||
@ -91,8 +89,7 @@ bool pluginSupportsPlatform(
} }
try { try {
final File pubspecFile = final File pubspecFile = entity.childFile('pubspec.yaml');
fileSystem.file(p.join(entity.path, 'pubspec.yaml'));
final YamlMap pubspecYaml = final YamlMap pubspecYaml =
loadYaml(pubspecFile.readAsStringSync()) as YamlMap; loadYaml(pubspecFile.readAsStringSync()) as YamlMap;
final YamlMap? flutterSection = pubspecYaml['flutter'] as YamlMap?; final YamlMap? flutterSection = pubspecYaml['flutter'] as YamlMap?;
@ -120,33 +117,33 @@ bool pluginSupportsPlatform(
} }
/// Returns whether the given directory contains a Flutter Android plugin. /// Returns whether the given directory contains a Flutter Android plugin.
bool isAndroidPlugin(FileSystemEntity entity, FileSystem fileSystem) { bool isAndroidPlugin(FileSystemEntity entity) {
return pluginSupportsPlatform(kAndroid, entity, fileSystem); return pluginSupportsPlatform(kAndroid, entity);
} }
/// Returns whether the given directory contains a Flutter iOS plugin. /// Returns whether the given directory contains a Flutter iOS plugin.
bool isIosPlugin(FileSystemEntity entity, FileSystem fileSystem) { bool isIosPlugin(FileSystemEntity entity) {
return pluginSupportsPlatform(kIos, entity, fileSystem); return pluginSupportsPlatform(kIos, entity);
} }
/// Returns whether the given directory contains a Flutter web plugin. /// Returns whether the given directory contains a Flutter web plugin.
bool isWebPlugin(FileSystemEntity entity, FileSystem fileSystem) { bool isWebPlugin(FileSystemEntity entity) {
return pluginSupportsPlatform(kWeb, entity, fileSystem); return pluginSupportsPlatform(kWeb, entity);
} }
/// Returns whether the given directory contains a Flutter Windows plugin. /// Returns whether the given directory contains a Flutter Windows plugin.
bool isWindowsPlugin(FileSystemEntity entity, FileSystem fileSystem) { bool isWindowsPlugin(FileSystemEntity entity) {
return pluginSupportsPlatform(kWindows, entity, fileSystem); return pluginSupportsPlatform(kWindows, entity);
} }
/// Returns whether the given directory contains a Flutter macOS plugin. /// Returns whether the given directory contains a Flutter macOS plugin.
bool isMacOsPlugin(FileSystemEntity entity, FileSystem fileSystem) { bool isMacOsPlugin(FileSystemEntity entity) {
return pluginSupportsPlatform(kMacos, entity, fileSystem); return pluginSupportsPlatform(kMacos, entity);
} }
/// Returns whether the given directory contains a Flutter linux plugin. /// Returns whether the given directory contains a Flutter linux plugin.
bool isLinuxPlugin(FileSystemEntity entity, FileSystem fileSystem) { bool isLinuxPlugin(FileSystemEntity entity) {
return pluginSupportsPlatform(kLinux, entity, fileSystem); return pluginSupportsPlatform(kLinux, entity);
} }
/// Throws a [ToolExit] with `exitCode` and log the `errorMessage` in red. /// Throws a [ToolExit] with `exitCode` and log the `errorMessage` in red.
@ -169,8 +166,7 @@ class ToolExit extends Error {
abstract class PluginCommand extends Command<void> { abstract class PluginCommand extends Command<void> {
/// Creates a command to operate on [packagesDir] with the given environment. /// Creates a command to operate on [packagesDir] with the given environment.
PluginCommand( PluginCommand(
this.packagesDir, this.packagesDir, {
this.fileSystem, {
this.processRunner = const ProcessRunner(), this.processRunner = const ProcessRunner(),
this.gitDir, this.gitDir,
}) { }) {
@ -223,11 +219,6 @@ abstract class PluginCommand extends Command<void> {
/// The directory containing the plugin packages. /// The directory containing the plugin packages.
final Directory packagesDir; final Directory packagesDir;
/// The file system.
///
/// This can be overridden for testing.
final FileSystem fileSystem;
/// The process runner. /// The process runner.
/// ///
/// This can be overridden for testing. /// This can be overridden for testing.
@ -414,19 +405,17 @@ abstract class PluginCommand extends Command<void> {
/// Returns whether the specified entity is a directory containing a /// Returns whether the specified entity is a directory containing a
/// `pubspec.yaml` file. /// `pubspec.yaml` file.
bool _isDartPackage(FileSystemEntity entity) { bool _isDartPackage(FileSystemEntity entity) {
return entity is Directory && return entity is Directory && entity.childFile('pubspec.yaml').existsSync();
fileSystem.file(p.join(entity.path, 'pubspec.yaml')).existsSync();
} }
/// Returns the example Dart packages contained in the specified plugin, or /// Returns the example Dart packages contained in the specified plugin, or
/// an empty List, if the plugin has no examples. /// an empty List, if the plugin has no examples.
Iterable<Directory> getExamplesForPlugin(Directory plugin) { Iterable<Directory> getExamplesForPlugin(Directory plugin) {
final Directory exampleFolder = final Directory exampleFolder = plugin.childDirectory('example');
fileSystem.directory(p.join(plugin.path, 'example'));
if (!exampleFolder.existsSync()) { if (!exampleFolder.existsSync()) {
return <Directory>[]; return <Directory>[];
} }
if (isFlutterPackage(exampleFolder, fileSystem)) { if (isFlutterPackage(exampleFolder)) {
return <Directory>[exampleFolder]; return <Directory>[exampleFolder];
} }
// Only look at the subdirectories of the example directory if the example // Only look at the subdirectories of the example directory if the example
@ -434,8 +423,7 @@ abstract class PluginCommand extends Command<void> {
// example directory for other dart packages. // example directory for other dart packages.
return exampleFolder return exampleFolder
.listSync() .listSync()
.where( .where((FileSystemEntity entity) => isFlutterPackage(entity))
(FileSystemEntity entity) => isFlutterPackage(entity, fileSystem))
.cast<Directory>(); .cast<Directory>();
} }

View File

@ -8,7 +8,6 @@ import 'dart:async';
import 'dart:io' as io; import 'dart:io' as io;
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart'; import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
@ -18,11 +17,10 @@ import 'common.dart';
class CreateAllPluginsAppCommand extends PluginCommand { class CreateAllPluginsAppCommand extends PluginCommand {
/// Creates an instance of the builder command. /// Creates an instance of the builder command.
CreateAllPluginsAppCommand( CreateAllPluginsAppCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
this.pluginsRoot, this.pluginsRoot,
}) : super(packagesDir, fileSystem) { }) : super(packagesDir) {
pluginsRoot ??= fileSystem.currentDirectory; pluginsRoot ??= packagesDir.fileSystem.currentDirectory;
appDirectory = pluginsRoot.childDirectory('all_plugins'); appDirectory = pluginsRoot.childDirectory('all_plugins');
} }
@ -161,8 +159,7 @@ class CreateAllPluginsAppCommand extends PluginCommand {
await for (final Directory package in getPlugins()) { await for (final Directory package in getPlugins()) {
final String pluginName = package.path.split('/').last; final String pluginName = package.path.split('/').last;
final File pubspecFile = final File pubspecFile = package.childFile('pubspec.yaml');
fileSystem.file(p.join(package.path, 'pubspec.yaml'));
final Pubspec pubspec = Pubspec.parse(pubspecFile.readAsStringSync()); final Pubspec pubspec = Pubspec.parse(pubspecFile.readAsStringSync());
if (pubspec.publishTo != 'none') { if (pubspec.publishTo != 'none') {

View File

@ -12,10 +12,9 @@ import 'common.dart';
class DriveExamplesCommand extends PluginCommand { class DriveExamplesCommand extends PluginCommand {
/// Creates an instance of the drive command. /// Creates an instance of the drive command.
DriveExamplesCommand( DriveExamplesCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
}) : super(packagesDir, fileSystem, processRunner: processRunner) { }) : super(packagesDir, processRunner: processRunner) {
argParser.addFlag(kAndroid, argParser.addFlag(kAndroid,
help: 'Runs the Android implementation of the examples'); help: 'Runs the Android implementation of the examples');
argParser.addFlag(kIos, argParser.addFlag(kIos,
@ -67,7 +66,7 @@ class DriveExamplesCommand extends PluginCommand {
continue; continue;
} }
print('\n==========\nChecking $pluginName...'); print('\n==========\nChecking $pluginName...');
if (!(await _pluginSupportedOnCurrentPlatform(plugin, fileSystem))) { if (!(await _pluginSupportedOnCurrentPlatform(plugin))) {
print('Not supported for the target platform; skipping.'); print('Not supported for the target platform; skipping.');
continue; continue;
} }
@ -79,8 +78,7 @@ class DriveExamplesCommand extends PluginCommand {
++examplesFound; ++examplesFound;
final String packageName = final String packageName =
p.relative(example.path, from: packagesDir.path); p.relative(example.path, from: packagesDir.path);
final Directory driverTests = final Directory driverTests = example.childDirectory('test_driver');
fileSystem.directory(p.join(example.path, 'test_driver'));
if (!driverTests.existsSync()) { if (!driverTests.existsSync()) {
print('No driver tests found for $packageName'); print('No driver tests found for $packageName');
continue; continue;
@ -98,7 +96,7 @@ class DriveExamplesCommand extends PluginCommand {
'.dart', '.dart',
); );
String deviceTestPath = p.join('test', deviceTestName); String deviceTestPath = p.join('test', deviceTestName);
if (!fileSystem if (!example.fileSystem
.file(p.join(example.path, deviceTestPath)) .file(p.join(example.path, deviceTestPath))
.existsSync()) { .existsSync()) {
// If the app isn't in test/ folder, look in test_driver/ instead. // If the app isn't in test/ folder, look in test_driver/ instead.
@ -106,13 +104,13 @@ class DriveExamplesCommand extends PluginCommand {
} }
final List<String> targetPaths = <String>[]; final List<String> targetPaths = <String>[];
if (fileSystem if (example.fileSystem
.file(p.join(example.path, deviceTestPath)) .file(p.join(example.path, deviceTestPath))
.existsSync()) { .existsSync()) {
targetPaths.add(deviceTestPath); targetPaths.add(deviceTestPath);
} else { } else {
final Directory integrationTests = final Directory integrationTests =
fileSystem.directory(p.join(example.path, 'integration_test')); example.childDirectory('integration_test');
if (await integrationTests.exists()) { if (await integrationTests.exists()) {
await for (final FileSystemEntity integrationTest await for (final FileSystemEntity integrationTest
@ -145,19 +143,19 @@ Tried searching for the following:
driveArgs.add('--enable-experiment=$enableExperiment'); driveArgs.add('--enable-experiment=$enableExperiment');
} }
if (isLinux && isLinuxPlugin(plugin, fileSystem)) { if (isLinux && isLinuxPlugin(plugin)) {
driveArgs.addAll(<String>[ driveArgs.addAll(<String>[
'-d', '-d',
'linux', 'linux',
]); ]);
} }
if (isMacos && isMacOsPlugin(plugin, fileSystem)) { if (isMacos && isMacOsPlugin(plugin)) {
driveArgs.addAll(<String>[ driveArgs.addAll(<String>[
'-d', '-d',
'macos', 'macos',
]); ]);
} }
if (isWeb && isWebPlugin(plugin, fileSystem)) { if (isWeb && isWebPlugin(plugin)) {
driveArgs.addAll(<String>[ driveArgs.addAll(<String>[
'-d', '-d',
'web-server', 'web-server',
@ -165,7 +163,7 @@ Tried searching for the following:
'--browser-name=chrome', '--browser-name=chrome',
]); ]);
} }
if (isWindows && isWindowsPlugin(plugin, fileSystem)) { if (isWindows && isWindowsPlugin(plugin)) {
driveArgs.addAll(<String>[ driveArgs.addAll(<String>[
'-d', '-d',
'windows', 'windows',
@ -220,7 +218,7 @@ Tried searching for the following:
} }
Future<bool> _pluginSupportedOnCurrentPlatform( Future<bool> _pluginSupportedOnCurrentPlatform(
FileSystemEntity plugin, FileSystem fileSystem) async { FileSystemEntity plugin) async {
final bool isAndroid = getBoolArg(kAndroid); final bool isAndroid = getBoolArg(kAndroid);
final bool isIOS = getBoolArg(kIos); final bool isIOS = getBoolArg(kIos);
final bool isLinux = getBoolArg(kLinux); final bool isLinux = getBoolArg(kLinux);
@ -228,27 +226,27 @@ Tried searching for the following:
final bool isWeb = getBoolArg(kWeb); final bool isWeb = getBoolArg(kWeb);
final bool isWindows = getBoolArg(kWindows); final bool isWindows = getBoolArg(kWindows);
if (isAndroid) { if (isAndroid) {
return isAndroidPlugin(plugin, fileSystem); return isAndroidPlugin(plugin);
} }
if (isIOS) { if (isIOS) {
return isIosPlugin(plugin, fileSystem); return isIosPlugin(plugin);
} }
if (isLinux) { if (isLinux) {
return isLinuxPlugin(plugin, fileSystem); return isLinuxPlugin(plugin);
} }
if (isMacos) { if (isMacos) {
return isMacOsPlugin(plugin, fileSystem); return isMacOsPlugin(plugin);
} }
if (isWeb) { if (isWeb) {
return isWebPlugin(plugin, fileSystem); return isWebPlugin(plugin);
} }
if (isWindows) { if (isWindows) {
return isWindowsPlugin(plugin, fileSystem); return isWindowsPlugin(plugin);
} }
// When we are here, no flags are specified. Only return true if the plugin // When we are here, no flags are specified. Only return true if the plugin
// supports Android for legacy command support. // supports Android for legacy command support.
// TODO(cyanglaz): Make Android flag also required like other platforms // TODO(cyanglaz): Make Android flag also required like other platforms
// (breaking change). https://github.com/flutter/flutter/issues/58285 // (breaking change). https://github.com/flutter/flutter/issues/58285
return isAndroidPlugin(plugin, fileSystem); return isAndroidPlugin(plugin);
} }
} }

View File

@ -17,12 +17,11 @@ import 'common.dart';
class FirebaseTestLabCommand extends PluginCommand { class FirebaseTestLabCommand extends PluginCommand {
/// Creates an instance of the test runner command. /// Creates an instance of the test runner command.
FirebaseTestLabCommand( FirebaseTestLabCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
Print print = print, Print print = print,
}) : _print = print, }) : _print = print,
super(packagesDir, fileSystem, processRunner: processRunner) { super(packagesDir, processRunner: processRunner) {
argParser.addOption( argParser.addOption(
'project', 'project',
defaultsTo: 'flutter-infra', defaultsTo: 'flutter-infra',
@ -105,10 +104,13 @@ class FirebaseTestLabCommand extends PluginCommand {
Future<void> run() async { Future<void> run() async {
final Stream<Directory> packagesWithTests = getPackages().where( final Stream<Directory> packagesWithTests = getPackages().where(
(Directory d) => (Directory d) =>
isFlutterPackage(d, fileSystem) && isFlutterPackage(d) &&
fileSystem d
.directory(p.join( .childDirectory('example')
d.path, 'example', 'android', 'app', 'src', 'androidTest')) .childDirectory('android')
.childDirectory('app')
.childDirectory('src')
.childDirectory('androidTest')
.existsSync()); .existsSync());
final List<String> failingPackages = <String>[]; final List<String> failingPackages = <String>[];
@ -118,23 +120,20 @@ class FirebaseTestLabCommand extends PluginCommand {
await for (final Directory package in packagesWithTests) { await for (final Directory package in packagesWithTests) {
// See https://github.com/flutter/flutter/issues/38983 // See https://github.com/flutter/flutter/issues/38983
final Directory exampleDirectory = final Directory exampleDirectory = package.childDirectory('example');
fileSystem.directory(p.join(package.path, 'example'));
final String packageName = final String packageName =
p.relative(package.path, from: packagesDir.path); p.relative(package.path, from: packagesDir.path);
_print('\nRUNNING FIREBASE TEST LAB TESTS for $packageName'); _print('\nRUNNING FIREBASE TEST LAB TESTS for $packageName');
final Directory androidDirectory = final Directory androidDirectory =
fileSystem.directory(p.join(exampleDirectory.path, 'android')); exampleDirectory.childDirectory('android');
final String enableExperiment = getStringArg(kEnableExperiment); final String enableExperiment = getStringArg(kEnableExperiment);
final String encodedEnableExperiment = final String encodedEnableExperiment =
Uri.encodeComponent('--enable-experiment=$enableExperiment'); Uri.encodeComponent('--enable-experiment=$enableExperiment');
// Ensures that gradle wrapper exists // Ensures that gradle wrapper exists
if (!fileSystem if (!androidDirectory.childFile(_gradleWrapper).existsSync()) {
.file(p.join(androidDirectory.path, _gradleWrapper))
.existsSync()) {
final int exitCode = await processRunner.runAndStream( final int exitCode = await processRunner.runAndStream(
'flutter', 'flutter',
<String>[ <String>[
@ -181,8 +180,7 @@ class FirebaseTestLabCommand extends PluginCommand {
final List<Directory> testDirs = final List<Directory> testDirs =
package.listSync().where(isTestDir).cast<Directory>().toList(); package.listSync().where(isTestDir).cast<Directory>().toList();
final Directory example = final Directory example = package.childDirectory('example');
fileSystem.directory(p.join(package.path, 'example'));
testDirs.addAll( testDirs.addAll(
example.listSync().where(isTestDir).cast<Directory>().toList()); example.listSync().where(isTestDir).cast<Directory>().toList());
for (final Directory testDir in testDirs) { for (final Directory testDir in testDirs) {

View File

@ -20,10 +20,9 @@ final Uri _googleFormatterUrl = Uri.https('github.com',
class FormatCommand extends PluginCommand { class FormatCommand extends PluginCommand {
/// Creates an instance of the format command. /// Creates an instance of the format command.
FormatCommand( FormatCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
}) : super(packagesDir, fileSystem, processRunner: processRunner) { }) : super(packagesDir, processRunner: processRunner) {
argParser.addFlag('fail-on-change', hide: true); argParser.addFlag('fail-on-change', hide: true);
argParser.addOption('clang-format', argParser.addOption('clang-format',
defaultsTo: 'clang-format', defaultsTo: 'clang-format',
@ -144,7 +143,8 @@ class FormatCommand extends PluginCommand {
final String javaFormatterPath = p.join( final String javaFormatterPath = p.join(
p.dirname(p.fromUri(io.Platform.script)), p.dirname(p.fromUri(io.Platform.script)),
'google-java-format-1.3-all-deps.jar'); 'google-java-format-1.3-all-deps.jar');
final File javaFormatterFile = fileSystem.file(javaFormatterPath); final File javaFormatterFile =
packagesDir.fileSystem.file(javaFormatterPath);
if (!javaFormatterFile.existsSync()) { if (!javaFormatterFile.existsSync()) {
print('Downloading Google Java Format...'); print('Downloading Google Java Format...');

View File

@ -13,10 +13,9 @@ import 'common.dart';
class JavaTestCommand extends PluginCommand { class JavaTestCommand extends PluginCommand {
/// Creates an instance of the test runner. /// Creates an instance of the test runner.
JavaTestCommand( JavaTestCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
}) : super(packagesDir, fileSystem, processRunner: processRunner); }) : super(packagesDir, processRunner: processRunner);
@override @override
final String name = 'java-test'; final String name = 'java-test';
@ -32,12 +31,17 @@ class JavaTestCommand extends PluginCommand {
Future<void> run() async { Future<void> run() async {
final Stream<Directory> examplesWithTests = getExamples().where( final Stream<Directory> examplesWithTests = getExamples().where(
(Directory d) => (Directory d) =>
isFlutterPackage(d, fileSystem) && isFlutterPackage(d) &&
(fileSystem (d
.directory(p.join(d.path, 'android', 'app', 'src', 'test')) .childDirectory('android')
.childDirectory('app')
.childDirectory('src')
.childDirectory('test')
.existsSync() || .existsSync() ||
fileSystem d.parent
.directory(p.join(d.path, '..', 'android', 'src', 'test')) .childDirectory('android')
.childDirectory('src')
.childDirectory('test')
.existsSync())); .existsSync()));
final List<String> failingPackages = <String>[]; final List<String> failingPackages = <String>[];
@ -47,11 +51,8 @@ class JavaTestCommand extends PluginCommand {
p.relative(example.path, from: packagesDir.path); p.relative(example.path, from: packagesDir.path);
print('\nRUNNING JAVA TESTS for $packageName'); print('\nRUNNING JAVA TESTS for $packageName');
final Directory androidDirectory = final Directory androidDirectory = example.childDirectory('android');
fileSystem.directory(p.join(example.path, 'android')); if (!androidDirectory.childFile(_gradleWrapper).existsSync()) {
if (!fileSystem
.file(p.join(androidDirectory.path, _gradleWrapper))
.existsSync()) {
print('ERROR: Run "flutter build apk" on example app of $packageName' print('ERROR: Run "flutter build apk" on example app of $packageName'
'before executing tests.'); 'before executing tests.');
missingFlutterBuild.add(packageName); missingFlutterBuild.add(packageName);

View File

@ -98,11 +98,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class LicenseCheckCommand extends PluginCommand { class LicenseCheckCommand extends PluginCommand {
/// Creates a new license check command for [packagesDir]. /// Creates a new license check command for [packagesDir].
LicenseCheckCommand( LicenseCheckCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
Print print = print, Print print = print,
}) : _print = print, }) : _print = print,
super(packagesDir, fileSystem); super(packagesDir);
final Print _print; final Print _print;

View File

@ -20,14 +20,13 @@ import 'common.dart';
class LintPodspecsCommand extends PluginCommand { class LintPodspecsCommand extends PluginCommand {
/// Creates an instance of the linter command. /// Creates an instance of the linter command.
LintPodspecsCommand( LintPodspecsCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
Platform platform = const LocalPlatform(), Platform platform = const LocalPlatform(),
Print print = print, Print print = print,
}) : _platform = platform, }) : _platform = platform,
_print = print, _print = print,
super(packagesDir, fileSystem, processRunner: processRunner) { super(packagesDir, processRunner: processRunner) {
argParser.addMultiOption('skip', argParser.addMultiOption('skip',
help: help:
'Skip all linting for podspecs with this basename (example: federated plugins with placeholder podspecs)', 'Skip all linting for podspecs with this basename (example: federated plugins with placeholder podspecs)',

View File

@ -12,8 +12,7 @@ import 'common.dart';
class ListCommand extends PluginCommand { class ListCommand extends PluginCommand {
/// Creates an instance of the list command, whose behavior depends on the /// Creates an instance of the list command, whose behavior depends on the
/// 'type' argument it provides. /// 'type' argument it provides.
ListCommand(Directory packagesDir, FileSystem fileSystem) ListCommand(Directory packagesDir) : super(packagesDir) {
: super(packagesDir, fileSystem) {
argParser.addOption( argParser.addOption(
_type, _type,
defaultsTo: _plugin, defaultsTo: _plugin,

View File

@ -9,7 +9,6 @@ import 'dart:io' as io;
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/local.dart'; import 'package:file/local.dart';
import 'package:path/path.dart' as p;
import 'analyze_command.dart'; import 'analyze_command.dart';
import 'build_examples_command.dart'; import 'build_examples_command.dart';
@ -32,11 +31,11 @@ import 'xctest_command.dart';
void main(List<String> args) { void main(List<String> args) {
const FileSystem fileSystem = LocalFileSystem(); const FileSystem fileSystem = LocalFileSystem();
Directory packagesDir = fileSystem Directory packagesDir =
.directory(p.join(fileSystem.currentDirectory.path, 'packages')); fileSystem.currentDirectory.childDirectory('packages');
if (!packagesDir.existsSync()) { if (!packagesDir.existsSync()) {
if (p.basename(fileSystem.currentDirectory.path) == 'packages') { if (fileSystem.currentDirectory.basename == 'packages') {
packagesDir = fileSystem.currentDirectory; packagesDir = fileSystem.currentDirectory;
} else { } else {
print('Error: Cannot find a "packages" sub-directory'); print('Error: Cannot find a "packages" sub-directory');
@ -47,22 +46,22 @@ void main(List<String> args) {
final CommandRunner<void> commandRunner = CommandRunner<void>( final CommandRunner<void> commandRunner = CommandRunner<void>(
'pub global run flutter_plugin_tools', 'pub global run flutter_plugin_tools',
'Productivity utils for hosting multiple plugins within one repository.') 'Productivity utils for hosting multiple plugins within one repository.')
..addCommand(AnalyzeCommand(packagesDir, fileSystem)) ..addCommand(AnalyzeCommand(packagesDir))
..addCommand(BuildExamplesCommand(packagesDir, fileSystem)) ..addCommand(BuildExamplesCommand(packagesDir))
..addCommand(CreateAllPluginsAppCommand(packagesDir, fileSystem)) ..addCommand(CreateAllPluginsAppCommand(packagesDir))
..addCommand(DriveExamplesCommand(packagesDir, fileSystem)) ..addCommand(DriveExamplesCommand(packagesDir))
..addCommand(FirebaseTestLabCommand(packagesDir, fileSystem)) ..addCommand(FirebaseTestLabCommand(packagesDir))
..addCommand(FormatCommand(packagesDir, fileSystem)) ..addCommand(FormatCommand(packagesDir))
..addCommand(JavaTestCommand(packagesDir, fileSystem)) ..addCommand(JavaTestCommand(packagesDir))
..addCommand(LicenseCheckCommand(packagesDir, fileSystem)) ..addCommand(LicenseCheckCommand(packagesDir))
..addCommand(LintPodspecsCommand(packagesDir, fileSystem)) ..addCommand(LintPodspecsCommand(packagesDir))
..addCommand(ListCommand(packagesDir, fileSystem)) ..addCommand(ListCommand(packagesDir))
..addCommand(PublishCheckCommand(packagesDir, fileSystem)) ..addCommand(PublishCheckCommand(packagesDir))
..addCommand(PublishPluginCommand(packagesDir, fileSystem)) ..addCommand(PublishPluginCommand(packagesDir))
..addCommand(PubspecCheckCommand(packagesDir, fileSystem)) ..addCommand(PubspecCheckCommand(packagesDir))
..addCommand(TestCommand(packagesDir, fileSystem)) ..addCommand(TestCommand(packagesDir))
..addCommand(VersionCheckCommand(packagesDir, fileSystem)) ..addCommand(VersionCheckCommand(packagesDir))
..addCommand(XCTestCommand(packagesDir, fileSystem)); ..addCommand(XCTestCommand(packagesDir));
commandRunner.run(args).catchError((Object e) { commandRunner.run(args).catchError((Object e) {
final ToolExit toolExit = e as ToolExit; final ToolExit toolExit = e as ToolExit;

View File

@ -21,13 +21,12 @@ import 'common.dart';
class PublishCheckCommand extends PluginCommand { class PublishCheckCommand extends PluginCommand {
/// Creates an instance of the publish command. /// Creates an instance of the publish command.
PublishCheckCommand( PublishCheckCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
this.httpClient, this.httpClient,
}) : _pubVersionFinder = }) : _pubVersionFinder =
PubVersionFinder(httpClient: httpClient ?? http.Client()), PubVersionFinder(httpClient: httpClient ?? http.Client()),
super(packagesDir, fileSystem, processRunner: processRunner) { super(packagesDir, processRunner: processRunner) {
argParser.addFlag( argParser.addFlag(
_allowPrereleaseFlag, _allowPrereleaseFlag,
help: 'Allows the pre-release SDK warning to pass.\n' help: 'Allows the pre-release SDK warning to pass.\n'

View File

@ -32,16 +32,14 @@ import 'common.dart';
class PublishPluginCommand extends PluginCommand { class PublishPluginCommand extends PluginCommand {
/// Creates an instance of the publish command. /// Creates an instance of the publish command.
PublishPluginCommand( PublishPluginCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
Print print = print, Print print = print,
io.Stdin stdinput, io.Stdin stdinput,
GitDir gitDir, GitDir gitDir,
}) : _print = print, }) : _print = print,
_stdin = stdinput ?? io.stdin, _stdin = stdinput ?? io.stdin,
super(packagesDir, fileSystem, super(packagesDir, processRunner: processRunner, gitDir: gitDir) {
processRunner: processRunner, gitDir: gitDir) {
argParser.addOption( argParser.addOption(
_packageOption, _packageOption,
help: 'The package to publish.' help: 'The package to publish.'
@ -133,12 +131,15 @@ class PublishPluginCommand extends PluginCommand {
} }
_print('Checking local repo...'); _print('Checking local repo...');
if (!await GitDir.isGitDir(packagesDir.path)) { // Ensure there are no symlinks in the path, as it can break
_print('$packagesDir is not a valid Git repository.'); // GitDir's allowSubdirectory:true.
final String packagesPath = packagesDir.resolveSymbolicLinksSync();
if (!await GitDir.isGitDir(packagesPath)) {
_print('$packagesPath is not a valid Git repository.');
throw ToolExit(1); throw ToolExit(1);
} }
final GitDir baseGitDir = final GitDir baseGitDir =
await GitDir.fromExisting(packagesDir.path, allowSubdirectory: true); await GitDir.fromExisting(packagesPath, allowSubdirectory: true);
final bool shouldPushTag = getBoolArg(_pushTagsOption); final bool shouldPushTag = getBoolArg(_pushTagsOption);
final String remote = getStringArg(_remoteOption); final String remote = getStringArg(_remoteOption);
@ -194,8 +195,9 @@ class PublishPluginCommand extends PluginCommand {
final List<String> packagesFailed = <String>[]; final List<String> packagesFailed = <String>[];
for (final String pubspecPath in changedPubspecs) { for (final String pubspecPath in changedPubspecs) {
final File pubspecFile = final File pubspecFile = packagesDir.fileSystem
fileSystem.directory(baseGitDir.path).childFile(pubspecPath); .directory(baseGitDir.path)
.childFile(pubspecPath);
final _CheckNeedsReleaseResult result = await _checkNeedsRelease( final _CheckNeedsReleaseResult result = await _checkNeedsRelease(
pubspecFile: pubspecFile, pubspecFile: pubspecFile,
gitVersionFinder: gitVersionFinder, gitVersionFinder: gitVersionFinder,
@ -453,8 +455,7 @@ Safe to ignore if the package is deleted in this commit.
} }
String _getTag(Directory packageDir) { String _getTag(Directory packageDir) {
final File pubspecFile = final File pubspecFile = packageDir.childFile('pubspec.yaml');
fileSystem.file(p.join(packageDir.path, 'pubspec.yaml'));
final YamlMap pubspecYaml = final YamlMap pubspecYaml =
loadYaml(pubspecFile.readAsStringSync()) as YamlMap; loadYaml(pubspecFile.readAsStringSync()) as YamlMap;
final String name = pubspecYaml['name'] as String; final String name = pubspecYaml['name'] as String;
@ -499,7 +500,7 @@ Safe to ignore if the package is deleted in this commit.
} }
void _ensureValidPubCredential() { void _ensureValidPubCredential() {
final File credentialFile = fileSystem.file(_credentialsPath); final File credentialFile = packagesDir.fileSystem.file(_credentialsPath);
if (credentialFile.existsSync() && if (credentialFile.existsSync() &&
credentialFile.readAsStringSync().isNotEmpty) { credentialFile.readAsStringSync().isNotEmpty) {
return; return;

View File

@ -19,12 +19,10 @@ import 'common.dart';
class PubspecCheckCommand extends PluginCommand { class PubspecCheckCommand extends PluginCommand {
/// Creates an instance of the version check command. /// Creates an instance of the version check command.
PubspecCheckCommand( PubspecCheckCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
GitDir? gitDir, GitDir? gitDir,
}) : super(packagesDir, fileSystem, }) : super(packagesDir, processRunner: processRunner, gitDir: gitDir);
processRunner: processRunner, gitDir: gitDir);
// Section order for plugins. Because the 'flutter' section is critical // Section order for plugins. Because the 'flutter' section is critical
// information for plugins, and usually small, it goes near the top unlike in // information for plugins, and usually small, it goes near the top unlike in

View File

@ -13,10 +13,9 @@ import 'common.dart';
class TestCommand extends PluginCommand { class TestCommand extends PluginCommand {
/// Creates an instance of the test command. /// Creates an instance of the test command.
TestCommand( TestCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
}) : super(packagesDir, fileSystem, processRunner: processRunner) { }) : super(packagesDir, processRunner: processRunner) {
argParser.addOption( argParser.addOption(
kEnableExperiment, kEnableExperiment,
defaultsTo: '', defaultsTo: '',
@ -37,7 +36,7 @@ class TestCommand extends PluginCommand {
await for (final Directory packageDir in getPackages()) { await for (final Directory packageDir in getPackages()) {
final String packageName = final String packageName =
p.relative(packageDir.path, from: packagesDir.path); p.relative(packageDir.path, from: packagesDir.path);
if (!fileSystem.directory(p.join(packageDir.path, 'test')).existsSync()) { if (!packageDir.childDirectory('test').existsSync()) {
print('SKIPPING $packageName - no test subdirectory'); print('SKIPPING $packageName - no test subdirectory');
continue; continue;
} }
@ -48,7 +47,7 @@ class TestCommand extends PluginCommand {
// `flutter test` automatically gets packages. `pub run test` does not. :( // `flutter test` automatically gets packages. `pub run test` does not. :(
int exitCode = 0; int exitCode = 0;
if (isFlutterPackage(packageDir, fileSystem)) { if (isFlutterPackage(packageDir)) {
final List<String> args = <String>[ final List<String> args = <String>[
'test', 'test',
'--color', '--color',
@ -56,7 +55,7 @@ class TestCommand extends PluginCommand {
'--enable-experiment=$enableExperiment', '--enable-experiment=$enableExperiment',
]; ];
if (isWebPlugin(packageDir, fileSystem)) { if (isWebPlugin(packageDir)) {
args.add('--platform=chrome'); args.add('--platform=chrome');
} }
exitCode = await processRunner.runAndStream( exitCode = await processRunner.runAndStream(

View File

@ -73,15 +73,13 @@ Map<Version, NextVersionType> getAllowedNextVersions(
class VersionCheckCommand extends PluginCommand { class VersionCheckCommand extends PluginCommand {
/// Creates an instance of the version check command. /// Creates an instance of the version check command.
VersionCheckCommand( VersionCheckCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
GitDir gitDir, GitDir gitDir,
this.httpClient, this.httpClient,
}) : _pubVersionFinder = }) : _pubVersionFinder =
PubVersionFinder(httpClient: httpClient ?? http.Client()), PubVersionFinder(httpClient: httpClient ?? http.Client()),
super(packagesDir, fileSystem, super(packagesDir, processRunner: processRunner, gitDir: gitDir) {
processRunner: processRunner, gitDir: gitDir) {
argParser.addFlag( argParser.addFlag(
_againstPubFlag, _againstPubFlag,
help: 'Whether the version check should run against the version on pub.\n' help: 'Whether the version check should run against the version on pub.\n'
@ -117,7 +115,7 @@ class VersionCheckCommand extends PluginCommand {
const String indentation = ' '; const String indentation = ' ';
for (final String pubspecPath in changedPubspecs) { for (final String pubspecPath in changedPubspecs) {
print('Checking versions for $pubspecPath...'); print('Checking versions for $pubspecPath...');
final File pubspecFile = fileSystem.file(pubspecPath); final File pubspecFile = packagesDir.fileSystem.file(pubspecPath);
if (!pubspecFile.existsSync()) { if (!pubspecFile.existsSync()) {
print('${indentation}Deleted; skipping.'); print('${indentation}Deleted; skipping.');
continue; continue;

View File

@ -26,10 +26,9 @@ const String _kFoundNoSimulatorsMessage =
class XCTestCommand extends PluginCommand { class XCTestCommand extends PluginCommand {
/// Creates an instance of the test command. /// Creates an instance of the test command.
XCTestCommand( XCTestCommand(
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
}) : super(packagesDir, fileSystem, processRunner: processRunner) { }) : super(packagesDir, processRunner: processRunner) {
argParser.addOption( argParser.addOption(
_kiOSDestination, _kiOSDestination,
help: help:
@ -68,7 +67,7 @@ class XCTestCommand extends PluginCommand {
final String packageName = final String packageName =
p.relative(plugin.path, from: packagesDir.path); p.relative(plugin.path, from: packagesDir.path);
print('Start running for $packageName ...'); print('Start running for $packageName ...');
if (!isIosPlugin(plugin, fileSystem)) { if (!isIosPlugin(plugin)) {
print('iOS is not supported by this plugin.'); print('iOS is not supported by this plugin.');
print('\n\n'); print('\n\n');
continue; continue;

View File

@ -18,9 +18,8 @@ void main() {
setUp(() { setUp(() {
initializeFakePackages(); initializeFakePackages();
processRunner = RecordingProcessRunner(); processRunner = RecordingProcessRunner();
final AnalyzeCommand analyzeCommand = AnalyzeCommand( final AnalyzeCommand analyzeCommand =
mockPackagesDir, mockFileSystem, AnalyzeCommand(mockPackagesDir, processRunner: processRunner);
processRunner: processRunner);
runner = CommandRunner<void>('analyze_command', 'Test for analyze_command'); runner = CommandRunner<void>('analyze_command', 'Test for analyze_command');
runner.addCommand(analyzeCommand); runner.addCommand(analyzeCommand);

View File

@ -21,9 +21,8 @@ void main() {
setUp(() { setUp(() {
initializeFakePackages(); initializeFakePackages();
processRunner = RecordingProcessRunner(); processRunner = RecordingProcessRunner();
final BuildExamplesCommand command = BuildExamplesCommand( final BuildExamplesCommand command =
mockPackagesDir, mockFileSystem, BuildExamplesCommand(mockPackagesDir, processRunner: processRunner);
processRunner: processRunner);
runner = CommandRunner<void>( runner = CommandRunner<void>(
'build_examples_command', 'Test for build_example_command'); 'build_examples_command', 'Test for build_example_command');

View File

@ -58,7 +58,6 @@ void main() {
final SamplePluginCommand samplePluginCommand = SamplePluginCommand( final SamplePluginCommand samplePluginCommand = SamplePluginCommand(
plugins, plugins,
packagesDir, packagesDir,
fileSystem,
processRunner: processRunner, processRunner: processRunner,
gitDir: gitDir, gitDir: gitDir,
); );
@ -156,8 +155,7 @@ void main() {
expect(plugins, unorderedEquals(<String>[plugin1.path, plugin2.path])); expect(plugins, unorderedEquals(<String>[plugin1.path, plugin2.path]));
}); });
test('all plugins should be tested if .cirrus.yml changes.', test('all plugins should be tested if .cirrus.yml changes.', () async {
() async {
gitDiffResponse = ''' gitDiffResponse = '''
.cirrus.yml .cirrus.yml
packages/plugin1/CHANGELOG packages/plugin1/CHANGELOG
@ -172,8 +170,7 @@ packages/plugin1/CHANGELOG
expect(plugins, unorderedEquals(<String>[plugin1.path, plugin2.path])); expect(plugins, unorderedEquals(<String>[plugin1.path, plugin2.path]));
}); });
test('all plugins should be tested if .ci.yaml changes', test('all plugins should be tested if .ci.yaml changes', () async {
() async {
gitDiffResponse = ''' gitDiffResponse = '''
.ci.yaml .ci.yaml
packages/plugin1/CHANGELOG packages/plugin1/CHANGELOG
@ -188,8 +185,7 @@ packages/plugin1/CHANGELOG
expect(plugins, unorderedEquals(<String>[plugin1.path, plugin2.path])); expect(plugins, unorderedEquals(<String>[plugin1.path, plugin2.path]));
}); });
test('all plugins should be tested if anything in .ci/ changes', test('all plugins should be tested if anything in .ci/ changes', () async {
() async {
gitDiffResponse = ''' gitDiffResponse = '''
.ci/Dockerfile .ci/Dockerfile
packages/plugin1/CHANGELOG packages/plugin1/CHANGELOG
@ -520,12 +516,10 @@ file2/file2.cc
class SamplePluginCommand extends PluginCommand { class SamplePluginCommand extends PluginCommand {
SamplePluginCommand( SamplePluginCommand(
this._plugins, this._plugins,
Directory packagesDir, Directory packagesDir, {
FileSystem fileSystem, {
ProcessRunner processRunner = const ProcessRunner(), ProcessRunner processRunner = const ProcessRunner(),
GitDir? gitDir, GitDir? gitDir,
}) : super(packagesDir, fileSystem, }) : super(packagesDir, processRunner: processRunner, gitDir: gitDir);
processRunner: processRunner, gitDir: gitDir);
final List<String> _plugins; final List<String> _plugins;

View File

@ -30,7 +30,6 @@ void main() {
final CreateAllPluginsAppCommand command = CreateAllPluginsAppCommand( final CreateAllPluginsAppCommand command = CreateAllPluginsAppCommand(
packagesDir, packagesDir,
fileSystem,
pluginsRoot: testRoot, pluginsRoot: testRoot,
); );
appDir = command.appDirectory; appDir = command.appDirectory;

View File

@ -21,9 +21,8 @@ void main() {
setUp(() { setUp(() {
initializeFakePackages(); initializeFakePackages();
processRunner = RecordingProcessRunner(); processRunner = RecordingProcessRunner();
final DriveExamplesCommand command = DriveExamplesCommand( final DriveExamplesCommand command =
mockPackagesDir, mockFileSystem, DriveExamplesCommand(mockPackagesDir, processRunner: processRunner);
processRunner: processRunner);
runner = CommandRunner<void>( runner = CommandRunner<void>(
'drive_examples_command', 'Test for drive_example_command'); 'drive_examples_command', 'Test for drive_example_command');

View File

@ -24,7 +24,7 @@ void main() {
initializeFakePackages(); initializeFakePackages();
processRunner = RecordingProcessRunner(); processRunner = RecordingProcessRunner();
final FirebaseTestLabCommand command = FirebaseTestLabCommand( final FirebaseTestLabCommand command = FirebaseTestLabCommand(
mockPackagesDir, mockFileSystem, mockPackagesDir,
processRunner: processRunner, processRunner: processRunner,
print: (Object message) => printedMessages.add(message.toString())); print: (Object message) => printedMessages.add(message.toString()));

View File

@ -17,9 +17,8 @@ void main() {
setUp(() { setUp(() {
initializeFakePackages(); initializeFakePackages();
final JavaTestCommand command = JavaTestCommand( final JavaTestCommand command =
mockPackagesDir, mockFileSystem, JavaTestCommand(mockPackagesDir, processRunner: processRunner);
processRunner: processRunner);
runner = runner =
CommandRunner<void>('java_test_test', 'Test for $JavaTestCommand'); CommandRunner<void>('java_test_test', 'Test for $JavaTestCommand');

View File

@ -25,7 +25,6 @@ void main() {
printedMessages = <String>[]; printedMessages = <String>[];
final LicenseCheckCommand command = LicenseCheckCommand( final LicenseCheckCommand command = LicenseCheckCommand(
packagesDir, packagesDir,
fileSystem,
print: (Object? message) => printedMessages.add(message.toString()), print: (Object? message) => printedMessages.add(message.toString()),
); );
runner = runner =

View File

@ -30,7 +30,6 @@ void main() {
when(mockPlatform.isMacOS).thenReturn(true); when(mockPlatform.isMacOS).thenReturn(true);
final LintPodspecsCommand command = LintPodspecsCommand( final LintPodspecsCommand command = LintPodspecsCommand(
mockPackagesDir, mockPackagesDir,
mockFileSystem,
processRunner: processRunner, processRunner: processRunner,
platform: mockPlatform, platform: mockPlatform,
print: (Object message) => printedMessages.add(message.toString()), print: (Object message) => printedMessages.add(message.toString()),

View File

@ -15,7 +15,7 @@ void main() {
setUp(() { setUp(() {
initializeFakePackages(); initializeFakePackages();
final ListCommand command = ListCommand(mockPackagesDir, mockFileSystem); final ListCommand command = ListCommand(mockPackagesDir);
runner = CommandRunner<void>('list_test', 'Test for $ListCommand'); runner = CommandRunner<void>('list_test', 'Test for $ListCommand');
runner.addCommand(command); runner.addCommand(command);

View File

@ -27,9 +27,8 @@ void main() {
setUp(() { setUp(() {
initializeFakePackages(); initializeFakePackages();
processRunner = PublishCheckProcessRunner(); processRunner = PublishCheckProcessRunner();
final PublishCheckCommand publishCheckCommand = PublishCheckCommand( final PublishCheckCommand publishCheckCommand =
mockPackagesDir, mockFileSystem, PublishCheckCommand(mockPackagesDir, processRunner: processRunner);
processRunner: processRunner);
runner = CommandRunner<void>( runner = CommandRunner<void>(
'publish_check_command', 'publish_check_command',
@ -146,8 +145,8 @@ void main() {
processRunner.processesToReturn.add(process); processRunner.processesToReturn.add(process);
final List<String> output = await runCapturingPrint( final List<String> output =
runner, <String>['publish-check']); await runCapturingPrint(runner, <String>['publish-check']);
expect(output, isNot(contains(contains('ERROR:')))); expect(output, isNot(contains(contains('ERROR:'))));
}); });
@ -180,8 +179,7 @@ void main() {
} }
return null; return null;
}); });
final PublishCheckCommand command = PublishCheckCommand( final PublishCheckCommand command = PublishCheckCommand(mockPackagesDir,
mockPackagesDir, mockFileSystem,
processRunner: processRunner, httpClient: mockClient); processRunner: processRunner, httpClient: mockClient);
runner = CommandRunner<void>( runner = CommandRunner<void>(
@ -247,8 +245,7 @@ void main() {
} }
return null; return null;
}); });
final PublishCheckCommand command = PublishCheckCommand( final PublishCheckCommand command = PublishCheckCommand(mockPackagesDir,
mockPackagesDir, mockFileSystem,
processRunner: processRunner, httpClient: mockClient); processRunner: processRunner, httpClient: mockClient);
runner = CommandRunner<void>( runner = CommandRunner<void>(
@ -317,8 +314,7 @@ void main() {
} }
return null; return null;
}); });
final PublishCheckCommand command = PublishCheckCommand( final PublishCheckCommand command = PublishCheckCommand(mockPackagesDir,
mockPackagesDir, mockFileSystem,
processRunner: processRunner, httpClient: mockClient); processRunner: processRunner, httpClient: mockClient);
runner = CommandRunner<void>( runner = CommandRunner<void>(

View File

@ -45,6 +45,9 @@ void main() {
setUp(() async { setUp(() async {
parentDir = fileSystem.systemTempDirectory parentDir = fileSystem.systemTempDirectory
.createTempSync('publish_plugin_command_test-'); .createTempSync('publish_plugin_command_test-');
// The temp directory can have symbolic links, which won't match git output;
// use a fully resolved version to avoid potential path comparison issues.
parentDir = fileSystem.directory(parentDir.resolveSymbolicLinksSync());
initializeFakePackages(parentDir: parentDir); initializeFakePackages(parentDir: parentDir);
pluginDir = createFakePlugin(testPluginName, pluginDir = createFakePlugin(testPluginName,
withSingleExample: false, packagesDirectory: parentDir); withSingleExample: false, packagesDirectory: parentDir);
@ -58,7 +61,7 @@ void main() {
processRunner = TestProcessRunner(); processRunner = TestProcessRunner();
mockStdin = MockStdin(); mockStdin = MockStdin();
commandRunner = CommandRunner<void>('tester', '') commandRunner = CommandRunner<void>('tester', '')
..addCommand(PublishPluginCommand(parentDir, fileSystem, ..addCommand(PublishPluginCommand(parentDir,
processRunner: processRunner, processRunner: processRunner,
print: (Object message) => printedMessages.add(message.toString()), print: (Object message) => printedMessages.add(message.toString()),
stdinput: mockStdin, stdinput: mockStdin,

View File

@ -23,9 +23,8 @@ void main() {
packagesDir = fileSystem.currentDirectory.childDirectory('packages'); packagesDir = fileSystem.currentDirectory.childDirectory('packages');
initializeFakePackages(parentDir: packagesDir.parent); initializeFakePackages(parentDir: packagesDir.parent);
processRunner = RecordingProcessRunner(); processRunner = RecordingProcessRunner();
final PubspecCheckCommand command = PubspecCheckCommand( final PubspecCheckCommand command =
packagesDir, fileSystem, PubspecCheckCommand(packagesDir, processRunner: processRunner);
processRunner: processRunner);
runner = CommandRunner<void>( runner = CommandRunner<void>(
'pubspec_check_command', 'Test for pubspec_check_command'); 'pubspec_check_command', 'Test for pubspec_check_command');

View File

@ -16,8 +16,8 @@ void main() {
setUp(() { setUp(() {
initializeFakePackages(); initializeFakePackages();
final TestCommand command = TestCommand(mockPackagesDir, mockFileSystem, final TestCommand command =
processRunner: processRunner); TestCommand(mockPackagesDir, processRunner: processRunner);
runner = CommandRunner<void>('test_test', 'Test for $TestCommand'); runner = CommandRunner<void>('test_test', 'Test for $TestCommand');
runner.addCommand(command); runner.addCommand(command);

View File

@ -88,8 +88,7 @@ void main() {
}); });
initializeFakePackages(); initializeFakePackages();
processRunner = RecordingProcessRunner(); processRunner = RecordingProcessRunner();
final VersionCheckCommand command = VersionCheckCommand( final VersionCheckCommand command = VersionCheckCommand(mockPackagesDir,
mockPackagesDir, mockFileSystem,
processRunner: processRunner, gitDir: gitDir); processRunner: processRunner, gitDir: gitDir);
runner = CommandRunner<void>( runner = CommandRunner<void>(
@ -238,13 +237,10 @@ void main() {
}); });
test('gracefully handles missing pubspec.yaml', () async { test('gracefully handles missing pubspec.yaml', () async {
createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); final Directory pluginDir = createFakePlugin('plugin',
includeChangeLog: true, includeVersion: true);
gitDiffResponse = 'packages/plugin/pubspec.yaml'; gitDiffResponse = 'packages/plugin/pubspec.yaml';
mockFileSystem.currentDirectory pluginDir.childFile('pubspec.yaml').deleteSync();
.childDirectory('packages')
.childDirectory('plugin')
.childFile('pubspec.yaml')
.deleteSync();
final List<String> output = await runCapturingPrint( final List<String> output = await runCapturingPrint(
runner, <String>['version-check', '--base-sha=master']); runner, <String>['version-check', '--base-sha=master']);
@ -600,8 +596,7 @@ The first version listed in CHANGELOG.md is 1.0.0.
final MockClient mockClient = MockClient((http.Request request) async { final MockClient mockClient = MockClient((http.Request request) async {
return http.Response(json.encode(httpResponse), 200); return http.Response(json.encode(httpResponse), 200);
}); });
final VersionCheckCommand command = VersionCheckCommand( final VersionCheckCommand command = VersionCheckCommand(mockPackagesDir,
mockPackagesDir, mockFileSystem,
processRunner: processRunner, gitDir: gitDir, httpClient: mockClient); processRunner: processRunner, gitDir: gitDir, httpClient: mockClient);
runner = CommandRunner<void>( runner = CommandRunner<void>(
@ -637,8 +632,7 @@ The first version listed in CHANGELOG.md is 1.0.0.
final MockClient mockClient = MockClient((http.Request request) async { final MockClient mockClient = MockClient((http.Request request) async {
return http.Response(json.encode(httpResponse), 200); return http.Response(json.encode(httpResponse), 200);
}); });
final VersionCheckCommand command = VersionCheckCommand( final VersionCheckCommand command = VersionCheckCommand(mockPackagesDir,
mockPackagesDir, mockFileSystem,
processRunner: processRunner, gitDir: gitDir, httpClient: mockClient); processRunner: processRunner, gitDir: gitDir, httpClient: mockClient);
runner = CommandRunner<void>( runner = CommandRunner<void>(
@ -682,8 +676,7 @@ ${indentation}Allowed versions: {1.0.0: NextVersionType.BREAKING_MAJOR, 0.1.0: N
final MockClient mockClient = MockClient((http.Request request) async { final MockClient mockClient = MockClient((http.Request request) async {
return http.Response('xx', 400); return http.Response('xx', 400);
}); });
final VersionCheckCommand command = VersionCheckCommand( final VersionCheckCommand command = VersionCheckCommand(mockPackagesDir,
mockPackagesDir, mockFileSystem,
processRunner: processRunner, gitDir: gitDir, httpClient: mockClient); processRunner: processRunner, gitDir: gitDir, httpClient: mockClient);
runner = CommandRunner<void>( runner = CommandRunner<void>(
@ -726,8 +719,7 @@ ${indentation}HTTP response: xx
final MockClient mockClient = MockClient((http.Request request) async { final MockClient mockClient = MockClient((http.Request request) async {
return http.Response('xx', 404); return http.Response('xx', 404);
}); });
final VersionCheckCommand command = VersionCheckCommand( final VersionCheckCommand command = VersionCheckCommand(mockPackagesDir,
mockPackagesDir, mockFileSystem,
processRunner: processRunner, gitDir: gitDir, httpClient: mockClient); processRunner: processRunner, gitDir: gitDir, httpClient: mockClient);
runner = CommandRunner<void>( runner = CommandRunner<void>(

View File

@ -91,9 +91,8 @@ void main() {
setUp(() { setUp(() {
initializeFakePackages(); initializeFakePackages();
processRunner = RecordingProcessRunner(); processRunner = RecordingProcessRunner();
final XCTestCommand command = XCTestCommand( final XCTestCommand command =
mockPackagesDir, mockFileSystem, XCTestCommand(mockPackagesDir, processRunner: processRunner);
processRunner: processRunner);
runner = CommandRunner<void>('xctest_command', 'Test for xctest_command'); runner = CommandRunner<void>('xctest_command', 'Test for xctest_command');
runner.addCommand(command); runner.addCommand(command);