[flutter_tools] remove globals from pub (#55412)
This commit is contained in:
parent
cbc121e392
commit
8df0d68633
@ -205,7 +205,7 @@ class PackagesPublishCommand extends FlutterCommand {
|
||||
if (boolArg('force')) '--force',
|
||||
];
|
||||
Cache.releaseLockEarly();
|
||||
await pub.interactively(<String>['publish', ...args]);
|
||||
await pub.interactively(<String>['publish', ...args], stdio: globals.stdio);
|
||||
return FlutterCommandResult.success();
|
||||
}
|
||||
}
|
||||
@ -236,7 +236,7 @@ class PackagesForwardCommand extends FlutterCommand {
|
||||
@override
|
||||
Future<FlutterCommandResult> runCommand() async {
|
||||
Cache.releaseLockEarly();
|
||||
await pub.interactively(<String>[_commandName, ...argResults.rest]);
|
||||
await pub.interactively(<String>[_commandName, ...argResults.rest], stdio: globals.stdio);
|
||||
return FlutterCommandResult.success();
|
||||
}
|
||||
|
||||
@ -264,7 +264,7 @@ class PackagesPassthroughCommand extends FlutterCommand {
|
||||
@override
|
||||
Future<FlutterCommandResult> runCommand() async {
|
||||
Cache.releaseLockEarly();
|
||||
await pub.interactively(argResults.rest);
|
||||
await pub.interactively(argResults.rest, stdio: globals.stdio);
|
||||
return FlutterCommandResult.success();
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +167,14 @@ Future<T> runInContext<T>(
|
||||
processManager: globals.processManager,
|
||||
logger: globals.logger,
|
||||
),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
usage: globals.flutterUsage,
|
||||
),
|
||||
ShutdownHooks: () => ShutdownHooks(logger: globals.logger),
|
||||
Signals: () => Signals(),
|
||||
Stdio: () => Stdio(),
|
||||
|
@ -5,7 +5,10 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import '../base/bot_detector.dart';
|
||||
import '../base/common.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/file_system.dart';
|
||||
@ -13,14 +16,19 @@ import '../base/io.dart' as io;
|
||||
import '../base/logger.dart';
|
||||
import '../base/process.dart';
|
||||
import '../cache.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../reporting/reporting.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
import 'sdk.dart';
|
||||
|
||||
/// The [Pub] instance.
|
||||
Pub get pub => context.get<Pub>();
|
||||
|
||||
/// The console environment key used by the pub tool.
|
||||
const String _kPubEnvironmentKey = 'PUB_ENVIRONMENT';
|
||||
|
||||
/// The console environment key used by the pub tool to find the cache directory.
|
||||
const String _kPubCacheEnvironmentKey = 'PUB_CACHE';
|
||||
|
||||
typedef MessageFilter = String Function(String message);
|
||||
|
||||
/// Represents Flutter-specific data that is added to the `PUB_ENVIRONMENT`
|
||||
/// environment variable and allows understanding the type of requests made to
|
||||
/// the package site on Flutter's behalf.
|
||||
@ -47,7 +55,6 @@ class PubContext {
|
||||
static final PubContext pubUpgrade = PubContext._(<String>['upgrade']);
|
||||
static final PubContext pubForward = PubContext._(<String>['forward']);
|
||||
static final PubContext runTest = PubContext._(<String>['run_test']);
|
||||
|
||||
static final PubContext flutterTests = PubContext._(<String>['flutter_tests']);
|
||||
static final PubContext updatePackages = PubContext._(<String>['update_packages']);
|
||||
|
||||
@ -63,26 +70,17 @@ class PubContext {
|
||||
}
|
||||
}
|
||||
|
||||
bool _shouldRunPubGet({ File pubSpecYaml, File dotPackages }) {
|
||||
if (!dotPackages.existsSync()) {
|
||||
return true;
|
||||
}
|
||||
final DateTime dotPackagesLastModified = dotPackages.lastModifiedSync();
|
||||
if (pubSpecYaml.lastModifiedSync().isAfter(dotPackagesLastModified)) {
|
||||
return true;
|
||||
}
|
||||
final File flutterToolsStamp = globals.cache.getStampFileFor('flutter_tools');
|
||||
if (flutterToolsStamp.existsSync() &&
|
||||
flutterToolsStamp.lastModifiedSync().isAfter(dotPackagesLastModified)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// A handle for interacting with the pub tool.
|
||||
abstract class Pub {
|
||||
/// Create a default [Pub] instance.
|
||||
const factory Pub() = _DefaultPub;
|
||||
factory Pub({
|
||||
@required FileSystem fileSystem,
|
||||
@required Logger logger,
|
||||
@required ProcessManager processManager,
|
||||
@required Platform platform,
|
||||
@required BotDetector botDetector,
|
||||
@required Usage usage,
|
||||
}) = _DefaultPub;
|
||||
|
||||
/// Runs `pub get`.
|
||||
///
|
||||
@ -129,11 +127,34 @@ abstract class Pub {
|
||||
Future<void> interactively(
|
||||
List<String> arguments, {
|
||||
String directory,
|
||||
@required io.Stdio stdio,
|
||||
});
|
||||
}
|
||||
|
||||
class _DefaultPub implements Pub {
|
||||
const _DefaultPub();
|
||||
_DefaultPub({
|
||||
@required FileSystem fileSystem,
|
||||
@required Logger logger,
|
||||
@required ProcessManager processManager,
|
||||
@required Platform platform,
|
||||
@required BotDetector botDetector,
|
||||
@required Usage usage,
|
||||
}) : _fileSystem = fileSystem,
|
||||
_logger = logger,
|
||||
_platform = platform,
|
||||
_botDetector = botDetector,
|
||||
_usage = usage,
|
||||
_processUtils = ProcessUtils(
|
||||
logger: logger,
|
||||
processManager: processManager,
|
||||
);
|
||||
|
||||
final FileSystem _fileSystem;
|
||||
final Logger _logger;
|
||||
final ProcessUtils _processUtils;
|
||||
final Platform _platform;
|
||||
final BotDetector _botDetector;
|
||||
final Usage _usage;
|
||||
|
||||
@override
|
||||
Future<void> get({
|
||||
@ -146,10 +167,12 @@ class _DefaultPub implements Pub {
|
||||
bool skipPubspecYamlCheck = false,
|
||||
String flutterRootOverride,
|
||||
}) async {
|
||||
directory ??= globals.fs.currentDirectory.path;
|
||||
directory ??= _fileSystem.currentDirectory.path;
|
||||
|
||||
final File pubSpecYaml = globals.fs.file(globals.fs.path.join(directory, 'pubspec.yaml'));
|
||||
final File dotPackages = globals.fs.file(globals.fs.path.join(directory, '.packages'));
|
||||
final File pubSpecYaml = _fileSystem.file(
|
||||
_fileSystem.path.join(directory, 'pubspec.yaml'));
|
||||
final File packageConfigFile = _fileSystem.file(
|
||||
_fileSystem.path.join(directory, '.dart_tool', 'package_config.json'));
|
||||
|
||||
if (!skipPubspecYamlCheck && !pubSpecYaml.existsSync()) {
|
||||
if (!skipIfAbsent) {
|
||||
@ -160,24 +183,33 @@ class _DefaultPub implements Pub {
|
||||
|
||||
final DateTime originalPubspecYamlModificationTime = pubSpecYaml.lastModifiedSync();
|
||||
|
||||
if (!checkLastModified || _shouldRunPubGet(pubSpecYaml: pubSpecYaml, dotPackages: dotPackages)) {
|
||||
if (!checkLastModified || _shouldRunPubGet(
|
||||
pubSpecYaml: pubSpecYaml,
|
||||
packageConfigFile: packageConfigFile,
|
||||
)) {
|
||||
final String command = upgrade ? 'upgrade' : 'get';
|
||||
final Status status = globals.logger.startProgress(
|
||||
'Running "flutter pub $command" in ${globals.fs.path.basename(directory)}...',
|
||||
timeout: timeoutConfiguration.slowOperation,
|
||||
final Status status = _logger.startProgress(
|
||||
'Running "flutter pub $command" in ${_fileSystem.path.basename(directory)}...',
|
||||
timeout: const TimeoutConfiguration().slowOperation,
|
||||
);
|
||||
final bool verbose = FlutterCommand.current != null && FlutterCommand.current.globalResults['verbose'] as bool;
|
||||
final bool verbose = _logger.isVerbose;
|
||||
final List<String> args = <String>[
|
||||
if (verbose) '--verbose' else '--verbosity=warning',
|
||||
...<String>[command, '--no-precompile'],
|
||||
if (offline) '--offline',
|
||||
if (verbose)
|
||||
'--verbose'
|
||||
else
|
||||
'--verbosity=warning',
|
||||
...<String>[
|
||||
command,
|
||||
'--no-precompile',
|
||||
],
|
||||
if (offline)
|
||||
'--offline',
|
||||
];
|
||||
try {
|
||||
await batch(
|
||||
args,
|
||||
context: context,
|
||||
directory: directory,
|
||||
filter: _filterOverrideWarnings,
|
||||
failureMessage: 'pub $command failed',
|
||||
retry: true,
|
||||
flutterRootOverride: flutterRootOverride,
|
||||
@ -190,11 +222,13 @@ class _DefaultPub implements Pub {
|
||||
}
|
||||
}
|
||||
|
||||
if (!dotPackages.existsSync()) {
|
||||
if (!packageConfigFile.existsSync()) {
|
||||
throwToolExit('$directory: pub did not create .packages file.');
|
||||
}
|
||||
if (pubSpecYaml.lastModifiedSync() != originalPubspecYamlModificationTime) {
|
||||
throwToolExit('$directory: unexpected concurrent modification of pubspec.yaml while running pub.');
|
||||
throwToolExit(
|
||||
'$directory: unexpected concurrent modification of '
|
||||
'pubspec.yaml while running pub.');
|
||||
}
|
||||
// We don't check if dotPackages was actually modified, because as far as we can tell sometimes
|
||||
// pub will decide it does not need to actually modify it.
|
||||
@ -202,29 +236,28 @@ class _DefaultPub implements Pub {
|
||||
// file to be more recently modified.
|
||||
final DateTime now = DateTime.now();
|
||||
if (now.isBefore(originalPubspecYamlModificationTime)) {
|
||||
globals.printError(
|
||||
'Warning: File "${globals.fs.path.absolute(pubSpecYaml.path)}" was created in the future. '
|
||||
_logger.printError(
|
||||
'Warning: File "${_fileSystem.path.absolute(pubSpecYaml.path)}" was created in the future. '
|
||||
'Optimizations that rely on comparing time stamps will be unreliable. Check your '
|
||||
'system clock for accuracy.\n'
|
||||
'The timestamp was: $originalPubspecYamlModificationTime\n'
|
||||
'The time now is: $now'
|
||||
);
|
||||
} else {
|
||||
dotPackages.setLastModifiedSync(now);
|
||||
final DateTime newDotPackagesTimestamp = dotPackages.lastModifiedSync();
|
||||
packageConfigFile.setLastModifiedSync(now);
|
||||
final DateTime newDotPackagesTimestamp = packageConfigFile.lastModifiedSync();
|
||||
if (newDotPackagesTimestamp.isBefore(originalPubspecYamlModificationTime)) {
|
||||
globals.printError(
|
||||
'Warning: Failed to set timestamp of "${globals.fs.path.absolute(dotPackages.path)}". '
|
||||
_logger.printError(
|
||||
'Warning: Failed to set timestamp of "${_fileSystem.path.absolute(packageConfigFile.path)}". '
|
||||
'Tried to set timestamp to $now, but new timestamp is $newDotPackagesTimestamp.'
|
||||
);
|
||||
if (newDotPackagesTimestamp.isAfter(now)) {
|
||||
globals.printError('Maybe the file was concurrently modified?');
|
||||
_logger.printError('Maybe the file was concurrently modified?');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Future<void> batch(
|
||||
List<String> arguments, {
|
||||
@ -236,7 +269,7 @@ class _DefaultPub implements Pub {
|
||||
bool showTraceForErrors,
|
||||
String flutterRootOverride,
|
||||
}) async {
|
||||
showTraceForErrors ??= await globals.isRunningOnBot;
|
||||
showTraceForErrors ??= await _botDetector.isRunningOnBot;
|
||||
|
||||
String lastPubMessage = 'no message';
|
||||
bool versionSolvingFailed = false;
|
||||
@ -259,7 +292,7 @@ class _DefaultPub implements Pub {
|
||||
int code;
|
||||
loop: while (true) {
|
||||
attempts += 1;
|
||||
code = await processUtils.stream(
|
||||
code = await _processUtils.stream(
|
||||
_pubCommand(arguments),
|
||||
workingDirectory: directory,
|
||||
mapFunction: filterWrapper, // may set versionSolvingFailed, lastPubMessage
|
||||
@ -275,7 +308,10 @@ class _DefaultPub implements Pub {
|
||||
}
|
||||
assert(message != null);
|
||||
versionSolvingFailed = false;
|
||||
globals.printStatus('$failureMessage ($message) -- attempting retry $attempts in $duration second${ duration == 1 ? "" : "s"}...');
|
||||
_logger.printStatus(
|
||||
'$failureMessage ($message) -- attempting retry $attempts in $duration '
|
||||
'second${ duration == 1 ? "" : "s"}...',
|
||||
);
|
||||
await Future<void>.delayed(Duration(seconds: duration));
|
||||
if (duration < 64) {
|
||||
duration *= 2;
|
||||
@ -292,6 +328,7 @@ class _DefaultPub implements Pub {
|
||||
PubResultEvent(
|
||||
context: context.toAnalyticsString(),
|
||||
result: result,
|
||||
usage: _usage,
|
||||
).send();
|
||||
|
||||
if (code != 0) {
|
||||
@ -303,33 +340,34 @@ class _DefaultPub implements Pub {
|
||||
Future<void> interactively(
|
||||
List<String> arguments, {
|
||||
String directory,
|
||||
@required io.Stdio stdio,
|
||||
}) async {
|
||||
Cache.releaseLockEarly();
|
||||
final io.Process process = await processUtils.start(
|
||||
final io.Process process = await _processUtils.start(
|
||||
_pubCommand(arguments),
|
||||
workingDirectory: directory,
|
||||
environment: await _createPubEnvironment(PubContext.interactive),
|
||||
);
|
||||
|
||||
// Pipe the Flutter tool stdin to the pub stdin.
|
||||
unawaited(process.stdin.addStream(globals.stdio.stdin)
|
||||
unawaited(process.stdin.addStream(stdio.stdin)
|
||||
// If pub exits unexpectedly with an error, that will be reported below
|
||||
// by the tool exit after the exit code check.
|
||||
.catchError((dynamic err, StackTrace stack) {
|
||||
globals.printTrace('Echoing stdin to the pub subprocess failed:');
|
||||
globals.printTrace('$err\n$stack');
|
||||
_logger.printTrace('Echoing stdin to the pub subprocess failed:');
|
||||
_logger.printTrace('$err\n$stack');
|
||||
}
|
||||
));
|
||||
|
||||
// Pipe the pub stdout and stderr to the tool stdout and stderr.
|
||||
try {
|
||||
await Future.wait<dynamic>(<Future<dynamic>>[
|
||||
globals.stdio.addStdoutStream(process.stdout),
|
||||
globals.stdio.addStderrStream(process.stderr),
|
||||
stdio.addStdoutStream(process.stdout),
|
||||
stdio.addStderrStream(process.stderr),
|
||||
]);
|
||||
} on Exception catch (err, stack) {
|
||||
globals.printTrace('Echoing stdout or stderr from the pub subprocess failed:');
|
||||
globals.printTrace('$err\n$stack');
|
||||
_logger.printTrace('Echoing stdout or stderr from the pub subprocess failed:');
|
||||
_logger.printTrace('$err\n$stack');
|
||||
}
|
||||
|
||||
// Wait for pub to exit.
|
||||
@ -341,12 +379,65 @@ class _DefaultPub implements Pub {
|
||||
|
||||
/// The command used for running pub.
|
||||
List<String> _pubCommand(List<String> arguments) {
|
||||
return <String>[sdkBinaryName('pub'), ...arguments];
|
||||
// TODO(jonahwilliams): refactor to use artifacts.
|
||||
final String sdkPath = _fileSystem.path.joinAll(<String>[
|
||||
Cache.flutterRoot,
|
||||
'bin',
|
||||
'cache',
|
||||
'dart-sdk',
|
||||
'bin',
|
||||
if (_platform.isWindows)
|
||||
'pub.bat'
|
||||
else
|
||||
'pub'
|
||||
]);
|
||||
return <String>[sdkPath, ...arguments];
|
||||
}
|
||||
|
||||
bool _shouldRunPubGet({ @required File pubSpecYaml, @required File packageConfigFile }) {
|
||||
if (!packageConfigFile.existsSync()) {
|
||||
return true;
|
||||
}
|
||||
final DateTime dotPackagesLastModified = packageConfigFile.lastModifiedSync();
|
||||
if (pubSpecYaml.lastModifiedSync().isAfter(dotPackagesLastModified)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef MessageFilter = String Function(String message);
|
||||
// Returns the environment value that should be used when running pub.
|
||||
//
|
||||
// Includes any existing environment variable, if one exists.
|
||||
//
|
||||
// [context] provides extra information to package server requests to
|
||||
// understand usage.
|
||||
Future<String> _getPubEnvironmentValue(PubContext pubContext) async {
|
||||
// DO NOT update this function without contacting kevmoo.
|
||||
// We have server-side tooling that assumes the values are consistent.
|
||||
final String existing = _platform.environment[_kPubEnvironmentKey];
|
||||
final List<String> values = <String>[
|
||||
if (existing != null && existing.isNotEmpty) existing,
|
||||
if (await _botDetector.isRunningOnBot) 'flutter_bot',
|
||||
'flutter_cli',
|
||||
...pubContext._values,
|
||||
];
|
||||
return values.join(':');
|
||||
}
|
||||
|
||||
String _getRootPubCacheIfAvailable() {
|
||||
if (_platform.environment.containsKey(_kPubCacheEnvironmentKey)) {
|
||||
return _platform.environment[_kPubCacheEnvironmentKey];
|
||||
}
|
||||
|
||||
final String cachePath = _fileSystem.path.join(Cache.flutterRoot, '.pub-cache');
|
||||
if (_fileSystem.directory(cachePath).existsSync()) {
|
||||
_logger.printTrace('Using $cachePath for the pub cache.');
|
||||
return cachePath;
|
||||
}
|
||||
|
||||
// Use pub's default location by returning null.
|
||||
return null;
|
||||
}
|
||||
|
||||
/// The full environment used when running pub.
|
||||
///
|
||||
@ -355,67 +446,12 @@ typedef MessageFilter = String Function(String message);
|
||||
Future<Map<String, String>> _createPubEnvironment(PubContext context, [ String flutterRootOverride ]) async {
|
||||
final Map<String, String> environment = <String, String>{
|
||||
'FLUTTER_ROOT': flutterRootOverride ?? Cache.flutterRoot,
|
||||
_pubEnvironmentKey: await _getPubEnvironmentValue(context),
|
||||
_kPubEnvironmentKey: await _getPubEnvironmentValue(context),
|
||||
};
|
||||
final String pubCache = _getRootPubCacheIfAvailable();
|
||||
if (pubCache != null) {
|
||||
environment[_pubCacheEnvironmentKey] = pubCache;
|
||||
environment[_kPubCacheEnvironmentKey] = pubCache;
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
|
||||
final RegExp _analyzerWarning = RegExp(r'^! \w+ [^ ]+ from path \.\./\.\./bin/cache/dart-sdk/lib/\w+$');
|
||||
|
||||
/// The console environment key used by the pub tool.
|
||||
const String _pubEnvironmentKey = 'PUB_ENVIRONMENT';
|
||||
|
||||
/// The console environment key used by the pub tool to find the cache directory.
|
||||
const String _pubCacheEnvironmentKey = 'PUB_CACHE';
|
||||
|
||||
/// Returns the environment value that should be used when running pub.
|
||||
///
|
||||
/// Includes any existing environment variable, if one exists.
|
||||
///
|
||||
/// [context] provides extra information to package server requests to
|
||||
/// understand usage.
|
||||
Future<String> _getPubEnvironmentValue(PubContext pubContext) async {
|
||||
// DO NOT update this function without contacting kevmoo.
|
||||
// We have server-side tooling that assumes the values are consistent.
|
||||
final String existing = globals.platform.environment[_pubEnvironmentKey];
|
||||
final List<String> values = <String>[
|
||||
if (existing != null && existing.isNotEmpty) existing,
|
||||
if (await globals.isRunningOnBot) 'flutter_bot',
|
||||
'flutter_cli',
|
||||
...pubContext._values,
|
||||
];
|
||||
return values.join(':');
|
||||
}
|
||||
|
||||
String _getRootPubCacheIfAvailable() {
|
||||
if (globals.platform.environment.containsKey(_pubCacheEnvironmentKey)) {
|
||||
return globals.platform.environment[_pubCacheEnvironmentKey];
|
||||
}
|
||||
|
||||
final String cachePath = globals.fs.path.join(Cache.flutterRoot, '.pub-cache');
|
||||
if (globals.fs.directory(cachePath).existsSync()) {
|
||||
globals.printTrace('Using $cachePath for the pub cache.');
|
||||
return cachePath;
|
||||
}
|
||||
|
||||
// Use pub's default location by returning null.
|
||||
return null;
|
||||
}
|
||||
|
||||
String _filterOverrideWarnings(String message) {
|
||||
// This function filters out these three messages:
|
||||
// Warning: You are using these overridden dependencies:
|
||||
// ! analyzer 0.29.0-alpha.0 from path ../../bin/cache/dart-sdk/lib/analyzer
|
||||
// ! front_end 0.1.0-alpha.0 from path ../../bin/cache/dart-sdk/lib/front_end
|
||||
if (message == 'Warning: You are using these overridden dependencies:') {
|
||||
return null;
|
||||
}
|
||||
if (message.contains(_analyzerWarning)) {
|
||||
return null;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
@ -129,7 +129,8 @@ class PubResultEvent extends UsageEvent {
|
||||
PubResultEvent({
|
||||
@required String context,
|
||||
@required String result,
|
||||
}) : super('pub-result', context, label: result, flutterUsage: globals.flutterUsage);
|
||||
@required Usage usage,
|
||||
}) : super('pub-result', context, label: result, flutterUsage: usage);
|
||||
}
|
||||
|
||||
/// An event that reports something about a build.
|
||||
|
@ -15,6 +15,7 @@ import 'package:flutter_tools/src/dart/sdk.dart';
|
||||
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:process/process.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
@ -65,7 +66,15 @@ void main() {
|
||||
testUsingContext('AnalysisServer success', () async {
|
||||
_createSampleProject(tempDir);
|
||||
|
||||
await const Pub().get(context: PubContext.flutterTests, directory: tempDir.path);
|
||||
final Pub pub = Pub(
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
processManager: processManager,
|
||||
platform: const LocalPlatform(),
|
||||
botDetector: globals.botDetector,
|
||||
usage: globals.flutterUsage,
|
||||
);
|
||||
await pub.get(context: PubContext.flutterTests, directory: tempDir.path);
|
||||
|
||||
server = AnalysisServer(dartSdkPath, <String>[tempDir.path],
|
||||
fileSystem: fileSystem,
|
||||
@ -90,7 +99,15 @@ void main() {
|
||||
testUsingContext('AnalysisServer errors', () async {
|
||||
_createSampleProject(tempDir, brokenCode: true);
|
||||
|
||||
await const Pub().get(context: PubContext.flutterTests, directory: tempDir.path);
|
||||
final Pub pub = Pub(
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
processManager: processManager,
|
||||
platform: const LocalPlatform(),
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
);
|
||||
await pub.get(context: PubContext.flutterTests, directory: tempDir.path);
|
||||
|
||||
server = AnalysisServer(dartSdkPath, <String>[tempDir.path],
|
||||
fileSystem: fileSystem,
|
||||
|
@ -86,7 +86,14 @@ void main() {
|
||||
);
|
||||
return _runFlutterTest(projectDir);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('can create a default project if empty directory exists', () async {
|
||||
@ -104,7 +111,14 @@ void main() {
|
||||
],
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('creates a module project correctly', () async {
|
||||
@ -126,7 +140,14 @@ void main() {
|
||||
]);
|
||||
return _runFlutterTest(projectDir);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('cannot create a project if non-empty non-project directory exists with .metadata', () async {
|
||||
@ -144,7 +165,14 @@ void main() {
|
||||
]),
|
||||
throwsToolExit(message: 'Sorry, unable to detect the type of project to recreate'));
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
...noColorTerminalOverride,
|
||||
});
|
||||
|
||||
@ -170,7 +198,14 @@ void main() {
|
||||
],
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('detects and recreates an app project correctly', () async {
|
||||
@ -195,7 +230,14 @@ void main() {
|
||||
],
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('detects and recreates a plugin project correctly', () async {
|
||||
@ -220,7 +262,14 @@ void main() {
|
||||
],
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('detects and recreates a package project correctly', () async {
|
||||
@ -251,7 +300,14 @@ void main() {
|
||||
],
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('kotlin/swift legacy app project', () async {
|
||||
@ -273,7 +329,14 @@ void main() {
|
||||
],
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('can create a package project', () async {
|
||||
@ -303,7 +366,14 @@ void main() {
|
||||
);
|
||||
return _runFlutterTest(projectDir);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('can create a plugin project', () async {
|
||||
@ -325,7 +395,14 @@ void main() {
|
||||
);
|
||||
return _runFlutterTest(projectDir.childDirectory('example'));
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('plugin example app depends on plugin', () async {
|
||||
@ -344,7 +421,14 @@ void main() {
|
||||
final PathDependency pathDependency = pubspec.dependencies[pluginName] as PathDependency;
|
||||
expect(pathDependency.path, '../');
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('kotlin/swift plugin project', () async {
|
||||
@ -429,7 +513,14 @@ void main() {
|
||||
<String>['lib/main.dart'],
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('module project with pub', () async {
|
||||
@ -464,7 +555,14 @@ void main() {
|
||||
'.android/Flutter/src/main/java/io/flutter/facade/Flutter.java',
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
@ -1038,7 +1136,14 @@ void main() {
|
||||
],
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('can re-gen module .ios/ folder, reusing custom org', () async {
|
||||
@ -1055,7 +1160,14 @@ void main() {
|
||||
'com.bar.foo.flutterProject',
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('can re-gen app android/ folder, reusing custom org', () async {
|
||||
@ -1210,7 +1322,14 @@ void main() {
|
||||
],
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext(
|
||||
@ -1227,7 +1346,14 @@ void main() {
|
||||
},
|
||||
overrides: <Type, Generator>{
|
||||
ProcessManager: () => loggingProcessManager,
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
@ -1245,7 +1371,14 @@ void main() {
|
||||
},
|
||||
overrides: <Type, Generator>{
|
||||
ProcessManager: () => loggingProcessManager,
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -195,7 +195,14 @@ void main() {
|
||||
expectDependenciesResolved(projectPath);
|
||||
expectZeroPluginsInjected(projectPath);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('get --offline fetches packages', () async {
|
||||
@ -208,7 +215,14 @@ void main() {
|
||||
expectDependenciesResolved(projectPath);
|
||||
expectZeroPluginsInjected(projectPath);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('set the number of plugins as usage value', () async {
|
||||
@ -222,7 +236,14 @@ void main() {
|
||||
expect(await getCommand.usageValues,
|
||||
containsPair(CustomDimensions.commandPackagesNumberPlugins, '0'));
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('indicate that the project is not a module in usage value', () async {
|
||||
@ -236,7 +257,14 @@ void main() {
|
||||
expect(await getCommand.usageValues,
|
||||
containsPair(CustomDimensions.commandPackagesProjectModule, 'false'));
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('indicate that the project is a module in usage value', () async {
|
||||
@ -250,7 +278,14 @@ void main() {
|
||||
expect(await getCommand.usageValues,
|
||||
containsPair(CustomDimensions.commandPackagesProjectModule, 'true'));
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('indicate that Android project reports v1 in usage value', () async {
|
||||
@ -265,7 +300,14 @@ void main() {
|
||||
containsPair(CustomDimensions.commandPackagesAndroidEmbeddingVersion, 'v1'));
|
||||
}, overrides: <Type, Generator>{
|
||||
FeatureFlags: () => TestFeatureFlags(isAndroidEmbeddingV2Enabled: false),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('indicate that Android project reports v2 in usage value', () async {
|
||||
@ -280,7 +322,14 @@ void main() {
|
||||
containsPair(CustomDimensions.commandPackagesAndroidEmbeddingVersion, 'v2'));
|
||||
}, overrides: <Type, Generator>{
|
||||
FeatureFlags: () => TestFeatureFlags(isAndroidEmbeddingV2Enabled: true),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('upgrade fetches packages', () async {
|
||||
@ -293,7 +342,14 @@ void main() {
|
||||
expectDependenciesResolved(projectPath);
|
||||
expectZeroPluginsInjected(projectPath);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('get fetches packages and injects plugin', () async {
|
||||
@ -306,7 +362,14 @@ void main() {
|
||||
expectDependenciesResolved(projectPath);
|
||||
expectModulePluginInjected(projectPath);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('get fetches packages and injects plugin in plugin project', () async {
|
||||
@ -327,7 +390,14 @@ void main() {
|
||||
expectDependenciesResolved(exampleProjectPath);
|
||||
expectPluginInjected(exampleProjectPath);
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
@ -351,7 +421,14 @@ void main() {
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
BotDetector: () => const AlwaysFalseBotDetector(),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('test with bot', () async {
|
||||
@ -366,7 +443,14 @@ void main() {
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
BotDetector: () => const AlwaysTrueBotDetector(),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('run', () async {
|
||||
@ -380,7 +464,14 @@ void main() {
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('pub publish', () async {
|
||||
@ -405,7 +496,14 @@ void main() {
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('pub publish input fails', () async {
|
||||
@ -426,7 +524,14 @@ void main() {
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('publish', () async {
|
||||
@ -439,7 +544,14 @@ void main() {
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
BotDetector: () => const AlwaysTrueBotDetector(),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('packages publish', () async {
|
||||
@ -452,7 +564,14 @@ void main() {
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
BotDetector: () => const AlwaysTrueBotDetector(),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('deps', () async {
|
||||
@ -465,7 +584,14 @@ void main() {
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
BotDetector: () => const AlwaysTrueBotDetector(),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('cache', () async {
|
||||
@ -478,7 +604,14 @@ void main() {
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
BotDetector: () => const AlwaysTrueBotDetector(),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('version', () async {
|
||||
@ -491,7 +624,14 @@ void main() {
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
BotDetector: () => const AlwaysTrueBotDetector(),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('uploader', () async {
|
||||
@ -504,7 +644,14 @@ void main() {
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
BotDetector: () => const AlwaysTrueBotDetector(),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('global', () async {
|
||||
@ -518,7 +665,14 @@ void main() {
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
BotDetector: () => const AlwaysTrueBotDetector(),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('outdated', () async {
|
||||
@ -531,7 +685,14 @@ void main() {
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Stdio: () => mockStdio,
|
||||
BotDetector: () => const AlwaysTrueBotDetector(),
|
||||
Pub: () => const Pub(),
|
||||
Pub: () => Pub(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
usage: globals.flutterUsage,
|
||||
botDetector: globals.botDetector,
|
||||
platform: globals.platform,
|
||||
),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -3,73 +3,81 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/bot_detector.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/context.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/dart/pub.dart';
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:process/process.dart';
|
||||
import 'package:quiver/testing/async.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
|
||||
import 'package:flutter_tools/src/base/bot_detector.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/dart/pub.dart';
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/mocks.dart' as mocks;
|
||||
import '../../src/testbed.dart';
|
||||
|
||||
void main() {
|
||||
setUpAll(() {
|
||||
Cache.flutterRoot = getFlutterRoot();
|
||||
Cache.flutterRoot = '';
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
MockDirectory.findCache = false;
|
||||
});
|
||||
|
||||
testUsingContext('pub get 69', () async {
|
||||
testWithoutContext('pub get 69', () async {
|
||||
String error;
|
||||
|
||||
final MockProcessManager processMock = context.get<ProcessManager>() as MockProcessManager;
|
||||
final MockProcessManager processMock = MockProcessManager(69);
|
||||
final BufferLogger logger = BufferLogger.test();
|
||||
final Pub pub = Pub(
|
||||
fileSystem: MockFileSystem(),
|
||||
logger: logger,
|
||||
processManager: processMock,
|
||||
usage: MockUsage(),
|
||||
platform: FakePlatform(
|
||||
environment: const <String, String>{},
|
||||
),
|
||||
botDetector: const BotDetectorAlwaysNo(),
|
||||
);
|
||||
|
||||
FakeAsync().run((FakeAsync time) {
|
||||
expect(processMock.lastPubEnvironment, isNull);
|
||||
expect(testLogger.statusText, '');
|
||||
expect(logger.statusText, '');
|
||||
pub.get(context: PubContext.flutterTests, checkLastModified: false).then((void value) {
|
||||
error = 'test completed unexpectedly';
|
||||
}, onError: (dynamic thrownError) {
|
||||
error = 'test failed unexpectedly: $thrownError';
|
||||
});
|
||||
time.elapse(const Duration(milliseconds: 500));
|
||||
expect(testLogger.statusText,
|
||||
expect(logger.statusText,
|
||||
'Running "flutter pub get" in /...\n'
|
||||
'pub get failed (server unavailable) -- attempting retry 1 in 1 second...\n',
|
||||
);
|
||||
expect(processMock.lastPubEnvironment, contains('flutter_cli:flutter_tests'));
|
||||
expect(processMock.lastPubCache, isNull);
|
||||
time.elapse(const Duration(milliseconds: 500));
|
||||
expect(testLogger.statusText,
|
||||
expect(logger.statusText,
|
||||
'Running "flutter pub get" in /...\n'
|
||||
'pub get failed (server unavailable) -- attempting retry 1 in 1 second...\n'
|
||||
'pub get failed (server unavailable) -- attempting retry 2 in 2 seconds...\n',
|
||||
);
|
||||
time.elapse(const Duration(seconds: 1));
|
||||
expect(testLogger.statusText,
|
||||
expect(logger.statusText,
|
||||
'Running "flutter pub get" in /...\n'
|
||||
'pub get failed (server unavailable) -- attempting retry 1 in 1 second...\n'
|
||||
'pub get failed (server unavailable) -- attempting retry 2 in 2 seconds...\n',
|
||||
);
|
||||
time.elapse(const Duration(seconds: 100)); // from t=0 to t=100
|
||||
expect(testLogger.statusText,
|
||||
expect(logger.statusText,
|
||||
'Running "flutter pub get" in /...\n'
|
||||
'pub get failed (server unavailable) -- attempting retry 1 in 1 second...\n'
|
||||
'pub get failed (server unavailable) -- attempting retry 2 in 2 seconds...\n'
|
||||
@ -80,7 +88,7 @@ void main() {
|
||||
'pub get failed (server unavailable) -- attempting retry 7 in 64 seconds...\n', // at t=61
|
||||
);
|
||||
time.elapse(const Duration(seconds: 200)); // from t=0 to t=200
|
||||
expect(testLogger.statusText,
|
||||
expect(logger.statusText,
|
||||
'Running "flutter pub get" in /...\n'
|
||||
'pub get failed (server unavailable) -- attempting retry 1 in 1 second...\n'
|
||||
'pub get failed (server unavailable) -- attempting retry 2 in 2 seconds...\n'
|
||||
@ -94,49 +102,51 @@ void main() {
|
||||
'pub get failed (server unavailable) -- attempting retry 10 in 64 seconds...\n', // at t=167
|
||||
);
|
||||
});
|
||||
expect(testLogger.errorText, isEmpty);
|
||||
expect(logger.errorText, isEmpty);
|
||||
expect(error, isNull);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => MockFileSystem(),
|
||||
ProcessManager: () => MockProcessManager(69),
|
||||
Platform: () => FakePlatform(
|
||||
environment: UnmodifiableMapView<String, String>(<String, String>{}),
|
||||
),
|
||||
Pub: () => const Pub(),
|
||||
});
|
||||
|
||||
testUsingContext('pub get 66 shows message from pub', () async {
|
||||
testWithoutContext('pub get 66 shows message from pub', () async {
|
||||
final BufferLogger logger = BufferLogger.test();
|
||||
final Pub pub = Pub(
|
||||
platform: FakePlatform(environment: const <String, String>{}),
|
||||
fileSystem: MockFileSystem(),
|
||||
logger: logger,
|
||||
usage: MockUsage(),
|
||||
botDetector: const BotDetectorAlwaysNo(),
|
||||
processManager: MockProcessManager(66, stderr: 'err1\nerr2\nerr3\n', stdout: 'out1\nout2\nout3\n'),
|
||||
);
|
||||
try {
|
||||
await pub.get(context: PubContext.flutterTests, checkLastModified: false);
|
||||
throw AssertionError('pubGet did not fail');
|
||||
} on ToolExit catch (error) {
|
||||
expect(error.message, 'pub get failed (66; err3)');
|
||||
}
|
||||
expect(testLogger.statusText,
|
||||
expect(logger.statusText,
|
||||
'Running "flutter pub get" in /...\n'
|
||||
'out1\n'
|
||||
'out2\n'
|
||||
'out3\n'
|
||||
);
|
||||
expect(testLogger.errorText,
|
||||
expect(logger.errorText,
|
||||
'err1\n'
|
||||
'err2\n'
|
||||
'err3\n'
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => MockProcessManager(66, stderr: 'err1\nerr2\nerr3\n', stdout: 'out1\nout2\nout3\n'),
|
||||
FileSystem: () => MockFileSystem(),
|
||||
Platform: () => FakePlatform(
|
||||
environment: UnmodifiableMapView<String, String>(<String, String>{}),
|
||||
),
|
||||
Pub: () => const Pub(),
|
||||
});
|
||||
|
||||
testUsingContext('pub cache in root is used', () async {
|
||||
testWithoutContext('pub cache in root is used', () async {
|
||||
String error;
|
||||
|
||||
final MockProcessManager processMock = context.get<ProcessManager>() as MockProcessManager;
|
||||
final MockFileSystem fsMock = context.get<FileSystem>() as MockFileSystem;
|
||||
final MockProcessManager processMock = MockProcessManager(69);
|
||||
final MockFileSystem fsMock = MockFileSystem();
|
||||
final Pub pub = Pub(
|
||||
platform: FakePlatform(environment: const <String, String>{}),
|
||||
usage: MockUsage(),
|
||||
fileSystem: fsMock,
|
||||
logger: BufferLogger.test(),
|
||||
processManager: processMock,
|
||||
botDetector: const BotDetectorAlwaysNo(),
|
||||
);
|
||||
|
||||
FakeAsync().run((FakeAsync time) {
|
||||
MockDirectory.findCache = true;
|
||||
@ -148,124 +158,137 @@ void main() {
|
||||
error = 'test failed unexpectedly: $thrownError';
|
||||
});
|
||||
time.elapse(const Duration(milliseconds: 500));
|
||||
|
||||
expect(processMock.lastPubCache, equals(fsMock.path.join(Cache.flutterRoot, '.pub-cache')));
|
||||
expect(error, isNull);
|
||||
});
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => MockFileSystem(),
|
||||
ProcessManager: () => MockProcessManager(69),
|
||||
Platform: () => FakePlatform(
|
||||
environment: UnmodifiableMapView<String, String>(<String, String>{}),
|
||||
),
|
||||
Pub: () => const Pub(),
|
||||
});
|
||||
|
||||
testUsingContext('pub cache in environment is used', () async {
|
||||
String error;
|
||||
|
||||
final MockProcessManager processMock = context.get<ProcessManager>() as MockProcessManager;
|
||||
testWithoutContext('pub cache in environment is used', () async {
|
||||
final MockProcessManager processMock = MockProcessManager(69);
|
||||
final Pub pub = Pub(
|
||||
fileSystem: MockFileSystem(),
|
||||
logger: BufferLogger.test(),
|
||||
processManager: processMock,
|
||||
usage: MockUsage(),
|
||||
botDetector: const BotDetectorAlwaysNo(),
|
||||
platform: FakePlatform(
|
||||
environment: const <String, String>{
|
||||
'PUB_CACHE': 'custom/pub-cache/path',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
FakeAsync().run((FakeAsync time) {
|
||||
MockDirectory.findCache = true;
|
||||
expect(processMock.lastPubEnvironment, isNull);
|
||||
expect(processMock.lastPubCache, isNull);
|
||||
|
||||
String error;
|
||||
pub.get(context: PubContext.flutterTests, checkLastModified: false).then((void value) {
|
||||
error = 'test completed unexpectedly';
|
||||
}, onError: (dynamic thrownError) {
|
||||
error = 'test failed unexpectedly: $thrownError';
|
||||
});
|
||||
time.elapse(const Duration(milliseconds: 500));
|
||||
|
||||
expect(processMock.lastPubCache, equals('custom/pub-cache/path'));
|
||||
expect(error, isNull);
|
||||
});
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => MockFileSystem(),
|
||||
ProcessManager: () => MockProcessManager(69),
|
||||
Platform: () => FakePlatform(
|
||||
environment: UnmodifiableMapView<String, String>(<String, String>{
|
||||
'PUB_CACHE': 'custom/pub-cache/path',
|
||||
}),
|
||||
),
|
||||
Pub: () => const Pub(),
|
||||
});
|
||||
|
||||
testUsingContext('analytics sent on success', () async {
|
||||
testWithoutContext('analytics sent on success', () async {
|
||||
MockDirectory.findCache = true;
|
||||
final MockUsage usage = MockUsage();
|
||||
final Pub pub = Pub(
|
||||
fileSystem: MockFileSystem(),
|
||||
logger: BufferLogger.test(),
|
||||
processManager: MockProcessManager(0),
|
||||
botDetector: const BotDetectorAlwaysNo(),
|
||||
usage: usage,
|
||||
platform: FakePlatform(
|
||||
environment: const <String, String>{
|
||||
'PUB_CACHE': 'custom/pub-cache/path',
|
||||
}
|
||||
),
|
||||
);
|
||||
|
||||
await pub.get(context: PubContext.flutterTests, checkLastModified: false);
|
||||
verify(globals.flutterUsage.sendEvent('pub-result', 'flutter-tests', label: 'success')).called(1);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => MockFileSystem(),
|
||||
ProcessManager: () => MockProcessManager(0),
|
||||
Platform: () => FakePlatform(
|
||||
environment: UnmodifiableMapView<String, String>(<String, String>{
|
||||
'PUB_CACHE': 'custom/pub-cache/path',
|
||||
}),
|
||||
),
|
||||
Usage: () => MockUsage(),
|
||||
Pub: () => const Pub(),
|
||||
|
||||
verify(usage.sendEvent('pub-result', 'flutter-tests', label: 'success')).called(1);
|
||||
});
|
||||
|
||||
testUsingContext('analytics sent on failure', () async {
|
||||
testWithoutContext('analytics sent on failure', () async {
|
||||
MockDirectory.findCache = true;
|
||||
final MockUsage usage = MockUsage();
|
||||
final Pub pub = Pub(
|
||||
usage: usage,
|
||||
fileSystem: MockFileSystem(),
|
||||
logger: BufferLogger.test(),
|
||||
processManager: MockProcessManager(1),
|
||||
botDetector: const BotDetectorAlwaysNo(),
|
||||
platform: FakePlatform(
|
||||
environment: const <String, String>{
|
||||
'PUB_CACHE': 'custom/pub-cache/path',
|
||||
},
|
||||
),
|
||||
);
|
||||
try {
|
||||
await pub.get(context: PubContext.flutterTests, checkLastModified: false);
|
||||
} on ToolExit {
|
||||
// Ignore.
|
||||
}
|
||||
verify(globals.flutterUsage.sendEvent('pub-result', 'flutter-tests', label: 'failure')).called(1);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => MockFileSystem(),
|
||||
ProcessManager: () => MockProcessManager(1),
|
||||
Platform: () => FakePlatform(
|
||||
environment: UnmodifiableMapView<String, String>(<String, String>{
|
||||
'PUB_CACHE': 'custom/pub-cache/path',
|
||||
}),
|
||||
),
|
||||
Usage: () => MockUsage(),
|
||||
Pub: () => const Pub(),
|
||||
|
||||
verify(usage.sendEvent('pub-result', 'flutter-tests', label: 'failure')).called(1);
|
||||
});
|
||||
|
||||
testUsingContext('analytics sent on failed version solve', () async {
|
||||
testWithoutContext('analytics sent on failed version solve', () async {
|
||||
MockDirectory.findCache = true;
|
||||
try {
|
||||
await pub.get(context: PubContext.flutterTests, checkLastModified: false);
|
||||
} on ToolExit {
|
||||
// Ignore.
|
||||
}
|
||||
verify(globals.flutterUsage.sendEvent('pub-result', 'flutter-tests', label: 'version-solving-failed')).called(1);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => MockFileSystem(),
|
||||
ProcessManager: () => MockProcessManager(
|
||||
final MockUsage usage = MockUsage();
|
||||
final Pub pub = Pub(
|
||||
fileSystem: MockFileSystem(),
|
||||
logger: BufferLogger.test(),
|
||||
processManager: MockProcessManager(
|
||||
1,
|
||||
stderr: 'version solving failed',
|
||||
),
|
||||
Platform: () => FakePlatform(
|
||||
environment: UnmodifiableMapView<String, String>(<String, String>{
|
||||
platform: FakePlatform(
|
||||
environment: <String, String>{
|
||||
'PUB_CACHE': 'custom/pub-cache/path',
|
||||
}),
|
||||
},
|
||||
),
|
||||
Usage: () => MockUsage(),
|
||||
Pub: () => const Pub(),
|
||||
usage: usage,
|
||||
botDetector: const BotDetectorAlwaysNo(),
|
||||
);
|
||||
|
||||
try {
|
||||
await pub.get(context: PubContext.flutterTests, checkLastModified: false);
|
||||
} on ToolExit {
|
||||
// Ignore.
|
||||
}
|
||||
|
||||
verify(usage.sendEvent('pub-result', 'flutter-tests', label: 'version-solving-failed')).called(1);
|
||||
});
|
||||
|
||||
test('Pub error handling', () async {
|
||||
final MemoryFileSystem fileSystem = MemoryFileSystem();
|
||||
testWithoutContext('Pub error handling', () async {
|
||||
final BufferLogger logger = BufferLogger.test();
|
||||
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
|
||||
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
FakeCommand(
|
||||
command: const <String>[
|
||||
'/bin/cache/dart-sdk/bin/pub',
|
||||
'bin/cache/dart-sdk/bin/pub',
|
||||
'--verbosity=warning',
|
||||
'get',
|
||||
'--no-precompile',
|
||||
],
|
||||
onRun: () {
|
||||
globals.fs.file('.packages')
|
||||
fileSystem.file('.dart_tool/package_config.json')
|
||||
.setLastModifiedSync(DateTime(2002));
|
||||
}
|
||||
),
|
||||
const FakeCommand(
|
||||
command: <String>[
|
||||
'/bin/cache/dart-sdk/bin/pub',
|
||||
'bin/cache/dart-sdk/bin/pub',
|
||||
'--verbosity=warning',
|
||||
'get',
|
||||
'--no-precompile',
|
||||
@ -273,56 +296,71 @@ void main() {
|
||||
),
|
||||
FakeCommand(
|
||||
command: const <String>[
|
||||
'/bin/cache/dart-sdk/bin/pub',
|
||||
'bin/cache/dart-sdk/bin/pub',
|
||||
'--verbosity=warning',
|
||||
'get',
|
||||
'--no-precompile',
|
||||
],
|
||||
onRun: () {
|
||||
globals.fs.file('pubspec.yaml')
|
||||
fileSystem.file('pubspec.yaml')
|
||||
.setLastModifiedSync(DateTime(2002));
|
||||
}
|
||||
),
|
||||
const FakeCommand(
|
||||
command: <String>[
|
||||
'/bin/cache/dart-sdk/bin/pub',
|
||||
'bin/cache/dart-sdk/bin/pub',
|
||||
'--verbosity=warning',
|
||||
'get',
|
||||
'--no-precompile',
|
||||
],
|
||||
),
|
||||
]);
|
||||
await Testbed().run(() async {
|
||||
final Pub pub = Pub(
|
||||
usage: MockUsage(),
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
processManager: processManager,
|
||||
platform: FakePlatform(
|
||||
operatingSystem: 'linux', // so that the command executed is consistent
|
||||
environment: <String, String>{},
|
||||
),
|
||||
botDetector: const BotDetectorAlwaysNo()
|
||||
);
|
||||
|
||||
// the good scenario: .packages is old, pub updates the file.
|
||||
globals.fs.file('.packages')
|
||||
..createSync()
|
||||
fileSystem.file('.dart_tool/package_config.json')
|
||||
..createSync(recursive: true)
|
||||
..setLastModifiedSync(DateTime(2000));
|
||||
globals.fs.file('pubspec.yaml')
|
||||
fileSystem.file('pubspec.yaml')
|
||||
..createSync()
|
||||
..setLastModifiedSync(DateTime(2001));
|
||||
await pub.get(context: PubContext.flutterTests, checkLastModified: true); // pub sets date of .packages to 2002
|
||||
expect(testLogger.statusText, 'Running "flutter pub get" in /...\n');
|
||||
expect(testLogger.errorText, isEmpty);
|
||||
expect(globals.fs.file('pubspec.yaml').lastModifiedSync(), DateTime(2001)); // because nothing should touch it
|
||||
expect(globals.fs.file('.packages').lastModifiedSync(), isNot(DateTime(2000))); // because pub changes it to 2002
|
||||
expect(globals.fs.file('.packages').lastModifiedSync(), isNot(DateTime(2002))); // because we set the timestamp again after pub
|
||||
testLogger.clear();
|
||||
|
||||
expect(logger.statusText, 'Running "flutter pub get" in /...\n');
|
||||
expect(logger.errorText, isEmpty);
|
||||
expect(fileSystem.file('pubspec.yaml').lastModifiedSync(), DateTime(2001)); // because nothing should touch it
|
||||
expect(fileSystem.file('.dart_tool/package_config.json').lastModifiedSync(), isNot(DateTime(2000))); // because pub changes it to 2002
|
||||
expect(fileSystem.file('.dart_tool/package_config.json').lastModifiedSync(), isNot(DateTime(2002))); // because we set the timestamp again after pub
|
||||
logger.clear();
|
||||
|
||||
// bad scenario 1: pub doesn't update file; doesn't matter, because we do instead
|
||||
globals.fs.file('.packages')
|
||||
fileSystem.file('.dart_tool/package_config.json')
|
||||
.setLastModifiedSync(DateTime(2000));
|
||||
globals.fs.file('pubspec.yaml')
|
||||
fileSystem.file('pubspec.yaml')
|
||||
.setLastModifiedSync(DateTime(2001));
|
||||
await pub.get(context: PubContext.flutterTests, checkLastModified: true); // pub does nothing
|
||||
expect(testLogger.statusText, 'Running "flutter pub get" in /...\n');
|
||||
expect(testLogger.errorText, isEmpty);
|
||||
expect(globals.fs.file('pubspec.yaml').lastModifiedSync(), DateTime(2001)); // because nothing should touch it
|
||||
expect(globals.fs.file('.packages').lastModifiedSync(), isNot(DateTime(2000))); // because we set the timestamp
|
||||
expect(globals.fs.file('.packages').lastModifiedSync(), isNot(DateTime(2002))); // just in case FakeProcessManager is buggy
|
||||
testLogger.clear();
|
||||
|
||||
expect(logger.statusText, 'Running "flutter pub get" in /...\n');
|
||||
expect(logger.errorText, isEmpty);
|
||||
expect(fileSystem.file('pubspec.yaml').lastModifiedSync(), DateTime(2001)); // because nothing should touch it
|
||||
expect(fileSystem.file('.dart_tool/package_config.json').lastModifiedSync(), isNot(DateTime(2000))); // because we set the timestamp
|
||||
expect(fileSystem.file('.dart_tool/package_config.json').lastModifiedSync(), isNot(DateTime(2002))); // just in case FakeProcessManager is buggy
|
||||
logger.clear();
|
||||
|
||||
// bad scenario 2: pub changes pubspec.yaml instead
|
||||
globals.fs.file('.packages')
|
||||
fileSystem.file('.dart_tool/package_config.json')
|
||||
.setLastModifiedSync(DateTime(2000));
|
||||
globals.fs.file('pubspec.yaml')
|
||||
fileSystem.file('pubspec.yaml')
|
||||
.setLastModifiedSync(DateTime(2001));
|
||||
try {
|
||||
await pub.get(context: PubContext.flutterTests, checkLastModified: true);
|
||||
@ -330,39 +368,33 @@ void main() {
|
||||
} on ToolExit catch (error) {
|
||||
expect(error.message, '/: unexpected concurrent modification of pubspec.yaml while running pub.');
|
||||
}
|
||||
expect(testLogger.statusText, 'Running "flutter pub get" in /...\n');
|
||||
expect(testLogger.errorText, isEmpty);
|
||||
expect(globals.fs.file('pubspec.yaml').lastModifiedSync(), DateTime(2002)); // because fake pub above touched it
|
||||
expect(globals.fs.file('.packages').lastModifiedSync(), DateTime(2000)); // because nothing touched it
|
||||
expect(logger.statusText, 'Running "flutter pub get" in /...\n');
|
||||
expect(logger.errorText, isEmpty);
|
||||
expect(fileSystem.file('pubspec.yaml').lastModifiedSync(), DateTime(2002)); // because fake pub above touched it
|
||||
expect(fileSystem.file('.dart_tool/package_config.json').lastModifiedSync(), DateTime(2000)); // because nothing touched it
|
||||
|
||||
// bad scenario 3: pubspec.yaml was created in the future
|
||||
globals.fs.file('.packages')
|
||||
fileSystem.file('.dart_tool/package_config.json')
|
||||
.setLastModifiedSync(DateTime(2000));
|
||||
globals.fs.file('pubspec.yaml')
|
||||
fileSystem.file('pubspec.yaml')
|
||||
.setLastModifiedSync(DateTime(9999));
|
||||
assert(DateTime(9999).isAfter(DateTime.now()));
|
||||
|
||||
await pub.get(context: PubContext.flutterTests, checkLastModified: true); // pub does nothing
|
||||
expect(testLogger.statusText, contains('Running "flutter pub get" in /...\n'));
|
||||
expect(testLogger.errorText, startsWith(
|
||||
|
||||
expect(logger.statusText, contains('Running "flutter pub get" in /...\n'));
|
||||
expect(logger.errorText, startsWith(
|
||||
'Warning: File "/pubspec.yaml" was created in the future. Optimizations that rely on '
|
||||
'comparing time stamps will be unreliable. Check your system clock for accuracy.\n'
|
||||
'The timestamp was:'
|
||||
));
|
||||
testLogger.clear();
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
Pub: () => const Pub(),
|
||||
Platform: () => FakePlatform(
|
||||
operatingSystem: 'linux', // so that the command executed is consistent
|
||||
environment: <String, String>{},
|
||||
),
|
||||
BotDetector: () => const BotDetectorAlwaysNo(), // so that the test never adds --trace to the pub command
|
||||
});
|
||||
logger.clear();
|
||||
});
|
||||
}
|
||||
|
||||
class BotDetectorAlwaysNo implements BotDetector {
|
||||
const BotDetectorAlwaysNo();
|
||||
|
||||
@override
|
||||
Future<bool> get isRunningOnBot async => false;
|
||||
}
|
||||
@ -405,7 +437,7 @@ class MockProcessManager implements ProcessManager {
|
||||
}
|
||||
|
||||
class MockFileSystem extends ForwardingFileSystem {
|
||||
MockFileSystem() : super(MemoryFileSystem());
|
||||
MockFileSystem() : super(MemoryFileSystem.test());
|
||||
|
||||
@override
|
||||
File file(dynamic path) {
|
||||
|
@ -4,7 +4,9 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/dart/pub.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
class ThrowingPub implements Pub {
|
||||
@override
|
||||
@ -34,7 +36,7 @@ class ThrowingPub implements Pub {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> interactively(List<String> arguments, {String directory}) {
|
||||
Future<void> interactively(List<String> arguments, {String directory, @required Stdio stdio,}) {
|
||||
throw UnsupportedError('Attempted to invoke pub during test.');
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user