Unverified Commit fde26751 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Make Pub an interface in the flutter tool (#42257)

parent fc626661
...@@ -102,7 +102,7 @@ class BuildRunner extends CodeGenerator { ...@@ -102,7 +102,7 @@ class BuildRunner extends CodeGenerator {
stringBuffer.writeln(' build_daemon: $kSupportedBuildDaemonVersion'); stringBuffer.writeln(' build_daemon: $kSupportedBuildDaemonVersion');
syntheticPubspec.writeAsStringSync(stringBuffer.toString()); syntheticPubspec.writeAsStringSync(stringBuffer.toString());
await pubGet( await pub.get(
context: PubContext.pubGet, context: PubContext.pubGet,
directory: generatedDirectory.path, directory: generatedDirectory.path,
upgrade: false, upgrade: false,
......
...@@ -179,7 +179,7 @@ class WebFs { ...@@ -179,7 +179,7 @@ class WebFs {
// Workaround for https://github.com/flutter/flutter/issues/41681. // Workaround for https://github.com/flutter/flutter/issues/41681.
final String toolPath = fs.path.join(Cache.flutterRoot, 'packages', 'flutter_tools'); final String toolPath = fs.path.join(Cache.flutterRoot, 'packages', 'flutter_tools');
if (!fs.isFileSync(fs.path.join(toolPath, '.packages'))) { if (!fs.isFileSync(fs.path.join(toolPath, '.packages'))) {
await pubGet( await pub.get(
context: PubContext.pubGet, context: PubContext.pubGet,
directory: toolPath, directory: toolPath,
offline: true, offline: true,
......
...@@ -498,7 +498,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi ...@@ -498,7 +498,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
templateContext['description'] = description; templateContext['description'] = description;
generatedCount += _renderTemplate(fs.path.join('module', 'common'), directory, templateContext, overwrite: overwrite); generatedCount += _renderTemplate(fs.path.join('module', 'common'), directory, templateContext, overwrite: overwrite);
if (argResults['pub']) { if (argResults['pub']) {
await pubGet( await pub.get(
context: PubContext.create, context: PubContext.create,
directory: directory.path, directory: directory.path,
offline: argResults['offline'], offline: argResults['offline'],
...@@ -517,7 +517,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi ...@@ -517,7 +517,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
templateContext['description'] = description; templateContext['description'] = description;
generatedCount += _renderTemplate('package', directory, templateContext, overwrite: overwrite); generatedCount += _renderTemplate('package', directory, templateContext, overwrite: overwrite);
if (argResults['pub']) { if (argResults['pub']) {
await pubGet( await pub.get(
context: PubContext.createPackage, context: PubContext.createPackage,
directory: directory.path, directory: directory.path,
offline: argResults['offline'], offline: argResults['offline'],
...@@ -534,7 +534,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi ...@@ -534,7 +534,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
templateContext['description'] = description; templateContext['description'] = description;
generatedCount += _renderTemplate('plugin', directory, templateContext, overwrite: overwrite); generatedCount += _renderTemplate('plugin', directory, templateContext, overwrite: overwrite);
if (argResults['pub']) { if (argResults['pub']) {
await pubGet( await pub.get(
context: PubContext.createPlugin, context: PubContext.createPlugin,
directory: directory.path, directory: directory.path,
offline: argResults['offline'], offline: argResults['offline'],
...@@ -570,7 +570,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi ...@@ -570,7 +570,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
} }
if (argResults['pub']) { if (argResults['pub']) {
await pubGet(context: PubContext.create, directory: directory.path, offline: argResults['offline']); await pub.get(context: PubContext.create, directory: directory.path, offline: argResults['offline']);
await project.ensureReadyForPlatformSpecificTooling(checkProjects: false); await project.ensureReadyForPlatformSpecificTooling(checkProjects: false);
} }
......
...@@ -93,7 +93,7 @@ class PackagesGetCommand extends FlutterCommand { ...@@ -93,7 +93,7 @@ class PackagesGetCommand extends FlutterCommand {
Future<void> _runPubGet(String directory) async { Future<void> _runPubGet(String directory) async {
final Stopwatch pubGetTimer = Stopwatch()..start(); final Stopwatch pubGetTimer = Stopwatch()..start();
try { try {
await pubGet(context: PubContext.pubGet, await pub.get(context: PubContext.pubGet,
directory: directory, directory: directory,
upgrade: upgrade , upgrade: upgrade ,
offline: argResults['offline'], offline: argResults['offline'],
...@@ -164,7 +164,7 @@ class PackagesTestCommand extends FlutterCommand { ...@@ -164,7 +164,7 @@ class PackagesTestCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
Cache.releaseLockEarly(); Cache.releaseLockEarly();
await pub(<String>['run', 'test', ...argResults.rest], context: PubContext.runTest, retry: false); await pub.batch(<String>['run', 'test', ...argResults.rest], context: PubContext.runTest, retry: false);
return null; return null;
} }
} }
...@@ -205,7 +205,7 @@ class PackagesPublishCommand extends FlutterCommand { ...@@ -205,7 +205,7 @@ class PackagesPublishCommand extends FlutterCommand {
if (argResults['force']) '--force', if (argResults['force']) '--force',
]; ];
Cache.releaseLockEarly(); Cache.releaseLockEarly();
await pubInteractively(<String>['publish', ...args]); await pub.interactively(<String>['publish', ...args]);
return null; return null;
} }
} }
...@@ -236,7 +236,7 @@ class PackagesForwardCommand extends FlutterCommand { ...@@ -236,7 +236,7 @@ class PackagesForwardCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
Cache.releaseLockEarly(); Cache.releaseLockEarly();
await pubInteractively(<String>[_commandName, ...argResults.rest]); await pub.interactively(<String>[_commandName, ...argResults.rest]);
return null; return null;
} }
...@@ -264,7 +264,7 @@ class PackagesPassthroughCommand extends FlutterCommand { ...@@ -264,7 +264,7 @@ class PackagesPassthroughCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
Cache.releaseLockEarly(); Cache.releaseLockEarly();
await pubInteractively(argResults.rest); await pub.interactively(argResults.rest);
return null; return null;
} }
} }
...@@ -131,7 +131,7 @@ class TestCommand extends FastFlutterCommand { ...@@ -131,7 +131,7 @@ class TestCommand extends FastFlutterCommand {
'directory (or one of its subdirectories).'); 'directory (or one of its subdirectories).');
} }
if (shouldRunPub) { if (shouldRunPub) {
await pubGet(context: PubContext.getVerifyContext(name), skipPubspecYamlCheck: true); await pub.get(context: PubContext.getVerifyContext(name), skipPubspecYamlCheck: true);
} }
final bool buildTestAssets = argResults['test-assets']; final bool buildTestAssets = argResults['test-assets'];
final List<String> names = argResults['name']; final List<String> names = argResults['name'];
......
...@@ -253,7 +253,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -253,7 +253,7 @@ class UpdatePackagesCommand extends FlutterCommand {
fakePackage.createSync(); fakePackage.createSync();
fakePackage.writeAsStringSync(_generateFakePubspec(dependencies.values)); fakePackage.writeAsStringSync(_generateFakePubspec(dependencies.values));
// First we run "pub upgrade" on this generated package: // First we run "pub upgrade" on this generated package:
await pubGet( await pub.get(
context: PubContext.updatePackages, context: PubContext.updatePackages,
directory: tempDir.path, directory: tempDir.path,
upgrade: true, upgrade: true,
...@@ -264,7 +264,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -264,7 +264,7 @@ class UpdatePackagesCommand extends FlutterCommand {
// of all the dependencies so that we can figure out the transitive // of all the dependencies so that we can figure out the transitive
// dependencies later. It also remembers which version was selected for // dependencies later. It also remembers which version was selected for
// each package. // each package.
await pub( await pub.batch(
<String>['deps', '--style=compact'], <String>['deps', '--style=compact'],
context: PubContext.updatePackages, context: PubContext.updatePackages,
directory: tempDir.path, directory: tempDir.path,
...@@ -324,7 +324,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -324,7 +324,7 @@ class UpdatePackagesCommand extends FlutterCommand {
int count = 0; int count = 0;
for (Directory dir in packages) { for (Directory dir in packages) {
await pubGet(context: PubContext.updatePackages, directory: dir.path, checkLastModified: false); await pub.get(context: PubContext.updatePackages, directory: dir.path, checkLastModified: false);
count += 1; count += 1;
} }
......
...@@ -264,7 +264,7 @@ class UpgradeCommandRunner { ...@@ -264,7 +264,7 @@ class UpgradeCommandRunner {
final String projectRoot = findProjectRoot(); final String projectRoot = findProjectRoot();
if (projectRoot != null) { if (projectRoot != null) {
printStatus(''); printStatus('');
await pubGet(context: PubContext.pubUpgrade, directory: projectRoot, upgrade: true, checkLastModified: false); await pub.get(context: PubContext.pubUpgrade, directory: projectRoot, upgrade: true, checkLastModified: false);
} }
} }
......
...@@ -119,7 +119,7 @@ class VersionCommand extends FlutterCommand { ...@@ -119,7 +119,7 @@ class VersionCommand extends FlutterCommand {
final String projectRoot = findProjectRoot(); final String projectRoot = findProjectRoot();
if (projectRoot != null) { if (projectRoot != null) {
printStatus(''); printStatus('');
await pubGet( await pub.get(
context: PubContext.pubUpgrade, context: PubContext.pubUpgrade,
directory: projectRoot, directory: projectRoot,
upgrade: true, upgrade: true,
......
...@@ -27,6 +27,7 @@ import 'base/utils.dart'; ...@@ -27,6 +27,7 @@ import 'base/utils.dart';
import 'build_system/build_system.dart'; import 'build_system/build_system.dart';
import 'cache.dart'; import 'cache.dart';
import 'compile.dart'; import 'compile.dart';
import 'dart/pub.dart';
import 'devfs.dart'; import 'devfs.dart';
import 'device.dart'; import 'device.dart';
import 'doctor.dart'; import 'doctor.dart';
...@@ -105,6 +106,7 @@ Future<T> runInContext<T>( ...@@ -105,6 +106,7 @@ Future<T> runInContext<T>(
MacOSWorkflow: () => const MacOSWorkflow(), MacOSWorkflow: () => const MacOSWorkflow(),
MDnsObservatoryDiscovery: () => MDnsObservatoryDiscovery(), MDnsObservatoryDiscovery: () => MDnsObservatoryDiscovery(),
OperatingSystemUtils: () => OperatingSystemUtils(), OperatingSystemUtils: () => OperatingSystemUtils(),
Pub: () => const Pub(),
ProcessInfo: () => ProcessInfo(), ProcessInfo: () => ProcessInfo(),
ProcessUtils: () => ProcessUtils(), ProcessUtils: () => ProcessUtils(),
Signals: () => Signals(), Signals: () => Signals(),
......
...@@ -7,6 +7,7 @@ import 'dart:async'; ...@@ -7,6 +7,7 @@ import 'dart:async';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart' as io; import '../base/io.dart' as io;
import '../base/logger.dart'; import '../base/logger.dart';
...@@ -19,6 +20,9 @@ import '../reporting/reporting.dart'; ...@@ -19,6 +20,9 @@ import '../reporting/reporting.dart';
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
import 'sdk.dart'; import 'sdk.dart';
/// The [Pub] instance.
Pub get pub => context.get<Pub>();
/// Represents Flutter-specific data that is added to the `PUB_ENVIRONMENT` /// Represents Flutter-specific data that is added to the `PUB_ENVIRONMENT`
/// environment variable and allows understanding the type of requests made to /// environment variable and allows understanding the type of requests made to
/// the package site on Flutter's behalf. /// the package site on Flutter's behalf.
...@@ -77,179 +81,225 @@ bool _shouldRunPubGet({ File pubSpecYaml, File dotPackages }) { ...@@ -77,179 +81,225 @@ bool _shouldRunPubGet({ File pubSpecYaml, File dotPackages }) {
return false; return false;
} }
/// [context] provides extra information to package server requests to /// A handle for interacting with the pub tool.
/// understand usage. abstract class Pub {
Future<void> pubGet({ /// Create a default [Pub] instance.
@required PubContext context, const factory Pub() = _DefaultPub;
String directory,
bool skipIfAbsent = false, /// Runs `pub get`.
bool upgrade = false, ///
bool offline = false, /// [context] provides extra information to package server requests to
bool checkLastModified = true, /// understand usage.
bool skipPubspecYamlCheck = false, Future<void> get({
}) async { @required PubContext context,
directory ??= fs.currentDirectory.path; String directory,
bool skipIfAbsent = false,
final File pubSpecYaml = fs.file(fs.path.join(directory, 'pubspec.yaml')); bool upgrade = false,
final File dotPackages = fs.file(fs.path.join(directory, '.packages')); bool offline = false,
bool checkLastModified = true,
if (!skipPubspecYamlCheck && !pubSpecYaml.existsSync()) { bool skipPubspecYamlCheck = false,
if (!skipIfAbsent) { });
throwToolExit('$directory: no pubspec.yaml found');
/// Runs pub in 'batch' mode.
///
/// forwarding complete lines written by pub to its stdout/stderr streams to
/// 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.
///
/// [context] provides extra information to package server requests to
/// understand usage.
Future<void> batch(
List<String> arguments, {
@required PubContext context,
String directory,
MessageFilter filter,
String failureMessage = 'pub failed',
@required bool retry,
bool showTraceForErrors,
});
/// 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.
Future<void> interactively(
List<String> arguments, {
String directory,
});
}
class _DefaultPub implements Pub {
const _DefaultPub();
@override
Future<void> get({
@required PubContext context,
String directory,
bool skipIfAbsent = false,
bool upgrade = false,
bool offline = false,
bool checkLastModified = true,
bool skipPubspecYamlCheck = false,
}) async {
directory ??= fs.currentDirectory.path;
final File pubSpecYaml = fs.file(fs.path.join(directory, 'pubspec.yaml'));
final File dotPackages = fs.file(fs.path.join(directory, '.packages'));
if (!skipPubspecYamlCheck && !pubSpecYaml.existsSync()) {
if (!skipIfAbsent) {
throwToolExit('$directory: no pubspec.yaml found');
}
return;
} }
return;
}
if (!checkLastModified || _shouldRunPubGet(pubSpecYaml: pubSpecYaml, dotPackages: dotPackages)) { if (!checkLastModified || _shouldRunPubGet(pubSpecYaml: pubSpecYaml, dotPackages: dotPackages)) {
final String command = upgrade ? 'upgrade' : 'get'; final String command = upgrade ? 'upgrade' : 'get';
final Status status = logger.startProgress( final Status status = logger.startProgress(
'Running "flutter pub $command" in ${fs.path.basename(directory)}...', 'Running "flutter pub $command" in ${fs.path.basename(directory)}...',
timeout: timeoutConfiguration.slowOperation, timeout: timeoutConfiguration.slowOperation,
);
final bool verbose = FlutterCommand.current != null && FlutterCommand.current.globalResults['verbose'];
final List<String> args = <String>[
if (verbose) '--verbose' else '--verbosity=warning',
...<String>[command, '--no-precompile'],
if (offline) '--offline',
];
try {
await pub(
args,
context: context,
directory: directory,
filter: _filterOverrideWarnings,
failureMessage: 'pub $command failed',
retry: true,
); );
status.stop(); final bool verbose = FlutterCommand.current != null && FlutterCommand.current.globalResults['verbose'];
} catch (exception) { final List<String> args = <String>[
status.cancel(); if (verbose) '--verbose' else '--verbosity=warning',
rethrow; ...<String>[command, '--no-precompile'],
if (offline) '--offline',
];
try {
await batch(
args,
context: context,
directory: directory,
filter: _filterOverrideWarnings,
failureMessage: 'pub $command failed',
retry: true,
);
status.stop();
} catch (exception) {
status.cancel();
rethrow;
}
} }
}
if (!dotPackages.existsSync()) { if (!dotPackages.existsSync()) {
throwToolExit('$directory: pub did not create .packages file.'); throwToolExit('$directory: pub did not create .packages file.');
} }
if (dotPackages.lastModifiedSync().isBefore(pubSpecYaml.lastModifiedSync())) { if (dotPackages.lastModifiedSync().isBefore(pubSpecYaml.lastModifiedSync())) {
throwToolExit('$directory: pub did not update .packages file ' throwToolExit('$directory: pub did not update .packages file '
'(pubspec.yaml timestamp: ${pubSpecYaml.lastModifiedSync()}; ' '(pubspec.yaml timestamp: ${pubSpecYaml.lastModifiedSync()}; '
'.packages timestamp: ${dotPackages.lastModifiedSync()}).'); '.packages timestamp: ${dotPackages.lastModifiedSync()}).');
}
} }
}
typedef MessageFilter = String Function(String message);
/// Runs pub in 'batch' mode, forwarding complete lines written by pub to its @override
/// stdout/stderr streams to the corresponding stream of this process, optionally Future<void> batch(
/// applying filtering. The pub process will not receive anything on its stdin stream. List<String> arguments, {
/// @required PubContext context,
/// The `--trace` argument is passed to `pub` (by mutating the provided String directory,
/// `arguments` list) when `showTraceForErrors` is true, and when `showTraceForErrors` MessageFilter filter,
/// is null/unset, and `isRunningOnBot` is true. String failureMessage = 'pub failed',
/// @required bool retry,
/// [context] provides extra information to package server requests to bool showTraceForErrors,
/// understand usage. }) async {
Future<void> pub( showTraceForErrors ??= isRunningOnBot;
List<String> arguments, {
@required PubContext context, bool versionSolvingFailed = false;
String directory, String filterWrapper(String line) {
MessageFilter filter, if (line.contains('version solving failed')) {
String failureMessage = 'pub failed', versionSolvingFailed = true;
@required bool retry, }
bool showTraceForErrors, if (filter == null) {
}) async { return line;
showTraceForErrors ??= isRunningOnBot; }
return filter(line);
bool versionSolvingFailed = false;
String filterWrapper(String line) {
if (line.contains('version solving failed')) {
versionSolvingFailed = true;
} }
if (filter == null) {
return line; if (showTraceForErrors) {
arguments.insert(0, '--trace');
} }
return filter(line); int attempts = 0;
} int duration = 1;
int code;
while (true) {
attempts += 1;
code = await processUtils.stream(
_pubCommand(arguments),
workingDirectory: directory,
mapFunction: filterWrapper,
environment: _createPubEnvironment(context),
);
if (code != 69) { // UNAVAILABLE in https://github.com/dart-lang/pub/blob/master/lib/src/exit_codes.dart
break;
}
versionSolvingFailed = false;
printStatus('$failureMessage ($code) -- attempting retry $attempts in $duration second${ duration == 1 ? "" : "s"}...');
await Future<void>.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) {
result = 'failure';
}
PubResultEvent(
context: context.toAnalyticsString(),
result: result,
).send();
if (showTraceForErrors) { if (code != 0) {
arguments.insert(0, '--trace'); throwToolExit('$failureMessage ($code)', exitCode: code);
}
} }
int attempts = 0;
int duration = 1; @override
int code; Future<void> interactively(
while (true) { List<String> arguments, {
attempts += 1; String directory,
code = await processUtils.stream( }) async {
Cache.releaseLockEarly();
final io.Process process = await processUtils.start(
_pubCommand(arguments), _pubCommand(arguments),
workingDirectory: directory, workingDirectory: directory,
mapFunction: filterWrapper, environment: _createPubEnvironment(PubContext.interactive),
environment: _createPubEnvironment(context),
); );
if (code != 69) { // UNAVAILABLE in https://github.com/dart-lang/pub/blob/master/lib/src/exit_codes.dart
break;
}
versionSolvingFailed = false;
printStatus('$failureMessage ($code) -- attempting retry $attempts in $duration second${ duration == 1 ? "" : "s"}...');
await Future<void>.delayed(Duration(seconds: duration));
if (duration < 64) {
duration *= 2;
}
}
assert(code != null);
String result = 'success'; // Pipe the Flutter tool stdin to the pub stdin.
if (versionSolvingFailed) { unawaited(process.stdin.addStream(io.stdin));
result = 'version-solving-failed';
} else if (code != 0) { // Pipe the put stdout and stderr to the tool stdout and stderr.
result = 'failure'; await Future.wait<dynamic>(<Future<dynamic>>[
} io.stdout.addStream(process.stdout),
PubResultEvent( io.stderr.addStream(process.stderr),
context: context.toAnalyticsString(), ]);
result: result,
).send();
if (code != 0) { // Wait for pub to exit.
throwToolExit('$failureMessage ($code)', exitCode: code); final int code = await process.exitCode;
if (code != 0) {
throwToolExit('pub finished with exit code $code', exitCode: code);
}
} }
}
/// Runs pub in 'interactive' mode, directly piping the stdin stream of this /// The command used for running pub.
/// process to that of pub, and the stdout/stderr stream of pub to the corresponding List<String> _pubCommand(List<String> arguments) {
/// streams of this process. return <String>[sdkBinaryName('pub'), ...arguments];
Future<void> pubInteractively(
List<String> arguments, {
String directory,
}) async {
Cache.releaseLockEarly();
final io.Process process = await processUtils.start(
_pubCommand(arguments),
workingDirectory: directory,
environment: _createPubEnvironment(PubContext.interactive),
);
// Pipe the Flutter tool stdin to the pub stdin.
unawaited(process.stdin.addStream(io.stdin));
// Pipe the put stdout and stderr to the tool stdout and stderr.
await Future.wait<dynamic>(<Future<dynamic>>[
io.stdout.addStream(process.stdout),
io.stderr.addStream(process.stderr),
]);
// Wait for pub to exit.
final int code = await process.exitCode;
if (code != 0) {
throwToolExit('pub finished with exit code $code', exitCode: code);
} }
}
/// The command used for running pub.
List<String> _pubCommand(List<String> arguments) {
return <String>[sdkBinaryName('pub'), ...arguments];
} }
typedef MessageFilter = String Function(String message);
/// The full environment used when running pub. /// The full environment used when running pub.
/// ///
/// [context] provides extra information to package server requests to /// [context] provides extra information to package server requests to
......
...@@ -538,7 +538,7 @@ abstract class FlutterCommand extends Command<void> { ...@@ -538,7 +538,7 @@ abstract class FlutterCommand extends Command<void> {
} }
if (shouldRunPub) { if (shouldRunPub) {
await pubGet(context: PubContext.getVerifyContext(name)); await pub.get(context: PubContext.getVerifyContext(name));
final FlutterProject project = FlutterProject.current(); final FlutterProject project = FlutterProject.current();
await project.ensureReadyForPlatformSpecificTooling(checkProjects: true); await project.ensureReadyForPlatformSpecificTooling(checkProjects: true);
} }
......
...@@ -32,7 +32,7 @@ void main() { ...@@ -32,7 +32,7 @@ void main() {
testUsingContext('AnalysisServer success', () async { testUsingContext('AnalysisServer success', () async {
_createSampleProject(tempDir); _createSampleProject(tempDir);
await pubGet(context: PubContext.flutterTests, directory: tempDir.path); await pub.get(context: PubContext.flutterTests, directory: tempDir.path);
server = AnalysisServer(dartSdkPath, <String>[tempDir.path]); server = AnalysisServer(dartSdkPath, <String>[tempDir.path]);
...@@ -46,13 +46,14 @@ void main() { ...@@ -46,13 +46,14 @@ void main() {
expect(errorCount, 0); expect(errorCount, 0);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
OperatingSystemUtils: () => os, OperatingSystemUtils: () => os,
Pub: () => const Pub(),
}); });
}); });
testUsingContext('AnalysisServer errors', () async { testUsingContext('AnalysisServer errors', () async {
_createSampleProject(tempDir, brokenCode: true); _createSampleProject(tempDir, brokenCode: true);
await pubGet(context: PubContext.flutterTests, directory: tempDir.path); await pub.get(context: PubContext.flutterTests, directory: tempDir.path);
server = AnalysisServer(dartSdkPath, <String>[tempDir.path]); server = AnalysisServer(dartSdkPath, <String>[tempDir.path]);
...@@ -68,6 +69,7 @@ void main() { ...@@ -68,6 +69,7 @@ void main() {
expect(errorCount, greaterThan(0)); expect(errorCount, greaterThan(0));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
OperatingSystemUtils: () => os, OperatingSystemUtils: () => os,
Pub: () => const Pub(),
}); });
testUsingContext('Returns no errors when source is error-free', () async { testUsingContext('Returns no errors when source is error-free', () async {
...@@ -85,6 +87,7 @@ void main() { ...@@ -85,6 +87,7 @@ void main() {
expect(errorCount, 0); expect(errorCount, 0);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
OperatingSystemUtils: () => os, OperatingSystemUtils: () => os,
Pub: () => const Pub(),
}); });
} }
......
...@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/build_system/build_system.dart'; ...@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build.dart'; import 'package:flutter_tools/src/commands/build.dart';
import 'package:flutter_tools/src/commands/build_web.dart'; import 'package:flutter_tools/src/commands/build_web.dart';
import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/features.dart'; import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
...@@ -44,6 +45,7 @@ void main() { ...@@ -44,6 +45,7 @@ void main() {
Platform: () => mockPlatform, Platform: () => mockPlatform,
FlutterVersion: () => MockFlutterVersion(), FlutterVersion: () => MockFlutterVersion(),
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true), FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
Pub: () => MockPub(),
}); });
}); });
...@@ -145,7 +147,6 @@ class UrlLauncherPlugin {} ...@@ -145,7 +147,6 @@ class UrlLauncherPlugin {}
when(buildSystem.build(any, any)).thenAnswer((Invocation invocation) async { when(buildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
return BuildResult(success: true); return BuildResult(success: true);
}); });
await runner.run(<String>['build', 'web']); await runner.run(<String>['build', 'web']);
expect(fs.file(fs.path.join('lib', 'generated_plugin_registrant.dart')).existsSync(), true); expect(fs.file(fs.path.join('lib', 'generated_plugin_registrant.dart')).existsSync(), true);
...@@ -179,3 +180,4 @@ class MockFlutterVersion extends Mock implements FlutterVersion { ...@@ -179,3 +180,4 @@ class MockFlutterVersion extends Mock implements FlutterVersion {
@override @override
bool get isMaster => true; bool get isMaster => true;
} }
class MockPub extends Mock implements Pub {}
...@@ -73,6 +73,7 @@ void main() { ...@@ -73,6 +73,7 @@ void main() {
final List<String> args = <String>[ final List<String> args = <String>[
'drive', 'drive',
'--target=$testApp', '--target=$testApp',
'--no-pub',
]; ];
try { try {
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
...@@ -99,6 +100,7 @@ void main() { ...@@ -99,6 +100,7 @@ void main() {
final List<String> args = <String>[ final List<String> args = <String>[
'drive', 'drive',
'--target=$testApp', '--target=$testApp',
'--no-pub',
]; ];
try { try {
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
...@@ -118,6 +120,7 @@ void main() { ...@@ -118,6 +120,7 @@ void main() {
'--no-wrap', '--no-wrap',
'drive', 'drive',
'--target=$appFile', '--target=$appFile',
'--no-pub',
]; ];
try { try {
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
...@@ -139,6 +142,7 @@ void main() { ...@@ -139,6 +142,7 @@ void main() {
'--no-wrap', '--no-wrap',
'drive', 'drive',
'--target=$appFile', '--target=$appFile',
'--no-pub',
]; ];
try { try {
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
...@@ -178,6 +182,7 @@ void main() { ...@@ -178,6 +182,7 @@ void main() {
final List<String> args = <String>[ final List<String> args = <String>[
'drive', 'drive',
'--target=$testApp', '--target=$testApp',
'--no-pub',
]; ];
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
expect(testLogger.errorText, isEmpty); expect(testLogger.errorText, isEmpty);
...@@ -208,6 +213,7 @@ void main() { ...@@ -208,6 +213,7 @@ void main() {
final List<String> args = <String>[ final List<String> args = <String>[
'drive', 'drive',
'--target=$testApp', '--target=$testApp',
'--no-pub',
]; ];
try { try {
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
...@@ -365,6 +371,7 @@ void main() { ...@@ -365,6 +371,7 @@ void main() {
final List<String> args = <String>[ final List<String> args = <String>[
'drive', 'drive',
'--target=$testApp', '--target=$testApp',
'--no-pub',
]; ];
try { try {
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
...@@ -391,6 +398,7 @@ void main() { ...@@ -391,6 +398,7 @@ void main() {
'drive', 'drive',
'--build', '--build',
'--target=$testApp', '--target=$testApp',
'--no-pub',
]; ];
try { try {
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
...@@ -417,6 +425,7 @@ void main() { ...@@ -417,6 +425,7 @@ void main() {
'drive', 'drive',
'--no-build', '--no-build',
'--target=$testApp', '--target=$testApp',
'--no-pub',
]; ];
try { try {
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
......
...@@ -36,7 +36,7 @@ void main() { ...@@ -36,7 +36,7 @@ void main() {
final RunCommand command = RunCommand(); final RunCommand command = RunCommand();
applyMocksToCommand(command); applyMocksToCommand(command);
try { try {
await createTestCommandRunner(command).run(<String>['run', '-t', 'abc123']); await createTestCommandRunner(command).run(<String>['run', '-t', 'abc123', '--no-pub']);
fail('Expect exception'); fail('Expect exception');
} on ToolExit catch (e) { } on ToolExit catch (e) {
expect(e.exitCode ?? 1, 1); expect(e.exitCode ?? 1, 1);
...@@ -61,6 +61,7 @@ void main() { ...@@ -61,6 +61,7 @@ void main() {
'run', 'run',
'--dart-flags', '"--observe"', '--dart-flags', '"--observe"',
'--no-hot', '--no-hot',
'--no-pub',
]; ];
}); });
......
...@@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/common.dart'; ...@@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/version.dart'; import 'package:flutter_tools/src/commands/version.dart';
import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/version.dart'; import 'package:flutter_tools/src/version.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
...@@ -30,6 +31,7 @@ void main() { ...@@ -30,6 +31,7 @@ void main() {
expect(testLogger.statusText, equals('v10.0.0\r\nv20.0.0\n' '')); expect(testLogger.statusText, equals('v10.0.0\r\nv20.0.0\n' ''));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => MockProcessManager(), ProcessManager: () => MockProcessManager(),
Pub: () => const Pub(),
}); });
testUsingContext('version switch', () async { testUsingContext('version switch', () async {
...@@ -40,6 +42,7 @@ void main() { ...@@ -40,6 +42,7 @@ void main() {
expect(testLogger.statusText, contains('Switching Flutter to version $version')); expect(testLogger.statusText, contains('Switching Flutter to version $version'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => MockProcessManager(), ProcessManager: () => MockProcessManager(),
Pub: () => const Pub(),
}); });
testUsingContext('switch to not supported version without force', () async { testUsingContext('switch to not supported version without force', () async {
...@@ -50,6 +53,7 @@ void main() { ...@@ -50,6 +53,7 @@ void main() {
expect(testLogger.errorText, contains('Version command is not supported in')); expect(testLogger.errorText, contains('Version command is not supported in'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => MockProcessManager(), ProcessManager: () => MockProcessManager(),
Pub: () => const Pub(),
}); });
testUsingContext('switch to not supported version with force', () async { testUsingContext('switch to not supported version with force', () async {
...@@ -60,6 +64,7 @@ void main() { ...@@ -60,6 +64,7 @@ void main() {
expect(testLogger.statusText, contains('Switching Flutter to version $version with force')); expect(testLogger.statusText, contains('Switching Flutter to version $version with force'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => MockProcessManager(), ProcessManager: () => MockProcessManager(),
Pub: () => const Pub(),
}); });
testUsingContext('tool exit on confusing version', () async { testUsingContext('tool exit on confusing version', () async {
...@@ -70,6 +75,7 @@ void main() { ...@@ -70,6 +75,7 @@ void main() {
throwsA(isInstanceOf<ToolExit>())); throwsA(isInstanceOf<ToolExit>()));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => MockProcessManager(), ProcessManager: () => MockProcessManager(),
Pub: () => const Pub(),
}); });
testUsingContext('exit tool if can\'t get the tags', () async { testUsingContext('exit tool if can\'t get the tags', () async {
......
...@@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/platform.dart'; ...@@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/analyze.dart'; import 'package:flutter_tools/src/commands/analyze.dart';
import 'package:flutter_tools/src/commands/create.dart'; import 'package:flutter_tools/src/commands/create.dart';
import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart'; import 'package:flutter_tools/src/runner/flutter_command.dart';
import '../../src/common.dart'; import '../../src/common.dart';
...@@ -53,7 +54,9 @@ void main() { ...@@ -53,7 +54,9 @@ void main() {
], ],
); );
expect(libMain.existsSync(), isTrue); expect(libMain.existsSync(), isTrue);
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
// Analyze in the current directory - no arguments // Analyze in the current directory - no arguments
testUsingContext('working directory', () async { testUsingContext('working directory', () async {
...@@ -62,7 +65,9 @@ void main() { ...@@ -62,7 +65,9 @@ void main() {
arguments: <String>['analyze'], arguments: <String>['analyze'],
statusTextContains: <String>['No issues found!'], statusTextContains: <String>['No issues found!'],
); );
}, timeout: allowForSlowAnalyzeTests); }, timeout: allowForSlowAnalyzeTests, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
// Analyze a specific file outside the current directory // Analyze a specific file outside the current directory
testUsingContext('passing one file throws', () async { testUsingContext('passing one file throws', () async {
...@@ -72,8 +77,9 @@ void main() { ...@@ -72,8 +77,9 @@ void main() {
toolExit: true, toolExit: true,
exitMessageContains: 'is not a directory', exitMessageContains: 'is not a directory',
); );
}, overrides: <Type, Generator>{
Pub: () => const Pub(),
}); });
// Analyze in the current directory - no arguments // Analyze in the current directory - no arguments
testUsingContext('working directory with errors', () async { testUsingContext('working directory with errors', () async {
// Break the code to produce the "The parameter 'onPressed' is required" hint // Break the code to produce the "The parameter 'onPressed' is required" hint
...@@ -104,7 +110,10 @@ void main() { ...@@ -104,7 +110,10 @@ void main() {
exitMessageContains: '2 issues found.', exitMessageContains: '2 issues found.',
toolExit: true, toolExit: true,
); );
}, timeout: allowForSlowAnalyzeTests, overrides: noColorTerminalOverride); }, timeout: allowForSlowAnalyzeTests, overrides: <Type, Generator>{
Pub: () => const Pub(),
...noColorTerminalOverride,
});
// Analyze in the current directory - no arguments // Analyze in the current directory - no arguments
testUsingContext('working directory with local options', () async { testUsingContext('working directory with local options', () async {
...@@ -131,7 +140,10 @@ void main() { ...@@ -131,7 +140,10 @@ void main() {
exitMessageContains: '3 issues found.', exitMessageContains: '3 issues found.',
toolExit: true, toolExit: true,
); );
}, timeout: allowForSlowAnalyzeTests, overrides: noColorTerminalOverride); }, timeout: allowForSlowAnalyzeTests, overrides: <Type, Generator>{
Pub: () => const Pub(),
...noColorTerminalOverride
});
testUsingContext('no duplicate issues', () async { testUsingContext('no duplicate issues', () async {
final Directory tempDir = fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_2.').absolute; final Directory tempDir = fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_2.').absolute;
...@@ -165,7 +177,10 @@ void bar() { ...@@ -165,7 +177,10 @@ void bar() {
} finally { } finally {
tryToDelete(tempDir); tryToDelete(tempDir);
} }
}, overrides: noColorTerminalOverride); }, overrides: <Type, Generator>{
Pub: () => const Pub(),
...noColorTerminalOverride
});
testUsingContext('returns no issues when source is error-free', () async { testUsingContext('returns no issues when source is error-free', () async {
const String contents = ''' const String contents = '''
...@@ -182,7 +197,10 @@ StringBuffer bar = StringBuffer('baz'); ...@@ -182,7 +197,10 @@ StringBuffer bar = StringBuffer('baz');
} finally { } finally {
tryToDelete(tempDir); tryToDelete(tempDir);
} }
}, overrides: noColorTerminalOverride); }, overrides: <Type, Generator>{
Pub: () => const Pub(),
...noColorTerminalOverride
});
testUsingContext('returns no issues for todo comments', () async { testUsingContext('returns no issues for todo comments', () async {
const String contents = ''' const String contents = '''
...@@ -200,7 +218,10 @@ StringBuffer bar = StringBuffer('baz'); ...@@ -200,7 +218,10 @@ StringBuffer bar = StringBuffer('baz');
} finally { } finally {
tryToDelete(tempDir); tryToDelete(tempDir);
} }
}, overrides: noColorTerminalOverride); }, overrides: <Type, Generator>{
Pub: () => const Pub(),
...noColorTerminalOverride
});
}); });
} }
......
...@@ -59,6 +59,7 @@ void main() { ...@@ -59,6 +59,7 @@ void main() {
'bundle', 'bundle',
...?arguments, ...?arguments,
'--target=$projectPath/lib/main.dart', '--target=$projectPath/lib/main.dart',
'--no-pub'
]); ]);
return command; return command;
} }
......
...@@ -13,6 +13,7 @@ import 'package:flutter_tools/src/base/net.dart'; ...@@ -13,6 +13,7 @@ import 'package:flutter_tools/src/base/net.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/create.dart'; import 'package:flutter_tools/src/commands/create.dart';
import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/dart/sdk.dart'; import 'package:flutter_tools/src/dart/sdk.dart';
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/version.dart'; import 'package:flutter_tools/src/version.dart';
...@@ -77,7 +78,9 @@ void main() { ...@@ -77,7 +78,9 @@ void main() {
], ],
); );
return _runFlutterTest(projectDir); return _runFlutterTest(projectDir);
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('can create a default project if empty directory exists', () async { testUsingContext('can create a default project if empty directory exists', () async {
await projectDir.create(recursive: true); await projectDir.create(recursive: true);
...@@ -93,7 +96,9 @@ void main() { ...@@ -93,7 +96,9 @@ void main() {
'ios/Runner/GeneratedPluginRegistrant.h', 'ios/Runner/GeneratedPluginRegistrant.h',
], ],
); );
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('creates a module project correctly', () async { testUsingContext('creates a module project correctly', () async {
await _createAndAnalyzeProject(projectDir, <String>[ await _createAndAnalyzeProject(projectDir, <String>[
...@@ -114,7 +119,9 @@ void main() { ...@@ -114,7 +119,9 @@ void main() {
]); ]);
return _runFlutterTest(projectDir); return _runFlutterTest(projectDir);
}, },
timeout: allowForRemotePubInvocation, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
},
); );
testUsingContext('cannot create a project if non-empty non-project directory exists with .metadata', () async { testUsingContext('cannot create a project if non-empty non-project directory exists with .metadata', () async {
...@@ -131,7 +138,10 @@ void main() { ...@@ -131,7 +138,10 @@ void main() {
'.ios/', '.ios/',
]), ]),
throwsToolExit(message: 'Sorry, unable to detect the type of project to recreate')); throwsToolExit(message: 'Sorry, unable to detect the type of project to recreate'));
}, timeout: allowForRemotePubInvocation, overrides: noColorTerminalOverride); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
...noColorTerminalOverride,
});
testUsingContext('Will create an app project if non-empty non-project directory exists without .metadata', () async { testUsingContext('Will create an app project if non-empty non-project directory exists without .metadata', () async {
await projectDir.absolute.childDirectory('blag').create(recursive: true); await projectDir.absolute.childDirectory('blag').create(recursive: true);
...@@ -154,7 +164,9 @@ void main() { ...@@ -154,7 +164,9 @@ void main() {
'.ios/', '.ios/',
], ],
); );
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('detects and recreates an app project correctly', () async { testUsingContext('detects and recreates an app project correctly', () async {
await projectDir.absolute.childDirectory('lib').create(recursive: true); await projectDir.absolute.childDirectory('lib').create(recursive: true);
...@@ -177,7 +189,9 @@ void main() { ...@@ -177,7 +189,9 @@ void main() {
'.ios/', '.ios/',
], ],
); );
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('detects and recreates a plugin project correctly', () async { testUsingContext('detects and recreates a plugin project correctly', () async {
await projectDir.create(recursive: true); await projectDir.create(recursive: true);
...@@ -200,7 +214,9 @@ void main() { ...@@ -200,7 +214,9 @@ void main() {
'lib/flutter_project.dart', 'lib/flutter_project.dart',
], ],
); );
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('detects and recreates a package project correctly', () async { testUsingContext('detects and recreates a package project correctly', () async {
await projectDir.create(recursive: true); await projectDir.create(recursive: true);
...@@ -229,7 +245,9 @@ void main() { ...@@ -229,7 +245,9 @@ void main() {
'test/widget_test.dart', 'test/widget_test.dart',
], ],
); );
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('kotlin/swift legacy app project', () async { testUsingContext('kotlin/swift legacy app project', () async {
return _createProject( return _createProject(
...@@ -249,7 +267,9 @@ void main() { ...@@ -249,7 +267,9 @@ void main() {
'ios/Runner/main.m', 'ios/Runner/main.m',
], ],
); );
}, timeout: allowForCreateFlutterProject); }, timeout: allowForCreateFlutterProject, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('can create a package project', () async { testUsingContext('can create a package project', () async {
await _createAndAnalyzeProject( await _createAndAnalyzeProject(
...@@ -277,7 +297,9 @@ void main() { ...@@ -277,7 +297,9 @@ void main() {
], ],
); );
return _runFlutterTest(projectDir); return _runFlutterTest(projectDir);
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('can create a plugin project', () async { testUsingContext('can create a plugin project', () async {
await _createAndAnalyzeProject( await _createAndAnalyzeProject(
...@@ -297,7 +319,9 @@ void main() { ...@@ -297,7 +319,9 @@ void main() {
], ],
); );
return _runFlutterTest(projectDir.childDirectory('example')); return _runFlutterTest(projectDir.childDirectory('example'));
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('kotlin/swift plugin project', () async { testUsingContext('kotlin/swift plugin project', () async {
return _createProject( return _createProject(
...@@ -380,7 +404,9 @@ void main() { ...@@ -380,7 +404,9 @@ void main() {
<String>['--with-driver-test', '--template=app'], <String>['--with-driver-test', '--template=app'],
<String>['lib/main.dart'], <String>['lib/main.dart'],
); );
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('module project with pub', () async { testUsingContext('module project with pub', () async {
return _createProject(projectDir, <String>[ return _createProject(projectDir, <String>[
...@@ -413,7 +439,9 @@ void main() { ...@@ -413,7 +439,9 @@ void main() {
'android/', 'android/',
'ios/', 'ios/',
]); ]);
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('androidx is used by default in an app project', () async { testUsingContext('androidx is used by default in an app project', () async {
...@@ -902,7 +930,9 @@ void main() { ...@@ -902,7 +930,9 @@ void main() {
'.android/app/src/main/java/com/bar/foo/flutter_project/host/MainActivity.java', '.android/app/src/main/java/com/bar/foo/flutter_project/host/MainActivity.java',
], ],
); );
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('can re-gen module .ios/ folder, reusing custom org', () async { testUsingContext('can re-gen module .ios/ folder, reusing custom org', () async {
await _createProject( await _createProject(
...@@ -917,7 +947,9 @@ void main() { ...@@ -917,7 +947,9 @@ void main() {
await project.ios.productBundleIdentifier, await project.ios.productBundleIdentifier,
'com.bar.foo.flutterProject', 'com.bar.foo.flutterProject',
); );
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('can re-gen app android/ folder, reusing custom org', () async { testUsingContext('can re-gen app android/ folder, reusing custom org', () async {
await _createProject( await _createProject(
...@@ -1070,6 +1102,8 @@ void main() { ...@@ -1070,6 +1102,8 @@ void main() {
'ios/Runner/GeneratedPluginRegistrant.h', 'ios/Runner/GeneratedPluginRegistrant.h',
], ],
); );
}, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
}); });
testUsingContext('fails when invalid package name', () async { testUsingContext('fails when invalid package name', () async {
...@@ -1097,6 +1131,7 @@ void main() { ...@@ -1097,6 +1131,7 @@ void main() {
timeout: allowForCreateFlutterProject, timeout: allowForCreateFlutterProject,
overrides: <Type, Generator>{ overrides: <Type, Generator>{
ProcessManager: () => loggingProcessManager, ProcessManager: () => loggingProcessManager,
Pub: () => const Pub(),
}, },
); );
...@@ -1115,6 +1150,7 @@ void main() { ...@@ -1115,6 +1150,7 @@ void main() {
timeout: allowForCreateFlutterProject, timeout: allowForCreateFlutterProject,
overrides: <Type, Generator>{ overrides: <Type, Generator>{
ProcessManager: () => loggingProcessManager, ProcessManager: () => loggingProcessManager,
Pub: () => const Pub(),
}, },
); );
......
...@@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/io.dart'; ...@@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/utils.dart'; import 'package:flutter_tools/src/base/utils.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/packages.dart'; import 'package:flutter_tools/src/commands/packages.dart';
import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
...@@ -206,7 +207,9 @@ void main() { ...@@ -206,7 +207,9 @@ void main() {
expectDependenciesResolved(projectPath); expectDependenciesResolved(projectPath);
expectZeroPluginsInjected(projectPath); expectZeroPluginsInjected(projectPath);
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('get --offline fetches packages', () async { testUsingContext('get --offline fetches packages', () async {
final String projectPath = await createProject(tempDir, final String projectPath = await createProject(tempDir,
...@@ -217,7 +220,9 @@ void main() { ...@@ -217,7 +220,9 @@ void main() {
expectDependenciesResolved(projectPath); expectDependenciesResolved(projectPath);
expectZeroPluginsInjected(projectPath); expectZeroPluginsInjected(projectPath);
}, timeout: allowForCreateFlutterProject); }, timeout: allowForCreateFlutterProject, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('set the number of plugins as usage value', () async { testUsingContext('set the number of plugins as usage value', () async {
final String projectPath = await createProject(tempDir, final String projectPath = await createProject(tempDir,
...@@ -229,7 +234,9 @@ void main() { ...@@ -229,7 +234,9 @@ void main() {
expect(await getCommand.usageValues, expect(await getCommand.usageValues,
containsPair(CustomDimensions.commandPackagesNumberPlugins, '0')); containsPair(CustomDimensions.commandPackagesNumberPlugins, '0'));
}, timeout: allowForCreateFlutterProject); }, timeout: allowForCreateFlutterProject, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('indicate that the project is not a module in usage value', () async { testUsingContext('indicate that the project is not a module in usage value', () async {
final String projectPath = await createProject(tempDir, final String projectPath = await createProject(tempDir,
...@@ -241,7 +248,9 @@ void main() { ...@@ -241,7 +248,9 @@ void main() {
expect(await getCommand.usageValues, expect(await getCommand.usageValues,
containsPair(CustomDimensions.commandPackagesProjectModule, 'false')); containsPair(CustomDimensions.commandPackagesProjectModule, 'false'));
}, timeout: allowForCreateFlutterProject); }, timeout: allowForCreateFlutterProject, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('indicate that the project is a module in usage value', () async { testUsingContext('indicate that the project is a module in usage value', () async {
final String projectPath = await createProject(tempDir, final String projectPath = await createProject(tempDir,
...@@ -253,7 +262,9 @@ void main() { ...@@ -253,7 +262,9 @@ void main() {
expect(await getCommand.usageValues, expect(await getCommand.usageValues,
containsPair(CustomDimensions.commandPackagesProjectModule, 'true')); containsPair(CustomDimensions.commandPackagesProjectModule, 'true'));
}, timeout: allowForCreateFlutterProject); }, timeout: allowForCreateFlutterProject, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('upgrade fetches packages', () async { testUsingContext('upgrade fetches packages', () async {
final String projectPath = await createProject(tempDir, final String projectPath = await createProject(tempDir,
...@@ -264,7 +275,9 @@ void main() { ...@@ -264,7 +275,9 @@ void main() {
expectDependenciesResolved(projectPath); expectDependenciesResolved(projectPath);
expectZeroPluginsInjected(projectPath); expectZeroPluginsInjected(projectPath);
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('get fetches packages and injects plugin', () async { testUsingContext('get fetches packages and injects plugin', () async {
final String projectPath = await createProjectWithPlugin('path_provider', final String projectPath = await createProjectWithPlugin('path_provider',
...@@ -275,7 +288,9 @@ void main() { ...@@ -275,7 +288,9 @@ void main() {
expectDependenciesResolved(projectPath); expectDependenciesResolved(projectPath);
expectModulePluginInjected(projectPath); expectModulePluginInjected(projectPath);
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
testUsingContext('get fetches packages and injects plugin in plugin project', () async { testUsingContext('get fetches packages and injects plugin in plugin project', () async {
final String projectPath = await createProject( final String projectPath = await createProject(
...@@ -294,7 +309,9 @@ void main() { ...@@ -294,7 +309,9 @@ void main() {
expectDependenciesResolved(exampleProjectPath); expectDependenciesResolved(exampleProjectPath);
expectPluginInjected(exampleProjectPath); expectPluginInjected(exampleProjectPath);
}, timeout: allowForRemotePubInvocation); }, timeout: allowForRemotePubInvocation, overrides: <Type, Generator>{
Pub: () => const Pub(),
});
}); });
group('packages test/pub', () { group('packages test/pub', () {
...@@ -317,6 +334,7 @@ void main() { ...@@ -317,6 +334,7 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
BotDetector: () => const AlwaysFalseBotDetector(), BotDetector: () => const AlwaysFalseBotDetector(),
Pub: () => const Pub(),
}); });
testUsingContext('test with bot', () async { testUsingContext('test with bot', () async {
...@@ -331,6 +349,7 @@ void main() { ...@@ -331,6 +349,7 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
BotDetector: () => const AlwaysTrueBotDetector(), BotDetector: () => const AlwaysTrueBotDetector(),
Pub: () => const Pub(),
}); });
testUsingContext('run', () async { testUsingContext('run', () async {
...@@ -344,6 +363,7 @@ void main() { ...@@ -344,6 +363,7 @@ void main() {
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
Pub: () => const Pub(),
}); });
testUsingContext('pub publish', () async { testUsingContext('pub publish', () async {
...@@ -368,6 +388,7 @@ void main() { ...@@ -368,6 +388,7 @@ void main() {
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
Pub: () => const Pub(),
}); });
testUsingContext('publish', () async { testUsingContext('publish', () async {
...@@ -380,6 +401,7 @@ void main() { ...@@ -380,6 +401,7 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
BotDetector: () => const AlwaysTrueBotDetector(), BotDetector: () => const AlwaysTrueBotDetector(),
Pub: () => const Pub(),
}); });
testUsingContext('packages publish', () async { testUsingContext('packages publish', () async {
...@@ -392,6 +414,7 @@ void main() { ...@@ -392,6 +414,7 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
BotDetector: () => const AlwaysTrueBotDetector(), BotDetector: () => const AlwaysTrueBotDetector(),
Pub: () => const Pub(),
}); });
testUsingContext('deps', () async { testUsingContext('deps', () async {
...@@ -404,6 +427,7 @@ void main() { ...@@ -404,6 +427,7 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
BotDetector: () => const AlwaysTrueBotDetector(), BotDetector: () => const AlwaysTrueBotDetector(),
Pub: () => const Pub(),
}); });
testUsingContext('cache', () async { testUsingContext('cache', () async {
...@@ -416,6 +440,7 @@ void main() { ...@@ -416,6 +440,7 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
BotDetector: () => const AlwaysTrueBotDetector(), BotDetector: () => const AlwaysTrueBotDetector(),
Pub: () => const Pub(),
}); });
testUsingContext('version', () async { testUsingContext('version', () async {
...@@ -428,6 +453,7 @@ void main() { ...@@ -428,6 +453,7 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
BotDetector: () => const AlwaysTrueBotDetector(), BotDetector: () => const AlwaysTrueBotDetector(),
Pub: () => const Pub(),
}); });
testUsingContext('uploader', () async { testUsingContext('uploader', () async {
...@@ -440,6 +466,7 @@ void main() { ...@@ -440,6 +466,7 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
BotDetector: () => const AlwaysTrueBotDetector(), BotDetector: () => const AlwaysTrueBotDetector(),
Pub: () => const Pub(),
}); });
testUsingContext('global', () async { testUsingContext('global', () async {
...@@ -453,6 +480,7 @@ void main() { ...@@ -453,6 +480,7 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Stdio: () => mockStdio, Stdio: () => mockStdio,
BotDetector: () => const AlwaysTrueBotDetector(), BotDetector: () => const AlwaysTrueBotDetector(),
Pub: () => const Pub(),
}); });
}); });
} }
...@@ -40,6 +40,7 @@ void main() { ...@@ -40,6 +40,7 @@ void main() {
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>[ await runner.run(<String>[
'aar', 'aar',
'--no-pub',
...?arguments, ...?arguments,
target, target,
]); ]);
......
...@@ -324,6 +324,7 @@ Future<BuildApkCommand> runBuildApkCommand( ...@@ -324,6 +324,7 @@ Future<BuildApkCommand> runBuildApkCommand(
await runner.run(<String>[ await runner.run(<String>[
'apk', 'apk',
...?arguments, ...?arguments,
'--no-pub',
fs.path.join(target, 'lib', 'main.dart'), fs.path.join(target, 'lib', 'main.dart'),
]); ]);
return command; return command;
......
...@@ -315,6 +315,7 @@ Future<BuildAppBundleCommand> runBuildAppBundleCommand( ...@@ -315,6 +315,7 @@ Future<BuildAppBundleCommand> runBuildAppBundleCommand(
await runner.run(<String>[ await runner.run(<String>[
'appbundle', 'appbundle',
...?arguments, ...?arguments,
'--no-pub',
fs.path.join(target, 'lib', 'main.dart'), fs.path.join(target, 'lib', 'main.dart'),
]); ]);
return command; return command;
......
...@@ -36,7 +36,7 @@ void main() { ...@@ -36,7 +36,7 @@ void main() {
FakeAsync().run((FakeAsync time) { FakeAsync().run((FakeAsync time) {
expect(processMock.lastPubEnvironment, isNull); expect(processMock.lastPubEnvironment, isNull);
expect(testLogger.statusText, ''); expect(testLogger.statusText, '');
pubGet(context: PubContext.flutterTests, checkLastModified: false).then((void value) { pub.get(context: PubContext.flutterTests, checkLastModified: false).then((void value) {
error = 'test completed unexpectedly'; error = 'test completed unexpectedly';
}, onError: (dynamic thrownError) { }, onError: (dynamic thrownError) {
error = 'test failed unexpectedly: $thrownError'; error = 'test failed unexpectedly: $thrownError';
...@@ -94,6 +94,7 @@ void main() { ...@@ -94,6 +94,7 @@ void main() {
Platform: () => FakePlatform( Platform: () => FakePlatform(
environment: UnmodifiableMapView<String, String>(<String, String>{}), environment: UnmodifiableMapView<String, String>(<String, String>{}),
), ),
Pub: () => const Pub(),
}); });
testUsingContext('pub cache in root is used', () async { testUsingContext('pub cache in root is used', () async {
...@@ -106,7 +107,7 @@ void main() { ...@@ -106,7 +107,7 @@ void main() {
MockDirectory.findCache = true; MockDirectory.findCache = true;
expect(processMock.lastPubEnvironment, isNull); expect(processMock.lastPubEnvironment, isNull);
expect(processMock.lastPubCache, isNull); expect(processMock.lastPubCache, isNull);
pubGet(context: PubContext.flutterTests, checkLastModified: false).then((void value) { pub.get(context: PubContext.flutterTests, checkLastModified: false).then((void value) {
error = 'test completed unexpectedly'; error = 'test completed unexpectedly';
}, onError: (dynamic thrownError) { }, onError: (dynamic thrownError) {
error = 'test failed unexpectedly: $thrownError'; error = 'test failed unexpectedly: $thrownError';
...@@ -121,6 +122,7 @@ void main() { ...@@ -121,6 +122,7 @@ void main() {
Platform: () => FakePlatform( Platform: () => FakePlatform(
environment: UnmodifiableMapView<String, String>(<String, String>{}), environment: UnmodifiableMapView<String, String>(<String, String>{}),
), ),
Pub: () => const Pub(),
}); });
testUsingContext('pub cache in environment is used', () async { testUsingContext('pub cache in environment is used', () async {
...@@ -132,7 +134,7 @@ void main() { ...@@ -132,7 +134,7 @@ void main() {
MockDirectory.findCache = true; MockDirectory.findCache = true;
expect(processMock.lastPubEnvironment, isNull); expect(processMock.lastPubEnvironment, isNull);
expect(processMock.lastPubCache, isNull); expect(processMock.lastPubCache, isNull);
pubGet(context: PubContext.flutterTests, checkLastModified: false).then((void value) { pub.get(context: PubContext.flutterTests, checkLastModified: false).then((void value) {
error = 'test completed unexpectedly'; error = 'test completed unexpectedly';
}, onError: (dynamic thrownError) { }, onError: (dynamic thrownError) {
error = 'test failed unexpectedly: $thrownError'; error = 'test failed unexpectedly: $thrownError';
...@@ -149,11 +151,12 @@ void main() { ...@@ -149,11 +151,12 @@ void main() {
'PUB_CACHE': 'custom/pub-cache/path', 'PUB_CACHE': 'custom/pub-cache/path',
}), }),
), ),
Pub: () => const Pub(),
}); });
testUsingContext('analytics sent on success', () async { testUsingContext('analytics sent on success', () async {
MockDirectory.findCache = true; MockDirectory.findCache = true;
await pubGet(context: PubContext.flutterTests, checkLastModified: false); await pub.get(context: PubContext.flutterTests, checkLastModified: false);
verify(flutterUsage.sendEvent('pub-result', 'flutter-tests', label: 'success')).called(1); verify(flutterUsage.sendEvent('pub-result', 'flutter-tests', label: 'success')).called(1);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => MockProcessManager(0), ProcessManager: () => MockProcessManager(0),
...@@ -164,12 +167,13 @@ void main() { ...@@ -164,12 +167,13 @@ void main() {
}), }),
), ),
Usage: () => MockUsage(), Usage: () => MockUsage(),
Pub: () => const Pub(),
}); });
testUsingContext('analytics sent on failure', () async { testUsingContext('analytics sent on failure', () async {
MockDirectory.findCache = true; MockDirectory.findCache = true;
try { try {
await pubGet(context: PubContext.flutterTests, checkLastModified: false); await pub.get(context: PubContext.flutterTests, checkLastModified: false);
} on ToolExit { } on ToolExit {
// Ignore. // Ignore.
} }
...@@ -183,12 +187,13 @@ void main() { ...@@ -183,12 +187,13 @@ void main() {
}), }),
), ),
Usage: () => MockUsage(), Usage: () => MockUsage(),
Pub: () => const Pub(),
}); });
testUsingContext('analytics sent on failed version solve', () async { testUsingContext('analytics sent on failed version solve', () async {
MockDirectory.findCache = true; MockDirectory.findCache = true;
try { try {
await pubGet(context: PubContext.flutterTests, checkLastModified: false); await pub.get(context: PubContext.flutterTests, checkLastModified: false);
} on ToolExit { } on ToolExit {
// Ignore. // Ignore.
} }
...@@ -205,6 +210,7 @@ void main() { ...@@ -205,6 +210,7 @@ void main() {
}), }),
), ),
Usage: () => MockUsage(), Usage: () => MockUsage(),
Pub: () => const Pub(),
}); });
} }
......
...@@ -44,7 +44,7 @@ void main() { ...@@ -44,7 +44,7 @@ void main() {
} }
'''); ''');
await pubGet(context: PubContext.flutterTests, directory: projectDirectory.path); await pub.get(context: PubContext.flutterTests, directory: projectDirectory.path);
final AnalysisServer server = AnalysisServer(dartSdkPath, <String>[projectDirectory.path]); final AnalysisServer server = AnalysisServer(dartSdkPath, <String>[projectDirectory.path]);
try { try {
final int errorCount = await analyze(server); final int errorCount = await analyze(server);
......
...@@ -11,7 +11,7 @@ import 'package:flutter_tools/src/base/file_system.dart'; ...@@ -11,7 +11,7 @@ import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/os.dart'; import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/process.dart'; import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/web/chrome.dart'; import 'package:flutter_tools/src/web/chrome.dart';
import 'package:flutter_tools/src/build_runner/web_fs.dart'; import 'package:flutter_tools/src/build_runner/web_fs.dart';
...@@ -89,6 +89,7 @@ void main() { ...@@ -89,6 +89,7 @@ void main() {
fs.file('.packages').createSync(); fs.file('.packages').createSync();
}, },
overrides: <Type, Generator>{ overrides: <Type, Generator>{
Pub: () => MockPub(),
OperatingSystemUtils: () => mockOperatingSystemUtils, OperatingSystemUtils: () => mockOperatingSystemUtils,
BuildDaemonCreator: () => mockBuildDaemonCreator, BuildDaemonCreator: () => mockBuildDaemonCreator,
ChromeLauncher: () => mockChromeLauncher, ChromeLauncher: () => mockChromeLauncher,
...@@ -128,10 +129,13 @@ void main() { ...@@ -128,10 +129,13 @@ void main() {
); );
// Since the .packages file is missing in the memory filesystem, this should // Since the .packages file is missing in the memory filesystem, this should
// be called. // be called.
verify(processUtils.stream(any, verify(pub.get(
workingDirectory: fs.path.join(Cache.flutterRoot, 'packages', 'flutter_tools'), context: PubContext.pubGet,
mapFunction: anyNamed('mapFunction'), directory: anyNamed('directory'),
environment: anyNamed('environment'),)).called(1); offline: true,
skipPubspecYamlCheck: true,
checkLastModified: false,
)).called(1);
// The build daemon is told to build once. // The build daemon is told to build once.
verify(mockBuildDaemonClient.startBuild()).called(1); verify(mockBuildDaemonClient.startBuild()).called(1);
...@@ -213,3 +217,4 @@ class MockHttpMultiServer extends Mock implements HttpMultiServer {} ...@@ -213,3 +217,4 @@ class MockHttpMultiServer extends Mock implements HttpMultiServer {}
class MockChromeLauncher extends Mock implements ChromeLauncher {} class MockChromeLauncher extends Mock implements ChromeLauncher {}
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {} class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
class MockProcessUtils extends Mock implements ProcessUtils {} class MockProcessUtils extends Mock implements ProcessUtils {}
class MockPub extends Mock implements Pub {}
...@@ -17,6 +17,7 @@ import 'package:flutter_tools/src/base/terminal.dart'; ...@@ -17,6 +17,7 @@ import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/base/time.dart'; import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/context_runner.dart'; import 'package:flutter_tools/src/context_runner.dart';
import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/doctor.dart'; import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/ios/plist_parser.dart'; import 'package:flutter_tools/src/ios/plist_parser.dart';
...@@ -29,6 +30,7 @@ import 'package:meta/meta.dart'; ...@@ -29,6 +30,7 @@ import 'package:meta/meta.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'common.dart'; import 'common.dart';
import 'testbed.dart';
export 'package:flutter_tools/src/base/context.dart' show Generator; export 'package:flutter_tools/src/base/context.dart' show Generator;
...@@ -92,6 +94,7 @@ void testUsingContext( ...@@ -92,6 +94,7 @@ void testUsingContext(
TimeoutConfiguration: () => const TimeoutConfiguration(), TimeoutConfiguration: () => const TimeoutConfiguration(),
PlistParser: () => FakePlistParser(), PlistParser: () => FakePlistParser(),
Signals: () => FakeSignals(), Signals: () => FakeSignals(),
Pub: () => ThrowingPub() // prevent accidentally using pub.
}, },
body: () { body: () {
final String flutterRoot = getFlutterRoot(); final String flutterRoot = getFlutterRoot();
......
...@@ -18,6 +18,7 @@ import 'package:flutter_tools/src/base/signals.dart'; ...@@ -18,6 +18,7 @@ import 'package:flutter_tools/src/base/signals.dart';
import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/context_runner.dart'; import 'package:flutter_tools/src/context_runner.dart';
import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/features.dart'; import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/version.dart'; import 'package:flutter_tools/src/version.dart';
...@@ -37,6 +38,7 @@ final Map<Type, Generator> _testbedDefaults = <Type, Generator>{ ...@@ -37,6 +38,7 @@ final Map<Type, Generator> _testbedDefaults = <Type, Generator>{
Usage: () => NoOpUsage(), // prevent addition of analytics from burdening test mocks Usage: () => NoOpUsage(), // prevent addition of analytics from burdening test mocks
FlutterVersion: () => FakeFlutterVersion(), // prevent requirement to mock git for test runner. FlutterVersion: () => FakeFlutterVersion(), // prevent requirement to mock git for test runner.
Signals: () => FakeSignals(), // prevent registering actual signal handlers. Signals: () => FakeSignals(), // prevent registering actual signal handlers.
Pub: () => ThrowingPub(), // prevent accidental invocations of pub.
}; };
/// Manages interaction with the tool injection and runner system. /// Manages interaction with the tool injection and runner system.
...@@ -711,3 +713,35 @@ class TestFeatureFlags implements FeatureFlags { ...@@ -711,3 +713,35 @@ class TestFeatureFlags implements FeatureFlags {
@override @override
final bool isNewAndroidEmbeddingEnabled; final bool isNewAndroidEmbeddingEnabled;
} }
class ThrowingPub implements Pub {
@override
Future<void> batch(List<String> arguments, {
PubContext context,
String directory,
MessageFilter filter,
String failureMessage = 'pub failed',
bool retry,
bool showTraceForErrors,
}) {
throw UnsupportedError('Attempted to inovke pub during test.');
}
@override
Future<void> get({
PubContext context,
String directory,
bool skipIfAbsent = false,
bool upgrade = false,
bool offline = false,
bool checkLastModified = true,
bool skipPubspecYamlCheck = false,
}) {
throw UnsupportedError('Attempted to inovke pub during test.');
}
@override
Future<void> interactively(List<String> arguments, {String directory}) {
throw UnsupportedError('Attempted to inovke pub during test.');
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment