diff --git a/packages/flutter_tools/lib/src/commands/packages.dart b/packages/flutter_tools/lib/src/commands/packages.dart index 14503a03b2f5..b65e3177b1fb 100644 --- a/packages/flutter_tools/lib/src/commands/packages.dart +++ b/packages/flutter_tools/lib/src/commands/packages.dart @@ -20,10 +20,10 @@ import '../runner/flutter_command.dart'; class PackagesCommand extends FlutterCommand { PackagesCommand() { - addSubcommand(PackagesGetCommand('get', false)); - addSubcommand(PackagesInteractiveGetCommand('upgrade', "Upgrade the current package's dependencies to latest versions.")); - addSubcommand(PackagesInteractiveGetCommand('add', 'Add a dependency to pubspec.yaml.')); - addSubcommand(PackagesInteractiveGetCommand('remove', 'Removes a dependency from the current package.')); + addSubcommand(PackagesGetCommand('get', "Get the current package's dependencies.", PubContext.pubGet)); + addSubcommand(PackagesGetCommand('upgrade', "Upgrade the current package's dependencies to latest versions.", PubContext.pubUpgrade)); + addSubcommand(PackagesGetCommand('add', 'Add a dependency to pubspec.yaml.', PubContext.pubAdd)); + addSubcommand(PackagesGetCommand('remove', 'Removes a dependency from the current package.', PubContext.pubRemove)); addSubcommand(PackagesTestCommand()); addSubcommand(PackagesForwardCommand('publish', 'Publish the current package to pub.dartlang.org.', requiresPubspec: true)); addSubcommand(PackagesForwardCommand('downgrade', 'Downgrade packages in a Flutter project.', requiresPubspec: true)); @@ -56,136 +56,6 @@ class PackagesCommand extends FlutterCommand { Future runCommand() async => FlutterCommandResult.fail(); } -class PackagesGetCommand extends FlutterCommand { - PackagesGetCommand(this.name, this.upgrade) { - argParser.addFlag('offline', - negatable: false, - help: 'Use cached packages instead of accessing the network.', - ); - } - - @override - final String name; - - final bool upgrade; - - @override - String get description { - return '${ upgrade ? "Upgrade" : "Get" } packages in a Flutter project.'; - } - - @override - String get invocation { - return '${runner!.executableName} pub $name []'; - } - - /// The pub packages usage values are incorrect since these are calculated/sent - /// before pub get completes. This needs to be performed after dependency resolution. - @override - Future get usageValues async { - final ArgResults argumentResults = argResults!; - final String? workingDirectory = argumentResults.rest.length == 1 ? argumentResults.rest[0] : null; - final String? target = findProjectRoot(globals.fs, workingDirectory); - if (target == null) { - return const CustomDimensions(); - } - - int numberPlugins; - - final FlutterProject rootProject = FlutterProject.fromDirectory(globals.fs.directory(target)); - // Do not send plugin analytics if pub has not run before. - final bool hasPlugins = rootProject.flutterPluginsDependenciesFile.existsSync() - && rootProject.packageConfigFile.existsSync(); - if (hasPlugins) { - // Do not fail pub get if package config files are invalid before pub has - // had a chance to run. - final List plugins = await findPlugins(rootProject, throwOnError: false); - numberPlugins = plugins.length; - } else { - numberPlugins = 0; - } - - return CustomDimensions( - commandPackagesNumberPlugins: numberPlugins, - commandPackagesProjectModule: rootProject.isModule, - commandPackagesAndroidEmbeddingVersion: rootProject.android.getEmbeddingVersion().toString().split('.').last, - ); - } - - Future _runPubGet(String directory, FlutterProject flutterProject) async { - if (flutterProject.manifest.generateSyntheticPackage) { - final Environment environment = Environment( - artifacts: globals.artifacts!, - logger: globals.logger, - cacheDir: globals.cache.getRoot(), - engineVersion: globals.flutterVersion.engineRevision, - fileSystem: globals.fs, - flutterRootDir: globals.fs.directory(Cache.flutterRoot), - outputDir: globals.fs.directory(getBuildDirectory()), - processManager: globals.processManager, - platform: globals.platform, - usage: globals.flutterUsage, - projectDir: flutterProject.directory, - generateDartPluginRegistry: true, - ); - - await generateLocalizationsSyntheticPackage( - environment: environment, - buildSystem: globals.buildSystem, - ); - } - - final Stopwatch pubGetTimer = Stopwatch()..start(); - try { - await pub.get( - context: PubContext.pubGet, - project: flutterProject, - upgrade: upgrade, - shouldSkipThirdPartyGenerator: false, - offline: boolArgDeprecated('offline'), - ); - pubGetTimer.stop(); - globals.flutterUsage.sendTiming('pub', 'get', pubGetTimer.elapsed, label: 'success'); - // Not limiting to catching Exception because the exception is rethrown. - } catch (_) { // ignore: avoid_catches_without_on_clauses - pubGetTimer.stop(); - globals.flutterUsage.sendTiming('pub', 'get', pubGetTimer.elapsed, label: 'failure'); - rethrow; - } - } - - @override - Future runCommand() async { - final ArgResults argumentResults = argResults!; - if (argumentResults.rest.length > 1) { - throwToolExit('Too many arguments.\n$usage'); - } - - final String? workingDirectory = argumentResults.rest.length == 1 ? argumentResults.rest[0] : null; - final String? target = findProjectRoot(globals.fs, workingDirectory); - if (target == null) { - throwToolExit( - 'Expected to find project root in ' - '${ workingDirectory ?? "current working directory" }.' - ); - } - final FlutterProject rootProject = FlutterProject.fromDirectory(globals.fs.directory(target)); - - // This will also resolve dependencies for the example folder, - await _runPubGet(target, rootProject); - - // We need to regenerate the platform specific tooling for both the project - // itself and example (if present). - await rootProject.regeneratePlatformSpecificTooling(); - if (rootProject.hasExampleApp && rootProject.example.pubspecFile.existsSync()) { - final FlutterProject exampleProject = rootProject.example; - await exampleProject.regeneratePlatformSpecificTooling(); - } - - return FlutterCommandResult.success(); - } -} - class PackagesTestCommand extends FlutterCommand { PackagesTestCommand() { requiresPubspecYaml(); @@ -223,6 +93,8 @@ class PackagesForwardCommand extends FlutterCommand { } } + PubContext context = PubContext.pubForward; + @override ArgParser argParser = ArgParser.allowAnything(); @@ -247,7 +119,11 @@ class PackagesForwardCommand extends FlutterCommand { Future runCommand() async { final List subArgs = argResults!.rest.toList() ..removeWhere((String arg) => arg == '--'); - await pub.interactively([_commandName, ...subArgs], stdio: globals.stdio); + await pub.interactively( + [ _commandName, ...subArgs], + context: context, + command: _commandName, + ); return FlutterCommandResult.success(); } } @@ -270,21 +146,31 @@ class PackagesPassthroughCommand extends FlutterCommand { return '${runner!.executableName} packages pub []'; } + static final PubContext _context = PubContext.pubPassThrough; + @override Future runCommand() async { - await pub.interactively(argResults!.rest, stdio: globals.stdio); + await pub.interactively( + command: 'pub', + argResults!.rest, + context: _context, + ); return FlutterCommandResult.success(); } } -class PackagesInteractiveGetCommand extends FlutterCommand { - PackagesInteractiveGetCommand(this._commandName, this._description); +/// Represents the pub sub-commands that makes package-resolutions. +class PackagesGetCommand extends FlutterCommand { + PackagesGetCommand(this._commandName, this._description, this._context); @override ArgParser argParser = ArgParser.allowAnything(); final String _commandName; final String _description; + final PubContext _context; + + FlutterProject? _rootProject; @override String get name => _commandName; @@ -300,29 +186,89 @@ class PackagesInteractiveGetCommand extends FlutterCommand { return '${runner!.executableName} pub $_commandName []'; } + /// An [ArgParser] that accepts all options and flags that the + /// + /// `pub get` + /// `pub upgrade` + /// `pub downgrade` + /// `pub add` + /// `pub remove` + /// + /// commands accept. + ArgParser get _permissiveArgParser { + final ArgParser argParser = ArgParser(); + argParser.addOption('directory', abbr: 'C'); + argParser.addFlag('offline'); + argParser.addFlag('dry-run', abbr: 'n'); + argParser.addFlag('help', abbr: 'h'); + argParser.addFlag('enforce-lockfile'); + argParser.addFlag('precompile'); + argParser.addFlag('major-versions'); + argParser.addFlag('null-safety'); + argParser.addFlag('example', defaultsTo: true); + argParser.addOption('sdk'); + argParser.addOption('path'); + argParser.addOption('hosted-url'); + argParser.addOption('git-url'); + argParser.addOption('git-ref'); + argParser.addOption('git-path'); + argParser.addFlag('dev'); + return argParser; + } + @override Future runCommand() async { List rest = argResults!.rest; - final bool isHelp = rest.contains('-h') || rest.contains('--help'); - String? target; - if (rest.length == 1 && (rest.single.contains('/') || rest.single.contains(r'\'))) { - // For historical reasons, if there is one argument to the command and it contains - // a multiple-component path (i.e. contains a slash) then we use that to determine - // to which project we're applying the command. - target = findProjectRoot(globals.fs, rest.single); - rest = []; - } else { - target = findProjectRoot(globals.fs); + bool isHelp = false; + bool example = true; + bool exampleWasParsed = false; + String? directoryOption; + bool dryRun = false; + try { + final ArgResults results = _permissiveArgParser.parse(rest); + isHelp = results['help'] as bool; + directoryOption = results['directory'] as String?; + example = results['example'] as bool; + exampleWasParsed = results.wasParsed('example'); + dryRun = results['dry-run'] as bool; + } on ArgParserException { + // Let pub give the error message. } + String? target; + FlutterProject? rootProject; - FlutterProject? flutterProject; if (!isHelp) { - if (target == null) { - throwToolExit('Expected to find project root in current working directory.'); + if (directoryOption == null && rest.length == 1 && + ((rest.single.contains('/') || rest.single.contains(r'\')) || + name == 'get')) { + // For historical reasons, if there is one argument to the command and it contains + // a multiple-component path (i.e. contains a slash) then we use that to determine + // to which project we're applying the command. + target = findProjectRoot(globals.fs, rest.single); + + globals.printWarning(''' + Using a naked argument for directory is deprecated and will stop working in a future Flutter release. + + Use --directory instead.'''); + if (target == null) { + throwToolExit('Expected to find project root in ${rest.single}.'); + } + rest = []; + } else { + target = findProjectRoot(globals.fs, directoryOption); + if (target == null) { + if (directoryOption == null) { + throwToolExit('Expected to find project root in current working directory.'); + } else { + throwToolExit('Expected to find project root in $directoryOption.'); + } + } } - flutterProject = FlutterProject.fromDirectory(globals.fs.directory(target)); - if (flutterProject.manifest.generateSyntheticPackage) { + rootProject = FlutterProject.fromDirectory(globals.fs.directory(target)); + _rootProject = rootProject; + + if (rootProject.manifest.generateSyntheticPackage) { final Environment environment = Environment( artifacts: globals.artifacts!, logger: globals.logger, @@ -334,7 +280,7 @@ class PackagesInteractiveGetCommand extends FlutterCommand { processManager: globals.processManager, platform: globals.platform, usage: globals.flutterUsage, - projectDir: flutterProject.directory, + projectDir: rootProject.directory, generateDartPluginRegistry: true, ); @@ -344,17 +290,70 @@ class PackagesInteractiveGetCommand extends FlutterCommand { ); } } + final String? relativeTarget = target == null ? null : globals.fs.path.relative(target); final List subArgs = rest.toList()..removeWhere((String arg) => arg == '--'); - await pub.interactively( - [name, ...subArgs], - directory: target, - stdio: globals.stdio, - touchesPackageConfig: !isHelp, - generateSyntheticPackage: flutterProject?.manifest.generateSyntheticPackage ?? false, - ); + final Stopwatch timer = Stopwatch()..start(); + try { + await pub.interactively( + [ + name, + ...subArgs, + // `dart pub get` and friends defaults to `--no-example`. + if(!exampleWasParsed && target != null) '--example', + if(directoryOption == null && relativeTarget != null) ...['--directory', relativeTarget], + ], + project: rootProject, + context: _context, + command: name, + touchesPackageConfig: !(isHelp || dryRun), + ); + globals.flutterUsage.sendTiming('pub', 'get', timer.elapsed, label: 'success'); + // Not limiting to catching Exception because the exception is rethrown. + } catch (_) { // ignore: avoid_catches_without_on_clauses + globals.flutterUsage.sendTiming('pub', 'get', timer.elapsed, label: 'failure'); + rethrow; + } + + if (rootProject != null) { + // We need to regenerate the platform specific tooling for both the project + // itself and example(if present). + await rootProject.regeneratePlatformSpecificTooling(); + if (example && rootProject.hasExampleApp && rootProject.example.pubspecFile.existsSync()) { + final FlutterProject exampleProject = rootProject.example; + await exampleProject.regeneratePlatformSpecificTooling(); + } + } - await flutterProject?.regeneratePlatformSpecificTooling(); return FlutterCommandResult.success(); } + + /// The pub packages usage values are incorrect since these are calculated/sent + /// before pub get completes. This needs to be performed after dependency resolution. + @override + Future get usageValues async { + final FlutterProject? rootProject = _rootProject; + if (rootProject == null) { + return const CustomDimensions(); + } + + int numberPlugins; + // Do not send plugin analytics if pub has not run before. + final bool hasPlugins = rootProject.flutterPluginsDependenciesFile.existsSync() + && rootProject.packageConfigFile.existsSync(); + if (hasPlugins) { + // Do not fail pub get if package config files are invalid before pub has + // had a chance to run. + final List plugins = await findPlugins(rootProject, throwOnError: false); + numberPlugins = plugins.length; + } else { + numberPlugins = 0; + } + + return CustomDimensions( + commandPackagesNumberPlugins: numberPlugins, + commandPackagesProjectModule: rootProject.isModule, + commandPackagesAndroidEmbeddingVersion: rootProject.android.getEmbeddingVersion().toString().split('.').last, + ); + } } diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart index fdb97d6a19a2..94c07ea00314 100644 --- a/packages/flutter_tools/lib/src/dart/pub.dart +++ b/packages/flutter_tools/lib/src/dart/pub.dart @@ -120,7 +120,10 @@ class PubContext { static final PubContext interactive = PubContext._(['interactive']); static final PubContext pubGet = PubContext._(['get']); static final PubContext pubUpgrade = PubContext._(['upgrade']); + static final PubContext pubAdd = PubContext._(['add']); + static final PubContext pubRemove = PubContext._(['remove']); static final PubContext pubForward = PubContext._(['forward']); + static final PubContext pubPassThrough = PubContext._(['passthrough']); static final PubContext runTest = PubContext._(['run_test']); static final PubContext flutterTests = PubContext._(['flutter_tests']); static final PubContext updatePackages = PubContext._(['update_packages']); @@ -161,7 +164,7 @@ abstract class Pub { required Stdio stdio, }) = _DefaultPub.test; - /// Runs `pub get` or `pub upgrade` for [project]. + /// Runs `pub get` for [project]. /// /// [context] provides extra information to package server requests to /// understand usage. @@ -173,7 +176,6 @@ abstract class Pub { Future get({ required PubContext context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, String? flutterRootOverride, @@ -203,14 +205,23 @@ abstract class Pub { /// Runs pub in 'interactive' mode. /// - /// directly piping the stdin stream of this process to that of pub, and the - /// stdout/stderr stream of pub to the corresponding streams of this process. + /// This will run the pub process with StdioInherited (unless [_stdio] is set + /// for testing). + /// + /// The pub process will be run in current working directory, so `--directory` + /// should be passed appropriately in [arguments]. This ensures output from + /// pub will refer to relative paths correctly. + /// + /// [touchesPackageConfig] should be true if this is a command expexted to + /// create a new `.dart_tool/package_config.json` file. Future interactively( List arguments, { - String? directory, - required io.Stdio stdio, + FlutterProject? project, + required PubContext context, + required String command, bool touchesPackageConfig = false, bool generateSyntheticPackage = false, + bool printProgress = true, }); } @@ -268,7 +279,6 @@ class _DefaultPub implements Pub { Future get({ required PubContext context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, @@ -280,8 +290,6 @@ class _DefaultPub implements Pub { }) async { final String directory = project.directory.path; final File packageConfigFile = project.packageConfigFile; - final Directory generatedDirectory = _fileSystem.directory( - _fileSystem.path.join(directory, '.dart_tool', 'flutter_gen')); final File lastVersion = _fileSystem.file( _fileSystem.path.join(directory, '.dart_tool', 'version')); final File currentVersion = _fileSystem.file( @@ -352,25 +360,7 @@ class _DefaultPub implements Pub { flutterRootOverride: flutterRootOverride, printProgress: printProgress ); - - if (!packageConfigFile.existsSync()) { - throwToolExit('$directory: pub did not create .dart_tools/package_config.json file.'); - } - lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); - await _updatePackageConfig( - packageConfigFile, - generatedDirectory, - project.manifest.generateSyntheticPackage, - ); - if (project.hasExampleApp && project.example.pubspecFile.existsSync()) { - final Directory exampleGeneratedDirectory = _fileSystem.directory( - _fileSystem.path.join(project.example.directory.path, '.dart_tool', 'flutter_gen')); - await _updatePackageConfig( - project.example.packageConfigFile, - exampleGeneratedDirectory, - project.example.manifest.generateSyntheticPackage, - ); - } + await _updateVersionAndPackageConfig(project); } /// Runs pub with [arguments] and [ProcessStartMode.inheritStdio] mode. @@ -392,9 +382,6 @@ class _DefaultPub implements Pub { String? flutterRootOverride, }) async { int exitCode; - if (printProgress) { - _logger.printStatus('Running "flutter pub $command" in ${_fileSystem.path.basename(directory)}...'); - } final List pubCommand = _pubCommand(arguments); final Map pubEnvironment = await _createPubEnvironment(context, flutterRootOverride); @@ -567,64 +554,22 @@ class _DefaultPub implements Pub { @override Future interactively( List arguments, { - String? directory, - required io.Stdio stdio, + FlutterProject? project, + required PubContext context, + required String command, bool touchesPackageConfig = false, bool generateSyntheticPackage = false, + bool printProgress = true, }) async { - // Fully resolved pub or pub.bat is calculated based on current platform. - final io.Process process = await _processUtils.start( - _pubCommand([ - if (_logger.supportsColor) '--color', - ...arguments, - ]), - workingDirectory: directory, - environment: await _createPubEnvironment(PubContext.interactive), + await _runWithStdioInherited( + arguments, + command: command, + directory: _fileSystem.currentDirectory.path, + context: context, + printProgress: printProgress, ); - - // Pipe the Flutter tool stdin to the pub stdin. - unawaited(process.stdin.addStream(stdio.stdin) - // If pub exits unexpectedly with an error, that will be reported below - // by the tool exit after the exit code check. - .catchError((dynamic err, StackTrace stack) { - _logger.printTrace('Echoing stdin to the pub subprocess failed:'); - _logger.printTrace('$err\n$stack'); - } - )); - - // Pipe the pub stdout and stderr to the tool stdout and stderr. - try { - await Future.wait(>[ - stdio.addStdoutStream(process.stdout), - stdio.addStderrStream(process.stderr), - ]); - } on Exception catch (err, stack) { - _logger.printTrace('Echoing stdout or stderr from the pub subprocess failed:'); - _logger.printTrace('$err\n$stack'); - } - - // Wait for pub to exit. - final int code = await process.exitCode; - if (code != 0) { - throwToolExit('pub finished with exit code $code', exitCode: code); - } - - if (touchesPackageConfig) { - final String targetDirectory = directory ?? _fileSystem.currentDirectory.path; - final File packageConfigFile = _fileSystem.file( - _fileSystem.path.join(targetDirectory, '.dart_tool', 'package_config.json')); - final Directory generatedDirectory = _fileSystem.directory( - _fileSystem.path.join(targetDirectory, '.dart_tool', 'flutter_gen')); - final File lastVersion = _fileSystem.file( - _fileSystem.path.join(targetDirectory, '.dart_tool', 'version')); - final File currentVersion = _fileSystem.file( - _fileSystem.path.join(Cache.flutterRoot!, 'version')); - lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); - await _updatePackageConfig( - packageConfigFile, - generatedDirectory, - generateSyntheticPackage, - ); + if (touchesPackageConfig && project != null) { + await _updateVersionAndPackageConfig(project); } } @@ -766,23 +711,46 @@ class _DefaultPub implements Pub { return environment; } - /// Update the package configuration file. + /// Updates the .dart_tool/version file to be equal to current Flutter + /// version. + /// + /// Calls [_updatePackageConfig] for [project] and [project.example] (if it + /// exists). + /// + /// This should be called after pub invocations that are expected to update + /// the packageConfig. + Future _updateVersionAndPackageConfig(FlutterProject project) async { + if (!project.packageConfigFile.existsSync()) { + throwToolExit('${project.directory}: pub did not create .dart_tools/package_config.json file.'); + } + final File lastVersion = _fileSystem.file( + _fileSystem.path.join(project.directory.path, '.dart_tool', 'version'), + ); + final File currentVersion = _fileSystem.file( + _fileSystem.path.join(Cache.flutterRoot!, 'version')); + lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); + + await _updatePackageConfig(project); + if (project.hasExampleApp && project.example.pubspecFile.existsSync()) { + await _updatePackageConfig(project.example); + } + } + + /// Update the package configuration file in [project]. /// - /// Creates a corresponding `package_config_subset` file that is used by the build - /// system to avoid rebuilds caused by an updated pub timestamp. + /// Creates a corresponding `package_config_subset` file that is used by the + /// build system to avoid rebuilds caused by an updated pub timestamp. /// - /// if [generateSyntheticPackage] is true then insert flutter_gen synthetic - /// package into the package configuration. This is used by the l10n localization - /// tooling to insert a new reference into the package_config file, allowing the import - /// of a package URI that is not specified in the pubspec.yaml + /// if `project.generateSyntheticPackage` is `true` then insert flutter_gen + /// synthetic package into the package configuration. This is used by the l10n + /// localization tooling to insert a new reference into the package_config + /// file, allowing the import of a package URI that is not specified in the + /// pubspec.yaml /// /// For more information, see: /// * [generateLocalizations], `in lib/src/localizations/gen_l10n.dart` - Future _updatePackageConfig( - File packageConfigFile, - Directory generatedDirectory, - bool generateSyntheticPackage, - ) async { + Future _updatePackageConfig(FlutterProject project) async { + final File packageConfigFile = project.packageConfigFile; final PackageConfig packageConfig = await loadPackageConfigWithLogging(packageConfigFile, logger: _logger); packageConfigFile.parent @@ -792,7 +760,7 @@ class _DefaultPub implements Pub { _fileSystem, )); - if (!generateSyntheticPackage) { + if (!project.manifest.generateSyntheticPackage) { return; } if (packageConfig.packages.any((Package package) => package.name == 'flutter_gen')) { diff --git a/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart index 9c419c3567f4..4a617ff70e12 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart @@ -29,7 +29,6 @@ class FakePub extends Fake implements Pub { Future get({ PubContext? context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, diff --git a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart index 6e10ff510afa..a7445131369d 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart @@ -480,7 +480,6 @@ class FakePub extends Fake implements Pub { Future get({ PubContext? context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, diff --git a/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart index e8b9db01ac26..4ab290199c6d 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart @@ -35,7 +35,7 @@ void main() { fileSystem.currentDirectory.childFile('.flutter-plugins').createSync(); fileSystem.currentDirectory.childFile('.flutter-plugins-dependencies').createSync(); - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); await commandRunner.run(['get']); @@ -60,7 +60,7 @@ void main() { ..createSync(recursive: true) ..writeAsBytesSync([0]); - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); await commandRunner.run(['get']); @@ -81,7 +81,7 @@ void main() { final Directory targetDirectory = fileSystem.currentDirectory.childDirectory('target'); targetDirectory.childFile('pubspec.yaml').createSync(); - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); await commandRunner.run(['get', targetDirectory.path]); @@ -98,7 +98,7 @@ void main() { fileSystem.currentDirectory.childFile('pubspec.yaml').createSync(); fileSystem.currentDirectory.childDirectory('example').createSync(recursive: true); - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); await commandRunner.run(['get']); @@ -115,7 +115,7 @@ void main() { }); testUsingContext('pub get throws error on missing directory', () async { - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); try { @@ -159,7 +159,7 @@ void main() { ''' ); - final PackagesGetCommand command = PackagesGetCommand('get', false); + final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); await commandRunner.run(['get']); @@ -183,23 +183,21 @@ class FakePub extends Fake implements Pub { final FileSystem fileSystem; @override - Future get({ + Future interactively( + List arguments, { + FlutterProject? project, required PubContext context, - required FlutterProject project, - bool skipIfAbsent = false, - bool upgrade = false, - bool offline = false, + required String command, + bool touchesPackageConfig = false, bool generateSyntheticPackage = false, - bool generateSyntheticPackageForExample = false, - String? flutterRootOverride, - bool checkUpToDate = false, - bool shouldSkipThirdPartyGenerator = true, bool printProgress = true, }) async { - fileSystem.directory(project.directory) - .childDirectory('.dart_tool') - .childFile('package_config.json') - ..createSync(recursive: true) - ..writeAsStringSync('{"configVersion":2,"packages":[]}'); + if (project != null) { + fileSystem.directory(project.directory) + .childDirectory('.dart_tool') + .childFile('package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync('{"configVersion":2,"packages":[]}'); + } } } diff --git a/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart index 1456bacc1ca1..56b9fa0d7a12 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart @@ -275,7 +275,6 @@ class FakePub extends Fake implements Pub { Future get({ required PubContext context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, diff --git a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart index c96b1474e7c4..4bd4f811aace 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart @@ -72,6 +72,7 @@ void main() { 'packages', verb, ...?args, + '--directory', projectPath, ]); return command; diff --git a/packages/flutter_tools/test/general.shard/cache_test.dart b/packages/flutter_tools/test/general.shard/cache_test.dart index 9ae86725b343..de4229c2d59c 100644 --- a/packages/flutter_tools/test/general.shard/cache_test.dart +++ b/packages/flutter_tools/test/general.shard/cache_test.dart @@ -1208,7 +1208,6 @@ class FakePub extends Fake implements Pub { Future get({ PubContext? context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, diff --git a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart index d3a8bc50068c..173a1a7b50eb 100644 --- a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart +++ b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart @@ -557,7 +557,7 @@ exit code: 66 ), throwsA(isA().having((ToolExit error) => error.message, 'message', toolExitMessage)), ); - expect(logger.statusText, 'Running "flutter pub get" in /...\n'); + expect(logger.statusText, isEmpty); expect( mockStdio.stdout.writes.map(utf8.decode), [ @@ -634,9 +634,7 @@ exit code: 66 ), ), ); - expect(logger.statusText, - 'Running "flutter pub get" in /...\n' - ); + expect(logger.statusText, isEmpty); expect(logger.errorText, isEmpty); expect(processManager, hasNoRemainingExpectations); }); @@ -1074,7 +1072,6 @@ exit code: 66 context: PubContext.flutterTests, ); // pub sets date of .packages to 2002 - expect(logger.statusText, 'Running "flutter pub get" in /...\n'); expect(logger.errorText, isEmpty); expect(fileSystem.file('pubspec.yaml').lastModifiedSync(), DateTime(2001)); // because nothing should touch it logger.clear(); @@ -1089,7 +1086,7 @@ exit code: 66 context: PubContext.flutterTests, ); // pub does nothing - expect(logger.statusText, 'Running "flutter pub get" in /...\n'); + expect(logger.statusText, isEmpty); expect(logger.errorText, isEmpty); expect(fileSystem.file('pubspec.yaml').lastModifiedSync(), DateTime(2001)); // because nothing should touch it logger.clear(); diff --git a/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart b/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart index 765773ed9dd4..4f5d774a6d42 100644 --- a/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart +++ b/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart @@ -951,7 +951,6 @@ class FakePub extends Fake implements Pub { Future get({ required PubContext context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, String? flutterRootOverride, diff --git a/packages/flutter_tools/test/src/fake_process_manager.dart b/packages/flutter_tools/test/src/fake_process_manager.dart index fb87570c873c..e0fc5102db67 100644 --- a/packages/flutter_tools/test/src/fake_process_manager.dart +++ b/packages/flutter_tools/test/src/fake_process_manager.dart @@ -110,15 +110,8 @@ class FakeCommand { Map? environment, Encoding? encoding, ) { - expect(command.length, this.command.length); - for(int i = 0; i < command.length; i++) { - final Pattern expected = this.command[i]; - if (expected is String) { - expect(command[i], expected); - } else { - expect(command[i], matches(this.command[i])); - } - } + final List matchers = this.command.map((Pattern x) => x is String ? x : matches(x)).toList(); + expect(command, matchers); if (this.workingDirectory != null) { expect(this.workingDirectory, workingDirectory); } diff --git a/packages/flutter_tools/test/src/throwing_pub.dart b/packages/flutter_tools/test/src/throwing_pub.dart index c00a7f12d5d9..a96d13375ab0 100644 --- a/packages/flutter_tools/test/src/throwing_pub.dart +++ b/packages/flutter_tools/test/src/throwing_pub.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/project.dart'; @@ -21,7 +20,6 @@ class ThrowingPub implements Pub { Future get({ PubContext? context, required FlutterProject project, - bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool checkLastModified = true, @@ -39,10 +37,12 @@ class ThrowingPub implements Pub { @override Future interactively( List arguments, { - String? directory, - required Stdio stdio, + FlutterProject? project, + required PubContext context, + required String command, bool touchesPackageConfig = false, bool generateSyntheticPackage = false, + bool printProgress = true, }) { throw UnsupportedError('Attempted to invoke pub during test.'); }