From d80e994a62536826b6174337c0af7960959dec0a Mon Sep 17 00:00:00 2001 From: Sigurd Meldgaard Date: Thu, 8 Sep 2022 15:13:23 +0200 Subject: [PATCH] Reland: Show output from pub get in flutter pub get (#110851) --- dev/bots/analyze_snippet_code.dart | 9 +- .../lib/tasks/web_dev_mode_tests.dart | 3 +- .../lib/src/commands/create.dart | 94 ++++--- .../lib/src/commands/create_base.dart | 19 -- .../lib/src/commands/daemon.dart | 2 +- .../lib/src/commands/packages.dart | 12 +- .../lib/src/commands/update_packages.dart | 6 +- .../lib/src/commands/upgrade.dart | 3 +- .../flutter_tools/lib/src/context_runner.dart | 2 + packages/flutter_tools/lib/src/dart/pub.dart | 256 ++++++++++++------ .../flutter_tools/lib/src/flutter_cache.dart | 10 +- .../lib/src/runner/flutter_command.dart | 2 +- .../hermetic/analyze_continuously_test.dart | 10 +- .../hermetic/create_usage_test.dart | 6 +- .../commands.shard/hermetic/drive_test.dart | 2 +- .../commands.shard/hermetic/pub_get_test.dart | 5 +- .../hermetic/update_packages_test.dart | 12 +- .../permeable/build_aar_test.dart | 2 +- .../commands.shard/permeable/create_test.dart | 27 +- .../commands.shard/permeable/format_test.dart | 6 + .../permeable/packages_test.dart | 44 ++- .../test/general.shard/cache_test.dart | 5 +- .../test/general.shard/dart/pub_get_test.dart | 243 ++++++++++++----- .../runner/flutter_command_test.dart | 4 +- .../web_plugin_registrant_test.dart | 5 + packages/flutter_tools/test/src/fakes.dart | 11 + .../test/src/test_flutter_command_runner.dart | 2 +- .../flutter_tools/test/src/throwing_pub.dart | 6 +- 28 files changed, 558 insertions(+), 250 deletions(-) diff --git a/dev/bots/analyze_snippet_code.dart b/dev/bots/analyze_snippet_code.dart index 1fce5f60ae..3a1ed07d8a 100644 --- a/dev/bots/analyze_snippet_code.dart +++ b/dev/bots/analyze_snippet_code.dart @@ -980,6 +980,13 @@ class _SnippetChecker { /// Invokes the analyzer on the given [directory] and returns the stdout (with some lines filtered). List _runAnalyzer() { _createConfigurationFiles(); + // Run pub get to avoid output from getting dependencies in the analyzer + // output. + Process.runSync( + _flutter, + ['pub', 'get'], + workingDirectory: _tempDirectory.absolute.path, + ); final ProcessResult result = Process.runSync( _flutter, ['--no-wrap', 'analyze', '--no-preamble', '--no-congratulate', '.'], @@ -1006,7 +1013,7 @@ class _SnippetChecker { if (stdout.isNotEmpty && stdout.first == 'Building flutter tool...') { stdout.removeAt(0); } - if (stdout.isNotEmpty && stdout.first.startsWith('Running "flutter pub get" in ')) { + if (stdout.isNotEmpty && stdout.first.isEmpty) { stdout.removeAt(0); } return stdout; diff --git a/dev/devicelab/lib/tasks/web_dev_mode_tests.dart b/dev/devicelab/lib/tasks/web_dev_mode_tests.dart index 0fc6a52e91..477b423a92 100644 --- a/dev/devicelab/lib/tasks/web_dev_mode_tests.dart +++ b/dev/devicelab/lib/tasks/web_dev_mode_tests.dart @@ -42,11 +42,10 @@ TaskFunction createWebDevModeTest(String webDevice, bool enableIncrementalCompil recursiveCopy(flutterGalleryDir, _editedFlutterGalleryDir); await inDirectory(_editedFlutterGalleryDir, () async { { - final Process packagesGet = await startProcess( + await exec( path.join(flutterDirectory.path, 'bin', 'flutter'), ['packages', 'get'], ); - await packagesGet.exitCode; final Process process = await startProcess( path.join(flutterDirectory.path, 'bin', 'flutter'), flutterCommandArgs('run', options), diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart index b999ea482b..e80f477c3a 100644 --- a/packages/flutter_tools/lib/src/commands/create.dart +++ b/packages/flutter_tools/lib/src/commands/create.dart @@ -192,7 +192,6 @@ class CreateCommand extends CreateBase { } validateOutputDirectoryArg(); - String? sampleCode; final String? sampleArgument = stringArg('sample'); if (sampleArgument != null) { @@ -255,7 +254,29 @@ class CreateCommand extends CreateBase { } final String dartSdk = globals.cache.dartSdkBuild; - final bool includeIos = featureFlags.isIOSEnabled && platforms.contains('ios'); + final bool includeIos; + final bool includeAndroid; + final bool includeWeb; + final bool includeLinux; + final bool includeMacos; + final bool includeWindows; + if (template == FlutterProjectType.module) { + // The module template only supports iOS and Android. + includeIos = true; + includeAndroid = true; + includeWeb = false; + includeLinux = false; + includeMacos = false; + includeWindows = false; + } else { + includeIos = featureFlags.isIOSEnabled && platforms.contains('ios'); + includeAndroid = featureFlags.isAndroidEnabled && platforms.contains('android'); + includeWeb = featureFlags.isWebEnabled && platforms.contains('web'); + includeLinux = featureFlags.isLinuxEnabled && platforms.contains('linux'); + includeMacos = featureFlags.isMacOSEnabled && platforms.contains('macos'); + includeWindows = featureFlags.isWindowsEnabled && platforms.contains('windows'); + } + String? developmentTeam; if (includeIos) { developmentTeam = await getCodeSigningIdentityDevelopmentTeam( @@ -282,11 +303,11 @@ class CreateCommand extends CreateBase { iosLanguage: stringArgDeprecated('ios-language'), iosDevelopmentTeam: developmentTeam, ios: includeIos, - android: featureFlags.isAndroidEnabled && platforms.contains('android'), - web: featureFlags.isWebEnabled && platforms.contains('web'), - linux: featureFlags.isLinuxEnabled && platforms.contains('linux'), - macos: featureFlags.isMacOSEnabled && platforms.contains('macos'), - windows: featureFlags.isWindowsEnabled && platforms.contains('windows'), + android: includeAndroid, + web: includeWeb, + linux: includeLinux, + macos: includeMacos, + windows: includeWindows, // Enable null safety everywhere. dartSdkVersionBounds: "'>=$dartSdk <3.0.0'", implementationTests: boolArgDeprecated('implementation-tests'), @@ -309,6 +330,7 @@ class CreateCommand extends CreateBase { final Directory relativeDir = globals.fs.directory(projectDirPath); int generatedFileCount = 0; + final PubContext pubContext; switch (template) { case FlutterProjectType.app: generatedFileCount += await generateApp( @@ -319,6 +341,7 @@ class CreateCommand extends CreateBase { printStatusWhenWriting: !creatingNewProject, projectType: template, ); + pubContext = PubContext.create; break; case FlutterProjectType.skeleton: generatedFileCount += await generateApp( @@ -329,6 +352,7 @@ class CreateCommand extends CreateBase { printStatusWhenWriting: !creatingNewProject, generateMetadata: false, ); + pubContext = PubContext.create; break; case FlutterProjectType.module: generatedFileCount += await _generateModule( @@ -337,6 +361,7 @@ class CreateCommand extends CreateBase { overwrite: overwrite, printStatusWhenWriting: !creatingNewProject, ); + pubContext = PubContext.create; break; case FlutterProjectType.package: generatedFileCount += await _generatePackage( @@ -345,6 +370,7 @@ class CreateCommand extends CreateBase { overwrite: overwrite, printStatusWhenWriting: !creatingNewProject, ); + pubContext = PubContext.createPackage; break; case FlutterProjectType.plugin: generatedFileCount += await _generateMethodChannelPlugin( @@ -354,6 +380,7 @@ class CreateCommand extends CreateBase { printStatusWhenWriting: !creatingNewProject, projectType: template, ); + pubContext = PubContext.createPlugin; break; case FlutterProjectType.ffiPlugin: generatedFileCount += await _generateFfiPlugin( @@ -363,8 +390,26 @@ class CreateCommand extends CreateBase { printStatusWhenWriting: !creatingNewProject, projectType: template, ); + pubContext = PubContext.createPlugin; break; } + + if (boolArgDeprecated('pub')) { + final FlutterProject project = FlutterProject.fromDirectory(relativeDir); + await pub.get( + context: pubContext, + project: project, + offline: boolArgDeprecated('offline'), + ); + await project.ensureReadyForPlatformSpecificTooling( + androidPlatform: includeAndroid, + iosPlatform: includeIos, + linuxPlatform: includeLinux, + macOSPlatform: includeMacos, + windowsPlatform: includeWindows, + webPlatform: includeWeb, + ); + } if (sampleCode != null) { generatedFileCount += _applySample(relativeDir, sampleCode); } @@ -447,18 +492,6 @@ Your $application code is in $relativeAppMain. overwrite: overwrite, printStatusWhenWriting: printStatusWhenWriting, ); - if (boolArgDeprecated('pub')) { - await pub.get( - context: PubContext.create, - directory: directory.path, - offline: boolArgDeprecated('offline'), - ); - final FlutterProject project = FlutterProject.fromDirectory(directory); - await project.ensureReadyForPlatformSpecificTooling( - androidPlatform: true, - iosPlatform: true, - ); - } return generatedCount; } @@ -480,13 +513,6 @@ Your $application code is in $relativeAppMain. overwrite: overwrite, printStatusWhenWriting: printStatusWhenWriting, ); - if (boolArgDeprecated('pub')) { - await pub.get( - context: PubContext.createPackage, - directory: directory.path, - offline: boolArgDeprecated('offline'), - ); - } return generatedCount; } @@ -526,14 +552,6 @@ Your $application code is in $relativeAppMain. printStatusWhenWriting: printStatusWhenWriting, ); - if (boolArgDeprecated('pub')) { - await pub.get( - context: PubContext.createPlugin, - directory: directory.path, - offline: boolArgDeprecated('offline'), - ); - } - final FlutterProject project = FlutterProject.fromDirectory(directory); final bool generateAndroid = templateContext['android'] == true; if (generateAndroid) { @@ -604,14 +622,6 @@ Your $application code is in $relativeAppMain. printStatusWhenWriting: printStatusWhenWriting, ); - if (boolArgDeprecated('pub')) { - await pub.get( - context: PubContext.createPlugin, - directory: directory.path, - offline: boolArgDeprecated('offline'), - ); - } - final FlutterProject project = FlutterProject.fromDirectory(directory); final bool generateAndroid = templateContext['android'] == true; if (generateAndroid) { diff --git a/packages/flutter_tools/lib/src/commands/create_base.dart b/packages/flutter_tools/lib/src/commands/create_base.dart index a131d6cd11..2f11b87b4f 100644 --- a/packages/flutter_tools/lib/src/commands/create_base.dart +++ b/packages/flutter_tools/lib/src/commands/create_base.dart @@ -17,7 +17,6 @@ import '../build_system/build_system.dart'; import '../cache.dart'; import '../convert.dart'; import '../dart/generate_synthetic_packages.dart'; -import '../dart/pub.dart'; import '../flutter_project_metadata.dart'; import '../globals.dart' as globals; import '../project.dart'; @@ -549,24 +548,6 @@ abstract class CreateBase extends FlutterCommand { environment: environment, buildSystem: globals.buildSystem, ); - - await pub.get( - context: PubContext.create, - directory: directory.path, - offline: boolArgDeprecated('offline'), - // For templates that use the l10n localization tooling, make sure - // importing the generated package works right after `flutter create`. - generateSyntheticPackage: true, - ); - - await project.ensureReadyForPlatformSpecificTooling( - androidPlatform: androidPlatform, - iosPlatform: iosPlatform, - linuxPlatform: linuxPlatform, - macOSPlatform: macOSPlatform, - windowsPlatform: windowsPlatform, - webPlatform: webPlatform, - ); } final List platformsForMigrateConfig = [SupportedPlatform.root]; if (androidPlatform) { diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart index 5b1d8f4ebd..3e3f9ccb97 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart @@ -1541,7 +1541,7 @@ class AppRunLogger extends DelegatingLogger { } @override - bool get supportsColor => throw UnimplementedError(); + bool get supportsColor => false; @override bool get hasTerminal => false; diff --git a/packages/flutter_tools/lib/src/commands/packages.dart b/packages/flutter_tools/lib/src/commands/packages.dart index f360cc5f87..14503a03b2 100644 --- a/packages/flutter_tools/lib/src/commands/packages.dart +++ b/packages/flutter_tools/lib/src/commands/packages.dart @@ -139,11 +139,10 @@ class PackagesGetCommand extends FlutterCommand { try { await pub.get( context: PubContext.pubGet, - directory: directory, + project: flutterProject, upgrade: upgrade, shouldSkipThirdPartyGenerator: false, offline: boolArgDeprecated('offline'), - generateSyntheticPackage: flutterProject.manifest.generateSyntheticPackage, ); pubGetTimer.stop(); globals.flutterUsage.sendTiming('pub', 'get', pubGetTimer.elapsed, label: 'success'); @@ -172,13 +171,14 @@ class PackagesGetCommand extends FlutterCommand { } final FlutterProject rootProject = FlutterProject.fromDirectory(globals.fs.directory(target)); + // This will also resolve dependencies for the example folder, await _runPubGet(target, rootProject); - await rootProject.regeneratePlatformSpecificTooling(); - // Get/upgrade packages in example app as well + // 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 _runPubGet(exampleProject.directory.path, exampleProject); await exampleProject.regeneratePlatformSpecificTooling(); } @@ -211,7 +211,7 @@ class PackagesTestCommand extends FlutterCommand { @override Future runCommand() async { - await pub.batch(['run', 'test', ...argResults!.rest], context: PubContext.runTest, retry: false); + await pub.batch(['run', 'test', ...argResults!.rest], context: PubContext.runTest); return FlutterCommandResult.success(); } } diff --git a/packages/flutter_tools/lib/src/commands/update_packages.dart b/packages/flutter_tools/lib/src/commands/update_packages.dart index dbef897c97..ef70ceeef1 100644 --- a/packages/flutter_tools/lib/src/commands/update_packages.dart +++ b/packages/flutter_tools/lib/src/commands/update_packages.dart @@ -16,6 +16,7 @@ import '../base/task_queue.dart'; import '../cache.dart'; import '../dart/pub.dart'; import '../globals.dart' as globals; +import '../project.dart'; import '../runner/flutter_command.dart'; /// Map from package name to package version, used to artificially pin a pub @@ -399,7 +400,7 @@ class UpdatePackagesCommand extends FlutterCommand { // needed packages to the pub cache, upgrading if requested. await pub.get( context: PubContext.updatePackages, - directory: tempDir.path, + project: FlutterProject.fromDirectory(tempDir), upgrade: doUpgrade, offline: boolArgDeprecated('offline'), flutterRootOverride: temporaryFlutterSdk?.path, @@ -422,7 +423,6 @@ class UpdatePackagesCommand extends FlutterCommand { context: PubContext.updatePackages, directory: tempDir.path, filter: tree.fill, - retry: false, // errors here are usually fatal since we're not hitting the network ); } } finally { @@ -502,7 +502,7 @@ class UpdatePackagesCommand extends FlutterCommand { stopwatch.start(); await pub.get( context: PubContext.updatePackages, - directory: dir.path, + project: FlutterProject.fromDirectory(dir), // All dependencies should already have been downloaded by the fake // package, so the concurrent checks can all happen offline. offline: true, diff --git a/packages/flutter_tools/lib/src/commands/upgrade.dart b/packages/flutter_tools/lib/src/commands/upgrade.dart index 446fdb2724..158597cac9 100644 --- a/packages/flutter_tools/lib/src/commands/upgrade.dart +++ b/packages/flutter_tools/lib/src/commands/upgrade.dart @@ -12,6 +12,7 @@ import '../cache.dart'; import '../dart/pub.dart'; import '../globals.dart' as globals; import '../persistent_tool_state.dart'; +import '../project.dart'; import '../runner/flutter_command.dart'; import '../version.dart'; import 'channel.dart'; @@ -330,7 +331,7 @@ class UpgradeCommandRunner { globals.printStatus(''); await pub.get( context: PubContext.pubUpgrade, - directory: projectRoot, + project: FlutterProject.fromDirectory(globals.fs.directory(projectRoot)), upgrade: true, ); } diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart index ca5369c55d..020efc5f7e 100644 --- a/packages/flutter_tools/lib/src/context_runner.dart +++ b/packages/flutter_tools/lib/src/context_runner.dart @@ -152,6 +152,7 @@ Future runInContext( logger: globals.logger, platform: globals.platform, osUtils: globals.os, + projectFactory: globals.projectFactory, ), CocoaPods: () => CocoaPods( fileSystem: globals.fs, @@ -312,6 +313,7 @@ Future runInContext( botDetector: globals.botDetector, platform: globals.platform, usage: globals.flutterUsage, + stdio: globals.stdio, ), Stdio: () => Stdio(), SystemClock: () => const SystemClock(), diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart index c784f85cf0..f64249d083 100644 --- a/packages/flutter_tools/lib/src/dart/pub.dart +++ b/packages/flutter_tools/lib/src/dart/pub.dart @@ -12,12 +12,14 @@ import '../base/common.dart'; import '../base/context.dart'; import '../base/file_system.dart'; import '../base/io.dart' as io; +import '../base/io.dart'; import '../base/logger.dart'; import '../base/platform.dart'; import '../base/process.dart'; import '../cache.dart'; import '../convert.dart'; import '../dart/package_map.dart'; +import '../project.dart'; import '../reporting/reporting.dart'; /// The [Pub] instance. @@ -148,9 +150,10 @@ abstract class Pub { required Platform platform, required BotDetector botDetector, required Usage usage, + required Stdio stdio, }) = _DefaultPub; - /// Runs `pub get`. + /// Runs `pub get` or `pub upgrade` for [project]. /// /// [context] provides extra information to package server requests to /// understand usage. @@ -158,13 +161,13 @@ abstract class Pub { /// If [shouldSkipThirdPartyGenerator] is true, the overall pub get will be /// skipped if the package config file has a "generator" other than "pub". /// Defaults to true. + /// Will also resolve dependencies in the example folder if present. Future get({ required PubContext context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, - bool generateSyntheticPackage = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, @@ -177,9 +180,8 @@ abstract class Pub { /// the corresponding stream of this process, optionally applying filtering. /// The pub process will not receive anything on its stdin stream. /// - /// The `--trace` argument is passed to `pub` (by mutating the provided - /// `arguments` list) when `showTraceForErrors` is true, and when `showTraceForErrors` - /// is null/unset, and `isRunningOnBot` is true. + /// The `--trace` argument is passed to `pub` when `showTraceForErrors` + /// `isRunningOnBot` is true. /// /// [context] provides extra information to package server requests to /// understand usage. @@ -189,8 +191,6 @@ abstract class Pub { String? directory, MessageFilter? filter, String failureMessage = 'pub failed', - required bool retry, - bool? showTraceForErrors, }); /// Runs pub in 'interactive' mode. @@ -214,6 +214,7 @@ class _DefaultPub implements Pub { required Platform platform, required BotDetector botDetector, required Usage usage, + required Stdio stdio, }) : _fileSystem = fileSystem, _logger = logger, _platform = platform, @@ -223,7 +224,8 @@ class _DefaultPub implements Pub { logger: logger, processManager: processManager, ), - _processManager = processManager; + _processManager = processManager, + _stdio = stdio; final FileSystem _fileSystem; final Logger _logger; @@ -232,40 +234,40 @@ class _DefaultPub implements Pub { final BotDetector _botDetector; final Usage _usage; final ProcessManager _processManager; + final Stdio _stdio; @override Future get({ required PubContext context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, + bool generateSyntheticPackageForExample = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, bool printProgress = true, }) async { - directory ??= _fileSystem.currentDirectory.path; - final File packageConfigFile = _fileSystem.file( - _fileSystem.path.join(directory, '.dart_tool', 'package_config.json')); + 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( _fileSystem.path.join(Cache.flutterRoot!, 'version')); - final File pubspecYaml = _fileSystem.file( - _fileSystem.path.join(directory, 'pubspec.yaml')); + final File pubspecYaml = project.pubspecFile; final File pubLockFile = _fileSystem.file( _fileSystem.path.join(directory, 'pubspec.lock') ); - if (shouldSkipThirdPartyGenerator && packageConfigFile.existsSync()) { + if (shouldSkipThirdPartyGenerator && project.packageConfigFile.existsSync()) { Map packageConfigMap; try { packageConfigMap = jsonDecode( - packageConfigFile.readAsStringSync(), + project.packageConfigFile.readAsStringSync(), ) as Map; } on FormatException { packageConfigMap = {}; @@ -298,31 +300,118 @@ class _DefaultPub implements Pub { } final String command = upgrade ? 'upgrade' : 'get'; - final Status? status = printProgress ? _logger.startProgress( - 'Running "flutter pub $command" in ${_fileSystem.path.basename(directory)}...', - ) : null; final bool verbose = _logger.isVerbose; final List args = [ + if (_logger.supportsColor) + '--color', if (verbose) - '--verbose' - else - '--verbosity=warning', + '--verbose', + '--directory', + _fileSystem.path.relative(directory), ...[ command, - '--no-precompile', ], if (offline) '--offline', + '--example', ]; - try { - await batch( - args, - context: context, - directory: directory, - failureMessage: 'pub $command failed', - retry: !offline, - flutterRootOverride: flutterRootOverride, + await _runWithRetries( + args, + command: command, + context: context, + directory: directory, + failureMessage: 'pub $command failed', + retry: !offline, + 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, ); + } + } + + /// Runs pub with [arguments]. + /// + /// Retries the command as long as the exit code is + /// `_kPubExitCodeUnavailable`. + /// + /// Prints the stderr and stdout of the last run. + /// + /// Sends an analytics event + Future _runWithRetries( + List arguments, { + required String command, + required bool printProgress, + required PubContext context, + required bool retry, + required String directory, + String failureMessage = 'pub failed', + String? flutterRootOverride, + }) async { + int exitCode; + int attempts = 0; + int duration = 1; + + List<_OutputLine>? output; + StreamSubscription recordLines(Stream> stream, _OutputStream streamName) { + return stream + .transform(utf8.decoder) + .transform(const LineSplitter()) + .listen((String line) => output!.add(_OutputLine(line, streamName))); + } + + final Status? status = printProgress + ? _logger.startProgress('Running "flutter pub $command" in ${_fileSystem.path.basename(directory)}...',) + : null; + final List pubCommand = _pubCommand(arguments); + final Map pubEnvironment = await _createPubEnvironment(context, flutterRootOverride); + try { + do { + output = <_OutputLine>[]; + attempts += 1; + final io.Process process = await _processUtils.start( + pubCommand, + workingDirectory: _fileSystem.path.current, + environment: pubEnvironment, + ); + final StreamSubscription stdoutSubscription = + recordLines(process.stdout, _OutputStream.stdout); + final StreamSubscription stderrSubscription = + recordLines(process.stderr, _OutputStream.stderr); + + exitCode = await process.exitCode; + unawaited(stdoutSubscription.cancel()); + unawaited(stderrSubscription.cancel()); + + if (retry && exitCode == _kPubExitCodeUnavailable) { + _logger.printStatus( + '$failureMessage (server unavailable) -- attempting retry $attempts in $duration ' + 'second${ duration == 1 ? "" : "s"}...', + ); + await Future.delayed(Duration(seconds: duration)); + if (duration < 64) { + duration *= 2; + } + // This will cause a retry. + output = null; + } + } while (output == null); status?.stop(); // The exception is rethrown, so don't catch only Exceptions. } catch (exception) { // ignore: avoid_catches_without_on_clauses @@ -342,15 +431,45 @@ class _DefaultPub implements Pub { rethrow; } - if (!packageConfigFile.existsSync()) { - throwToolExit('$directory: pub did not create .dart_tools/package_config.json file.'); + if (printProgress) { + // Show the output of the last run. + for (final _OutputLine line in output) { + switch (line.stream) { + case _OutputStream.stdout: + _stdio.stdoutWrite('${line.line}\n'); + break; + case _OutputStream.stderr: + _stdio.stderrWrite('${line.line}\n'); + break; + } + } + } + + final int code = exitCode; + String result = 'success'; + if (output.any((_OutputLine line) => line.line.contains('version solving failed'))) { + result = 'version-solving-failed'; + } else if (code != 0) { + result = 'failure'; + } + PubResultEvent( + context: context.toAnalyticsString(), + result: result, + usage: _usage, + ).send(); + final String lastPubMessage = output.isEmpty ? 'no message' : output.last.line; + + if (code != 0) { + final StringBuffer buffer = StringBuffer('$failureMessage\n'); + buffer.writeln('command: "${pubCommand.join(' ')}"'); + buffer.write(_stringifyPubEnv(pubEnvironment)); + buffer.writeln('exit code: $code'); + buffer.writeln('last line of pub output: "${lastPubMessage.trim()}"'); + throwToolExit( + buffer.toString(), + exitCode: code, + ); } - lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); - await _updatePackageConfig( - packageConfigFile, - generatedDirectory, - generateSyntheticPackage, - ); } // For surfacing pub env in crash reporting @@ -374,19 +493,13 @@ class _DefaultPub implements Pub { String? directory, MessageFilter? filter, String failureMessage = 'pub failed', - required bool retry, - bool? showTraceForErrors, String? flutterRootOverride, }) async { - showTraceForErrors ??= await _botDetector.isRunningOnBot; + final bool showTraceForErrors = await _botDetector.isRunningOnBot; String lastPubMessage = 'no message'; - bool versionSolvingFailed = false; String? filterWrapper(String line) { lastPubMessage = line; - if (line.contains('version solving failed')) { - versionSolvingFailed = true; - } if (filter == null) { return line; } @@ -396,44 +509,17 @@ class _DefaultPub implements Pub { if (showTraceForErrors) { arguments.insert(0, '--trace'); } - int attempts = 0; - int duration = 1; - int code; - final List pubCommand = _pubCommand(arguments); final Map pubEnvironment = await _createPubEnvironment(context, flutterRootOverride); - while (true) { - attempts += 1; - code = await _processUtils.stream( + final List pubCommand = _pubCommand(arguments); + final int code = await _processUtils.stream( pubCommand, workingDirectory: directory, mapFunction: filterWrapper, // may set versionSolvingFailed, lastPubMessage environment: pubEnvironment, ); - String? message; - if (retry) { - if (code == _kPubExitCodeUnavailable) { - message = 'server unavailable'; - } - } - if (message == null) { - break; - } - versionSolvingFailed = false; - _logger.printStatus( - '$failureMessage ($message) -- attempting retry $attempts in $duration ' - 'second${ duration == 1 ? "" : "s"}...', - ); - await Future.delayed(Duration(seconds: duration)); - if (duration < 64) { - duration *= 2; - } - } - assert(code != null); String result = 'success'; - if (versionSolvingFailed) { - result = 'version-solving-failed'; - } else if (code != 0) { + if (code != 0) { result = 'failure'; } PubResultEvent( @@ -465,7 +551,10 @@ class _DefaultPub implements Pub { }) async { // Fully resolved pub or pub.bat is calculated based on current platform. final io.Process process = await _processUtils.start( - _pubCommand(arguments), + _pubCommand([ + if (_logger.supportsColor) '--color', + ...arguments, + ]), workingDirectory: directory, environment: await _createPubEnvironment(PubContext.interactive), ); @@ -721,3 +810,14 @@ class _DefaultPub implements Pub { return buffer.toString(); } } + +class _OutputLine { + _OutputLine(this.line, this.stream); + final String line; + final _OutputStream stream; +} + +enum _OutputStream { + stdout, + stderr, +} diff --git a/packages/flutter_tools/lib/src/flutter_cache.dart b/packages/flutter_tools/lib/src/flutter_cache.dart index 4ef0ef317d..22609b8d8c 100644 --- a/packages/flutter_tools/lib/src/flutter_cache.dart +++ b/packages/flutter_tools/lib/src/flutter_cache.dart @@ -19,6 +19,7 @@ import 'cache.dart'; import 'dart/package_map.dart'; import 'dart/pub.dart'; import 'globals.dart' as globals; +import 'project.dart'; /// An implementation of the [Cache] which provides all of Flutter's default artifacts. class FlutterCache extends Cache { @@ -29,6 +30,7 @@ class FlutterCache extends Cache { required super.fileSystem, required Platform platform, required super.osUtils, + required FlutterProjectFactory projectFactory, }) : super(logger: logger, platform: platform, artifacts: []) { registerArtifact(MaterialFonts(this)); registerArtifact(GradleWrapper(this)); @@ -54,6 +56,7 @@ class FlutterCache extends Cache { // before the version is determined. flutterRoot: () => Cache.flutterRoot!, pub: () => pub, + projectFactory: projectFactory, )); } } @@ -70,14 +73,17 @@ class PubDependencies extends ArtifactSet { required String Function() flutterRoot, required Logger logger, required Pub Function() pub, + required FlutterProjectFactory projectFactory, }) : _logger = logger, _flutterRoot = flutterRoot, _pub = pub, + _projectFactory = projectFactory, super(DevelopmentArtifact.universal); final String Function() _flutterRoot; final Logger _logger; final Pub Function() _pub; + final FlutterProjectFactory _projectFactory; @override Future isUpToDate( @@ -118,7 +124,9 @@ class PubDependencies extends ArtifactSet { ) async { await _pub().get( context: PubContext.pubGet, - directory: fileSystem.path.join(_flutterRoot(), 'packages', 'flutter_tools'), + project: _projectFactory.fromDirectory( + fileSystem.directory(fileSystem.path.join(_flutterRoot(), 'packages', 'flutter_tools')) + ), offline: offline ); } diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index e4e193db21..41eee55e51 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -1355,7 +1355,7 @@ abstract class FlutterCommand extends Command { await pub.get( context: PubContext.getVerifyContext(name), - generateSyntheticPackage: project.manifest.generateSyntheticPackage, + project: project, checkUpToDate: cachePubGet, ); await project.regeneratePlatformSpecificTooling(); diff --git a/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart index 2322d70d26..8ab74392f7 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart @@ -17,12 +17,14 @@ import 'package:flutter_tools/src/commands/analyze.dart'; import 'package:flutter_tools/src/dart/analysis.dart'; import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/globals.dart' as globals; +import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project_validator.dart'; import 'package:process/process.dart'; import '../../src/common.dart'; import '../../src/context.dart'; import '../../src/fake_process_manager.dart'; +import '../../src/fakes.dart'; import '../../src/test_flutter_command_runner.dart'; void main() { @@ -36,6 +38,7 @@ void main() { late ProcessManager processManager; late AnsiTerminal terminal; late Logger logger; + late FakeStdio mockStdio; setUp(() { fileSystem = globals.localFileSystem; @@ -44,6 +47,7 @@ void main() { terminal = AnsiTerminal(platform: platform, stdio: Stdio()); logger = BufferLogger(outputPreferences: OutputPreferences.test(), terminal: terminal); tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_analysis_test.'); + mockStdio = FakeStdio(); }); tearDown(() { @@ -80,10 +84,11 @@ void main() { platform: const LocalPlatform(), botDetector: globals.botDetector, usage: globals.flutterUsage, + stdio: mockStdio, ); await pub.get( context: PubContext.flutterTests, - directory: tempDir.path, + project: FlutterProject.fromDirectoryTest(tempDir), ); final AnalysisServer server = AnalysisServer( @@ -119,10 +124,11 @@ void main() { platform: const LocalPlatform(), usage: globals.flutterUsage, botDetector: globals.botDetector, + stdio: mockStdio, ); await pub.get( context: PubContext.flutterTests, - directory: tempDir.path, + project: FlutterProject.fromDirectoryTest(tempDir), ); final AnalysisServer server = AnalysisServer( 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 6cc52e3230..86ebe770ea 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 @@ -11,6 +11,7 @@ import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/doctor.dart'; import 'package:flutter_tools/src/doctor_validator.dart'; import 'package:flutter_tools/src/globals.dart' as globals; +import 'package:flutter_tools/src/project.dart'; import 'package:test/fake.dart'; import '../../src/context.dart'; @@ -27,17 +28,18 @@ class FakePub extends Fake implements Pub { @override Future get({ PubContext? context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, + bool generateSyntheticPackageForExample = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, bool printProgress = true, }) async { - fs.directory(directory).childFile('.packages').createSync(); + project.directory.childFile('.packages').createSync(); if (offline == true) { calledGetOffline += 1; } else { 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 397b4a666c..966d552503 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart @@ -306,7 +306,7 @@ class FakePub extends Fake implements Pub { @override Future get({ PubContext? context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = 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 080fa54e79..6861f22253 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 @@ -169,17 +169,18 @@ class FakePub extends Fake implements Pub { @override Future get({ required PubContext context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, + bool generateSyntheticPackageForExample = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, bool printProgress = true, }) async { - fileSystem.directory(directory) + fileSystem.directory(project.directory) .childDirectory('.dart_tool') .childFile('package_config.json') ..createSync(recursive: true) 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 2d947bc5c1..92d4f597c5 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 @@ -8,6 +8,7 @@ import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/commands/update_packages.dart'; import 'package:flutter_tools/src/dart/pub.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:test/fake.dart'; import 'package:yaml/yaml.dart'; @@ -223,20 +224,19 @@ class FakePub extends Fake implements Pub { @override Future get({ required PubContext context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, + bool generateSyntheticPackageForExample = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, bool printProgress = true, }) async { - if (directory != null) { - pubGetDirectories.add(directory); - } - fileSystem.directory(directory).childFile('pubspec.lock') + pubGetDirectories.add(project.directory.path); + project.directory.childFile('pubspec.lock') ..createSync(recursive: true) ..writeAsStringSync(''' # Generated by pub @@ -266,8 +266,6 @@ sdks: String? directory, MessageFilter? filter, String failureMessage = 'pub failed', - required bool retry, - bool? showTraceForErrors, }) async { if (directory != null) { pubBatchDirectories.add(directory); diff --git a/packages/flutter_tools/test/commands.shard/permeable/build_aar_test.dart b/packages/flutter_tools/test/commands.shard/permeable/build_aar_test.dart index b3d346dc1c..dceac215eb 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/build_aar_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/build_aar_test.dart @@ -20,7 +20,7 @@ import '../../src/android_common.dart'; import '../../src/common.dart'; import '../../src/context.dart'; import '../../src/fake_process_manager.dart'; -import '../../src/fakes.dart'; +import '../../src/fakes.dart' hide FakeFlutterProjectFactory; import '../../src/test_flutter_command_runner.dart'; void main() { diff --git a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart index 47ef02afd8..8d9707c4e1 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart @@ -64,6 +64,7 @@ void main() { late LoggingProcessManager loggingProcessManager; late FakeProcessManager fakeProcessManager; late BufferLogger logger; + late FakeStdio mockStdio; setUpAll(() async { Cache.disableLocking(); @@ -80,6 +81,7 @@ void main() { channel: frameworkChannel, ); fakeProcessManager = FakeProcessManager.empty(); + mockStdio = FakeStdio(); }); tearDown(() { @@ -171,6 +173,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -218,6 +221,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -244,6 +248,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -273,6 +278,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -298,6 +304,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), ...noColorTerminalOverride, }); @@ -323,6 +330,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), ...noColorTerminalOverride, }); @@ -356,6 +364,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -388,6 +397,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -415,6 +425,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -453,6 +464,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -482,6 +494,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -520,6 +533,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -550,6 +564,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -580,6 +595,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), Logger: ()=>logger, }); @@ -607,6 +623,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -728,6 +745,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1426,6 +1444,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1454,6 +1473,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1711,6 +1731,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1735,6 +1756,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1885,6 +1907,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1909,13 +1932,14 @@ void main() { }, overrides: { ProcessManager: () => loggingProcessManager, - Pub: () => Pub( + Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, processManager: globals.processManager, usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }, ); @@ -2869,6 +2893,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); diff --git a/packages/flutter_tools/test/commands.shard/permeable/format_test.dart b/packages/flutter_tools/test/commands.shard/permeable/format_test.dart index 7a154bd060..8180d2f7b9 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/format_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/format_test.dart @@ -4,21 +4,25 @@ import 'package:args/command_runner.dart'; import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/commands/format.dart'; import 'package:flutter_tools/src/globals.dart' as globals; import '../../src/common.dart'; import '../../src/context.dart'; +import '../../src/fakes.dart'; import '../../src/test_flutter_command_runner.dart'; void main() { group('format', () { late Directory tempDir; + late FakeStdio mockStdio; setUp(() { Cache.disableLocking(); tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_format_test.'); + mockStdio = FakeStdio(); }); tearDown(() { @@ -38,6 +42,8 @@ void main() { final String formatted = srcFile.readAsStringSync(); expect(formatted, original); + }, overrides: { + Stdio: () => mockStdio, }); testUsingContext('dry-run', () async { 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 a145dd7027..e6a98415bb 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart @@ -30,6 +30,12 @@ import '../../src/fakes.dart'; import '../../src/test_flutter_command_runner.dart'; void main() { + late FakeStdio mockStdio; + + setUp(() { + mockStdio = FakeStdio()..stdout.terminalColumns = 80; + }); + Cache.disableLocking(); group('packages get/upgrade', () { late Directory tempDir; @@ -195,16 +201,25 @@ void main() { } } - testUsingContext('get fetches packages', () async { + testUsingContext('get fetches packages and has output from pub', () async { final String projectPath = await createProject(tempDir, arguments: ['--no-pub', '--template=module']); removeGeneratedFiles(projectPath); await runCommandIn(projectPath, 'get'); + expect(mockStdio.stdout.writes.map(utf8.decode), + allOf( + contains(matches(RegExp(r'Resolving dependencies in .+flutter_project\.\.\.'))), + contains('+ flutter 0.0.0 from sdk flutter\n'), + contains(matches(RegExp(r'Changed \d+ dependencies in .+flutter_project!'))), + ), + ); + expectDependenciesResolved(projectPath); expectZeroPluginsInjected(projectPath); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -212,6 +227,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -225,6 +241,7 @@ void main() { expectDependenciesResolved(projectPath); expectZeroPluginsInjected(projectPath); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -232,6 +249,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -245,6 +263,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesNumberPlugins, 0); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -252,6 +271,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -267,6 +287,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesNumberPlugins, 1); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -274,6 +295,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -287,6 +309,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesProjectModule, false); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -294,6 +317,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -307,6 +331,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesProjectModule, true); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -314,6 +339,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -336,6 +362,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesAndroidEmbeddingVersion, 'v1'); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -343,6 +370,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -356,6 +384,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesAndroidEmbeddingVersion, 'v2'); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -363,6 +392,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -376,7 +406,7 @@ void main() { expectDependenciesResolved(projectPath); expectZeroPluginsInjected(projectPath); }, overrides: { - Stdio: () => FakeStdio()..stdout.terminalColumns = 80, + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -384,6 +414,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -397,6 +428,7 @@ void main() { expectDependenciesResolved(projectPath); expectModulePluginInjected(projectPath); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -404,6 +436,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -425,6 +458,7 @@ void main() { expectDependenciesResolved(exampleProjectPath); expectPluginInjected(exampleProjectPath); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -432,6 +466,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); }); @@ -468,6 +503,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -493,6 +529,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -523,6 +560,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -553,6 +591,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -581,6 +620,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); }); diff --git a/packages/flutter_tools/test/general.shard/cache_test.dart b/packages/flutter_tools/test/general.shard/cache_test.dart index 56c80613fe..c72aee9f70 100644 --- a/packages/flutter_tools/test/general.shard/cache_test.dart +++ b/packages/flutter_tools/test/general.shard/cache_test.dart @@ -16,6 +16,7 @@ import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/flutter_cache.dart'; import 'package:flutter_tools/src/globals.dart' as globals; +import 'package:flutter_tools/src/project.dart'; import 'package:test/fake.dart'; import '../src/common.dart'; @@ -908,6 +909,7 @@ void main() { flutterRoot: () => '', logger: logger, pub: () => FakePub(), + projectFactory: FakeFlutterProjectFactory(), ); expect(await pubDependencies.isUpToDate(fileSystem), false); // no package config @@ -950,6 +952,7 @@ void main() { flutterRoot: () => '', logger: logger, pub: () => pub, + projectFactory: FakeFlutterProjectFactory() ); await pubDependencies.update(FakeArtifactUpdater(), logger, fileSystem, FakeOperatingSystemUtils()); @@ -1155,7 +1158,7 @@ class FakePub extends Fake implements Pub { @override Future get({ PubContext? context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = 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 f3f9bfe18b..417185d141 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 @@ -12,11 +12,14 @@ import 'package:flutter_tools/src/base/io.dart' show ProcessException; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/cache.dart'; +import 'package:flutter_tools/src/convert.dart'; import 'package:flutter_tools/src/dart/pub.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; import '../../src/common.dart'; import '../../src/fake_process_manager.dart'; +import '../../src/fakes.dart'; void main() { setUpAll(() { @@ -38,9 +41,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await expectLater(() => pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ), throwsToolExit(message: 'Your Flutter SDK download may be corrupt or missing permissions to run')); @@ -52,9 +57,10 @@ void main() { const FakeCommand(command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ]), ]); final BufferLogger logger = BufferLogger.test(); @@ -82,9 +88,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, shouldSkipThirdPartyGenerator: false, @@ -99,9 +107,10 @@ void main() { const FakeCommand(command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ]), ]); final BufferLogger logger = BufferLogger.test(); @@ -130,9 +139,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ); @@ -146,9 +157,10 @@ void main() { const FakeCommand(command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ]), ]); final BufferLogger logger = BufferLogger.test(); @@ -177,9 +189,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ); @@ -207,9 +221,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ); @@ -240,9 +256,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ); @@ -256,9 +274,10 @@ void main() { const FakeCommand(command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ]), ]); final BufferLogger logger = BufferLogger.test(); @@ -277,9 +296,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ); @@ -294,9 +315,10 @@ void main() { const FakeCommand(command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ]), ]); final BufferLogger logger = BufferLogger.test(); @@ -314,9 +336,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ); @@ -331,9 +355,10 @@ void main() { FakeCommand(command: const [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], onRun: () { fileSystem.file('.dart_tool/package_config.json').createSync(recursive: true); }), @@ -351,9 +376,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ); @@ -368,9 +395,10 @@ void main() { const FakeCommand(command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ]), ]); final BufferLogger logger = BufferLogger.test(); @@ -387,9 +415,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ); @@ -403,9 +433,10 @@ void main() { const FakeCommand(command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ]), ]); final BufferLogger logger = BufferLogger.test(); @@ -425,9 +456,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ); @@ -441,9 +474,10 @@ void main() { const FakeCommand(command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ]), ]); final BufferLogger logger = BufferLogger.test(); @@ -465,9 +499,11 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.pubGet, checkUpToDate: true, ); @@ -483,9 +519,10 @@ void main() { command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], exitCode: 69, environment: {'FLUTTER_ROOT': '', 'PUB_ENVIRONMENT': 'flutter_cli:flutter_tests'}, @@ -511,11 +548,15 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); FakeAsync().run((FakeAsync time) { expect(logger.statusText, ''); - pub.get(context: PubContext.flutterTests).then((void value) { + pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests, + ).then((void value) { error = 'test completed unexpectedly'; }, onError: (dynamic thrownError) { error = 'test failed unexpectedly: $thrownError'; @@ -576,10 +617,11 @@ void main() { command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', '--offline', + '--example', ], exitCode: 69, environment: {'FLUTTER_ROOT': '', 'PUB_ENVIRONMENT': 'flutter_cli:flutter_tests'}, @@ -596,11 +638,16 @@ void main() { usage: TestUsage(), platform: FakePlatform(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); FakeAsync().run((FakeAsync time) { expect(logger.statusText, ''); - pub.get(context: PubContext.flutterTests, offline: true).then((void value) { + pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests, + offline: true + ).then((void value) { error = 'test completed unexpectedly'; }, onError: (dynamic thrownError) { error = 'test failed unexpectedly: $thrownError'; @@ -624,9 +671,10 @@ void main() { command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], exitCode: 66, stderr: 'err1\nerr2\nerr3\n', @@ -634,18 +682,19 @@ void main() { environment: {'FLUTTER_ROOT': '', 'PUB_ENVIRONMENT': 'flutter_cli:flutter_tests'}, ), ]); - + final FakeStdio mockStdio = FakeStdio(); final Pub pub = Pub( platform: FakePlatform(), fileSystem: fileSystem, logger: logger, usage: TestUsage(), botDetector: const BotDetectorAlwaysNo(), + stdio: mockStdio, processManager: processManager, ); const String toolExitMessage = ''' pub get failed -command: "bin/cache/dart-sdk/bin/dart __deprecated_pub --verbosity=warning get --no-precompile" +command: "bin/cache/dart-sdk/bin/dart __deprecated_pub --directory . get --example" pub env: { "FLUTTER_ROOT": "", "PUB_ENVIRONMENT": "flutter_cli:flutter_tests", @@ -654,19 +703,28 @@ exit code: 66 last line of pub output: "err3" '''; await expectLater( - () => pub.get(context: PubContext.flutterTests), + () => pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests, + ), throwsA(isA().having((ToolExit error) => error.message, 'message', toolExitMessage)), ); - expect(logger.statusText, - 'Running "flutter pub get" in /...\n' - 'out1\n' - 'out2\n' - 'out3\n' + expect(logger.statusText, 'Running "flutter pub get" in /...\n'); + expect( + mockStdio.stdout.writes.map(utf8.decode), + [ + 'out1\n', + 'out2\n', + 'out3\n', + ] ); - expect(logger.errorText, - 'err1\n' - 'err2\n' - 'err3\n' + expect( + mockStdio.stderr.writes.map(utf8.decode), + [ + 'err1\n', + 'err2\n', + 'err3\n', + ] ); expect(processManager, hasNoRemainingExpectations); }); @@ -680,18 +738,20 @@ last line of pub output: "err3" command: const [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], onRun: () { throw const ProcessException( 'bin/cache/dart-sdk/bin/dart', [ '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], 'message', 1, @@ -710,10 +770,14 @@ last line of pub output: "err3" logger: logger, usage: TestUsage(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), processManager: processManager, ); await expectLater( - () => pub.get(context: PubContext.flutterTests), + () => pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests, + ), throwsA( isA().having( (ProcessException error) => error.message, @@ -741,9 +805,10 @@ last line of pub output: "err3" command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], exitCode: 69, environment: { @@ -760,10 +825,14 @@ last line of pub output: "err3" logger: BufferLogger.test(), processManager: processManager, botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); FakeAsync().run((FakeAsync time) { - pub.get(context: PubContext.flutterTests).then((void value) { + pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests + ).then((void value) { error = 'test completed unexpectedly'; }, onError: (dynamic thrownError) { error = 'test failed unexpectedly: $thrownError'; @@ -802,9 +871,10 @@ last line of pub output: "err3" command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], exitCode: 69, environment: { @@ -825,10 +895,14 @@ last line of pub output: "err3" logger: BufferLogger.test(), processManager: processManager, botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); FakeAsync().run((FakeAsync time) { - pub.get(context: PubContext.flutterTests).then((void value) { + pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests, + ).then((void value) { error = 'test completed unexpectedly'; }, onError: (dynamic thrownError) { error = thrownError.toString(); @@ -853,9 +927,10 @@ last line of pub output: "err3" command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], exitCode: 69, environment: { @@ -871,6 +946,7 @@ last line of pub output: "err3" processManager: processManager, usage: TestUsage(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), platform: FakePlatform( environment: const { 'PUB_CACHE': 'custom/pub-cache/path', @@ -880,7 +956,9 @@ last line of pub output: "err3" FakeAsync().run((FakeAsync time) { String? error; - pub.get(context: PubContext.flutterTests).then((void value) { + pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests).then((void value) { error = 'test completed unexpectedly'; }, onError: (dynamic thrownError) { error = 'test failed unexpectedly: $thrownError'; @@ -899,6 +977,7 @@ last line of pub output: "err3" logger: BufferLogger.test(), processManager: FakeProcessManager.any(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), usage: usage, platform: FakePlatform( environment: const { @@ -913,8 +992,8 @@ last line of pub output: "err3" ..writeAsStringSync('{"configVersion": 2,"packages": []}'); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.flutterTests, - generateSyntheticPackage: true, ); expect(usage.events, contains( const TestUsageEvent('pub-result', 'flutter-tests', label: 'success'), @@ -929,6 +1008,7 @@ last line of pub output: "err3" logger: BufferLogger.test(), processManager: FakeProcessManager.any(), botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), usage: usage, platform: FakePlatform( environment: const { @@ -952,8 +1032,8 @@ last line of pub output: "err3" '''); await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), context: PubContext.flutterTests, - generateSyntheticPackage: true, ); expect( @@ -976,9 +1056,10 @@ last line of pub output: "err3" command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], exitCode: 1, ), @@ -990,6 +1071,7 @@ last line of pub output: "err3" logger: BufferLogger.test(), processManager: processManager, botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), platform: FakePlatform( environment: const { 'PUB_CACHE': 'custom/pub-cache/path', @@ -997,7 +1079,10 @@ last line of pub output: "err3" ), ); try { - await pub.get(context: PubContext.flutterTests); + await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests, + ); } on ToolExit { // Ignore. } @@ -1018,9 +1103,10 @@ last line of pub output: "err3" command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], exitCode: 1, stderr: 'version solving failed', @@ -1038,11 +1124,15 @@ last line of pub output: "err3" ), usage: usage, botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio(), ); fileSystem.file('pubspec.yaml').writeAsStringSync('name: foo'); try { - await pub.get(context: PubContext.flutterTests); + await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests + ); } on ToolExit { // Ignore. } @@ -1061,9 +1151,10 @@ last line of pub output: "err3" command: const [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], onRun: () { fileSystem.file('.dart_tool/package_config.json') @@ -1074,18 +1165,20 @@ last line of pub output: "err3" command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], ), FakeCommand( command: const [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], onRun: () { fileSystem.file('pubspec.yaml') @@ -1096,9 +1189,10 @@ last line of pub output: "err3" command: [ 'bin/cache/dart-sdk/bin/dart', '__deprecated_pub', - '--verbosity=warning', + '--directory', + '.', 'get', - '--no-precompile', + '--example', ], ), ]); @@ -1110,7 +1204,8 @@ last line of pub output: "err3" platform: FakePlatform( environment: {}, ), - botDetector: const BotDetectorAlwaysNo() + botDetector: const BotDetectorAlwaysNo(), + stdio: FakeStdio() ); fileSystem.file('version').createSync(); @@ -1121,7 +1216,10 @@ last line of pub output: "err3" fileSystem.file('pubspec.yaml') ..createSync() ..setLastModifiedSync(DateTime(2001)); - await pub.get(context: PubContext.flutterTests); // pub sets date of .packages to 2002 + await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests, + ); // pub sets date of .packages to 2002 expect(logger.statusText, 'Running "flutter pub get" in /...\n'); expect(logger.errorText, isEmpty); @@ -1133,7 +1231,10 @@ last line of pub output: "err3" .setLastModifiedSync(DateTime(2000)); fileSystem.file('pubspec.yaml') .setLastModifiedSync(DateTime(2001)); - await pub.get(context: PubContext.flutterTests); // pub does nothing + await pub.get( + project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + context: PubContext.flutterTests, + ); // pub does nothing expect(logger.statusText, 'Running "flutter pub get" in /...\n'); expect(logger.errorText, isEmpty); 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 7522d37fbb..e9ff3b5ab0 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 @@ -20,6 +20,7 @@ import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/pre_run_validator.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/runner/flutter_command.dart'; import 'package:test/fake.dart'; @@ -814,11 +815,12 @@ class FakePub extends Fake implements Pub { @override Future get({ PubContext context, - String directory, + FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, + bool generateSyntheticPackageForExample = false, String flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, diff --git a/packages/flutter_tools/test/integration.shard/web_plugin_registrant_test.dart b/packages/flutter_tools/test/integration.shard/web_plugin_registrant_test.dart index b79701b141..f2e205e380 100644 --- a/packages/flutter_tools/test/integration.shard/web_plugin_registrant_test.dart +++ b/packages/flutter_tools/test/integration.shard/web_plugin_registrant_test.dart @@ -75,6 +75,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: globals.stdio, ), }); @@ -122,6 +123,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: globals.stdio, ), }); @@ -153,6 +155,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: globals.stdio, ), }); @@ -183,6 +186,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: globals.stdio, ), }); @@ -232,6 +236,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: globals.stdio, ), }); } diff --git a/packages/flutter_tools/test/src/fakes.dart b/packages/flutter_tools/test/src/fakes.dart index d0d8ad21ae..6be91d9302 100644 --- a/packages/flutter_tools/test/src/fakes.dart +++ b/packages/flutter_tools/test/src/fakes.dart @@ -14,6 +14,7 @@ import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/convert.dart'; import 'package:flutter_tools/src/features.dart'; import 'package:flutter_tools/src/ios/plist_parser.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/version.dart'; import 'package:test/fake.dart'; @@ -561,3 +562,13 @@ class FakeStopwatchFactory implements StopwatchFactory { return stopwatches[name] ?? FakeStopwatch(); } } + +class FakeFlutterProjectFactory implements FlutterProjectFactory { + @override + FlutterProject fromDirectory(Directory directory) { + return FlutterProject.fromDirectoryTest(directory); + } + + @override + Map get projects => throw UnimplementedError(); +} diff --git a/packages/flutter_tools/test/src/test_flutter_command_runner.dart b/packages/flutter_tools/test/src/test_flutter_command_runner.dart index 22b68f1793..d616bbd0da 100644 --- a/packages/flutter_tools/test/src/test_flutter_command_runner.dart +++ b/packages/flutter_tools/test/src/test_flutter_command_runner.dart @@ -35,7 +35,7 @@ Future createProject(Directory temp, { List? arguments }) async final CreateCommand command = CreateCommand(); final CommandRunner runner = createTestCommandRunner(command); await runner.run(['create', ...arguments, projectPath]); - // Created `.packages` since it's not created when the flag `--no-pub` is passed. + // Create `.packages` since it's not created when the flag `--no-pub` is passed. globals.fs.file(globals.fs.path.join(projectPath, '.packages')).createSync(); return projectPath; } diff --git a/packages/flutter_tools/test/src/throwing_pub.dart b/packages/flutter_tools/test/src/throwing_pub.dart index 235771b816..c00a7f12d5 100644 --- a/packages/flutter_tools/test/src/throwing_pub.dart +++ b/packages/flutter_tools/test/src/throwing_pub.dart @@ -4,6 +4,7 @@ import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/dart/pub.dart'; +import 'package:flutter_tools/src/project.dart'; class ThrowingPub implements Pub { @override @@ -12,8 +13,6 @@ class ThrowingPub implements Pub { String? directory, MessageFilter? filter, String? failureMessage = 'pub failed', - bool? retry, - bool? showTraceForErrors, }) { throw UnsupportedError('Attempted to invoke pub during test.'); } @@ -21,13 +20,14 @@ class ThrowingPub implements Pub { @override Future get({ PubContext? context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool checkLastModified = true, bool skipPubspecYamlCheck = false, bool generateSyntheticPackage = false, + bool generateSyntheticPackageForExample = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true,