Improve flutter test startup time (#29404)
This commit is contained in:
parent
cf12c31465
commit
b123846cb0
@ -10,6 +10,7 @@ import '../base/file_system.dart';
|
|||||||
import '../base/platform.dart';
|
import '../base/platform.dart';
|
||||||
import '../cache.dart';
|
import '../cache.dart';
|
||||||
import '../codegen.dart';
|
import '../codegen.dart';
|
||||||
|
import '../dart/pub.dart';
|
||||||
import '../project.dart';
|
import '../project.dart';
|
||||||
import '../runner/flutter_command.dart';
|
import '../runner/flutter_command.dart';
|
||||||
import '../test/coverage_collector.dart';
|
import '../test/coverage_collector.dart';
|
||||||
@ -17,7 +18,7 @@ import '../test/event_printer.dart';
|
|||||||
import '../test/runner.dart';
|
import '../test/runner.dart';
|
||||||
import '../test/watcher.dart';
|
import '../test/watcher.dart';
|
||||||
|
|
||||||
class TestCommand extends FlutterCommand {
|
class TestCommand extends FastFlutterCommand {
|
||||||
TestCommand({ bool verboseHelp = false }) {
|
TestCommand({ bool verboseHelp = false }) {
|
||||||
requiresPubspecYaml();
|
requiresPubspecYaml();
|
||||||
usesPubOption();
|
usesPubOption();
|
||||||
@ -91,8 +92,7 @@ class TestCommand extends FlutterCommand {
|
|||||||
String get description => 'Run Flutter unit tests for the current project.';
|
String get description => 'Run Flutter unit tests for the current project.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> validateCommand() async {
|
Future<FlutterCommandResult> runCommand() async {
|
||||||
await super.validateCommand();
|
|
||||||
if (!fs.isFileSync('pubspec.yaml')) {
|
if (!fs.isFileSync('pubspec.yaml')) {
|
||||||
throwToolExit(
|
throwToolExit(
|
||||||
'Error: No pubspec.yaml file found in the current working directory.\n'
|
'Error: No pubspec.yaml file found in the current working directory.\n'
|
||||||
@ -100,10 +100,9 @@ class TestCommand extends FlutterCommand {
|
|||||||
'called *_test.dart and must reside in the package\'s \'test\' '
|
'called *_test.dart and must reside in the package\'s \'test\' '
|
||||||
'directory (or one of its subdirectories).');
|
'directory (or one of its subdirectories).');
|
||||||
}
|
}
|
||||||
}
|
if (shouldRunPub) {
|
||||||
|
await pubGet(context: PubContext.getVerifyContext(name), skipPubspecYamlCheck: true);
|
||||||
@override
|
}
|
||||||
Future<FlutterCommandResult> runCommand() async {
|
|
||||||
final List<String> names = argResults['name'];
|
final List<String> names = argResults['name'];
|
||||||
final List<String> plainNames = argResults['plain-name'];
|
final List<String> plainNames = argResults['plain-name'];
|
||||||
final FlutterProject flutterProject = await FlutterProject.current();
|
final FlutterProject flutterProject = await FlutterProject.current();
|
||||||
|
@ -76,13 +76,14 @@ Future<void> pubGet({
|
|||||||
bool upgrade = false,
|
bool upgrade = false,
|
||||||
bool offline = false,
|
bool offline = false,
|
||||||
bool checkLastModified = true,
|
bool checkLastModified = true,
|
||||||
|
bool skipPubspecYamlCheck = false
|
||||||
}) async {
|
}) async {
|
||||||
directory ??= fs.currentDirectory.path;
|
directory ??= fs.currentDirectory.path;
|
||||||
|
|
||||||
final File pubSpecYaml = fs.file(fs.path.join(directory, 'pubspec.yaml'));
|
final File pubSpecYaml = fs.file(fs.path.join(directory, 'pubspec.yaml'));
|
||||||
final File dotPackages = fs.file(fs.path.join(directory, '.packages'));
|
final File dotPackages = fs.file(fs.path.join(directory, '.packages'));
|
||||||
|
|
||||||
if (!pubSpecYaml.existsSync()) {
|
if (!skipPubspecYamlCheck && !pubSpecYaml.existsSync()) {
|
||||||
if (!skipIfAbsent)
|
if (!skipIfAbsent)
|
||||||
throwToolExit('$directory: no pubspec.yaml found');
|
throwToolExit('$directory: no pubspec.yaml found');
|
||||||
return;
|
return;
|
||||||
|
@ -662,3 +662,15 @@ abstract class FlutterCommand extends Command<void> {
|
|||||||
|
|
||||||
ApplicationPackageStore applicationPackages;
|
ApplicationPackageStore applicationPackages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A command which runs less analytics and checks to speed up startup time.
|
||||||
|
abstract class FastFlutterCommand extends FlutterCommand {
|
||||||
|
@override
|
||||||
|
Future<void> run() {
|
||||||
|
return context.run<void>(
|
||||||
|
name: 'command',
|
||||||
|
overrides: <Type, Generator>{FlutterCommand: () => this},
|
||||||
|
body: runCommand,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -275,6 +275,7 @@ class _Compiler {
|
|||||||
flutterProject: flutterProject,
|
flutterProject: flutterProject,
|
||||||
trackWidgetCreation: trackWidgetCreation,
|
trackWidgetCreation: trackWidgetCreation,
|
||||||
compilerMessageConsumer: reportCompilerMessage,
|
compilerMessageConsumer: reportCompilerMessage,
|
||||||
|
initializeFromDill: testFilePath,
|
||||||
// We already ran codegen once at the start, we only need to
|
// We already ran codegen once at the start, we only need to
|
||||||
// configure builders.
|
// configure builders.
|
||||||
runCold: true,
|
runCold: true,
|
||||||
|
@ -20,28 +20,17 @@ import 'globals.dart';
|
|||||||
class FlutterVersion {
|
class FlutterVersion {
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
FlutterVersion([this._clock = const SystemClock()]) {
|
FlutterVersion([this._clock = const SystemClock()]) {
|
||||||
_channel = _runGit('git rev-parse --abbrev-ref --symbolic @{u}');
|
|
||||||
final String branch = _runGit('git rev-parse --abbrev-ref HEAD');
|
|
||||||
_branch = branch == 'HEAD' ? _channel : branch;
|
|
||||||
|
|
||||||
final int slash = _channel.indexOf('/');
|
|
||||||
if (slash != -1) {
|
|
||||||
final String remote = _channel.substring(0, slash);
|
|
||||||
_repositoryUrl = _runGit('git ls-remote --get-url $remote');
|
|
||||||
_channel = _channel.substring(slash + 1);
|
|
||||||
} else if (_channel.isEmpty) {
|
|
||||||
_channel = 'unknown';
|
|
||||||
}
|
|
||||||
|
|
||||||
_frameworkRevision = _runGit('git log -n 1 --pretty=format:%H');
|
_frameworkRevision = _runGit('git log -n 1 --pretty=format:%H');
|
||||||
_frameworkAge = _runGit('git log -n 1 --pretty=format:%ar');
|
|
||||||
_frameworkVersion = GitTagVersion.determine().frameworkVersionFor(_frameworkRevision);
|
_frameworkVersion = GitTagVersion.determine().frameworkVersionFor(_frameworkRevision);
|
||||||
}
|
}
|
||||||
|
|
||||||
final SystemClock _clock;
|
final SystemClock _clock;
|
||||||
|
|
||||||
String _repositoryUrl;
|
String _repositoryUrl;
|
||||||
String get repositoryUrl => _repositoryUrl;
|
String get repositoryUrl {
|
||||||
|
final String _ = channel;
|
||||||
|
return _repositoryUrl;
|
||||||
|
}
|
||||||
|
|
||||||
static const Set<String> officialChannels = <String>{
|
static const Set<String> officialChannels = <String>{
|
||||||
'master',
|
'master',
|
||||||
@ -64,7 +53,22 @@ class FlutterVersion {
|
|||||||
String _channel;
|
String _channel;
|
||||||
/// The channel is the upstream branch.
|
/// The channel is the upstream branch.
|
||||||
/// `master`, `dev`, `beta`, `stable`; or old ones, like `alpha`, `hackathon`, ...
|
/// `master`, `dev`, `beta`, `stable`; or old ones, like `alpha`, `hackathon`, ...
|
||||||
String get channel => _channel;
|
String get channel {
|
||||||
|
if (_channel == null) {
|
||||||
|
final String channel = _runGit('git rev-parse --abbrev-ref --symbolic @{u}');
|
||||||
|
final int slash = channel.indexOf('/');
|
||||||
|
if (slash != -1) {
|
||||||
|
final String remote = channel.substring(0, slash);
|
||||||
|
_repositoryUrl = _runGit('git ls-remote --get-url $remote');
|
||||||
|
_channel = channel.substring(slash + 1);
|
||||||
|
} else if (channel.isEmpty) {
|
||||||
|
_channel = 'unknown';
|
||||||
|
} else {
|
||||||
|
_channel = channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _channel;
|
||||||
|
}
|
||||||
|
|
||||||
/// The name of the local branch.
|
/// The name of the local branch.
|
||||||
/// Use getBranchName() to read this.
|
/// Use getBranchName() to read this.
|
||||||
@ -75,7 +79,9 @@ class FlutterVersion {
|
|||||||
String get frameworkRevisionShort => _shortGitRevision(frameworkRevision);
|
String get frameworkRevisionShort => _shortGitRevision(frameworkRevision);
|
||||||
|
|
||||||
String _frameworkAge;
|
String _frameworkAge;
|
||||||
String get frameworkAge => _frameworkAge;
|
String get frameworkAge {
|
||||||
|
return _frameworkAge ??= _runGit('git log -n 1 --pretty=format:%ar');
|
||||||
|
}
|
||||||
|
|
||||||
String _frameworkVersion;
|
String _frameworkVersion;
|
||||||
String get frameworkVersion => _frameworkVersion;
|
String get frameworkVersion => _frameworkVersion;
|
||||||
@ -182,6 +188,10 @@ class FlutterVersion {
|
|||||||
/// If [redactUnknownBranches] is true and the branch is unknown,
|
/// If [redactUnknownBranches] is true and the branch is unknown,
|
||||||
/// the branch name will be returned as `'[user-branch]'`.
|
/// the branch name will be returned as `'[user-branch]'`.
|
||||||
String getBranchName({ bool redactUnknownBranches = false }) {
|
String getBranchName({ bool redactUnknownBranches = false }) {
|
||||||
|
_branch ??= () {
|
||||||
|
final String branch = _runGit('git rev-parse --abbrev-ref HEAD');
|
||||||
|
return branch == 'HEAD' ? channel : branch;
|
||||||
|
}();
|
||||||
if (redactUnknownBranches || _branch.isEmpty) {
|
if (redactUnknownBranches || _branch.isEmpty) {
|
||||||
// Only return the branch names we know about; arbitrary branch names might contain PII.
|
// Only return the branch names we know about; arbitrary branch names might contain PII.
|
||||||
if (!officialChannels.contains(_branch) && !obsoleteBranches.containsKey(_branch))
|
if (!officialChannels.contains(_branch) && !obsoleteBranches.containsKey(_branch))
|
||||||
@ -266,7 +276,7 @@ class FlutterVersion {
|
|||||||
/// writes shared cache files.
|
/// writes shared cache files.
|
||||||
Future<void> checkFlutterVersionFreshness() async {
|
Future<void> checkFlutterVersionFreshness() async {
|
||||||
// Don't perform update checks if we're not on an official channel.
|
// Don't perform update checks if we're not on an official channel.
|
||||||
if (!officialChannels.contains(_channel)) {
|
if (!officialChannels.contains(channel)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +369,7 @@ class FlutterVersion {
|
|||||||
|
|
||||||
// Cache is empty or it's been a while since the last server ping. Ping the server.
|
// Cache is empty or it's been a while since the last server ping. Ping the server.
|
||||||
try {
|
try {
|
||||||
final DateTime remoteFrameworkCommitDate = DateTime.parse(await FlutterVersion.fetchRemoteFrameworkCommitDate(_channel));
|
final DateTime remoteFrameworkCommitDate = DateTime.parse(await FlutterVersion.fetchRemoteFrameworkCommitDate(channel));
|
||||||
await versionCheckStamp.store(
|
await versionCheckStamp.store(
|
||||||
newTimeVersionWasChecked: _clock.now(),
|
newTimeVersionWasChecked: _clock.now(),
|
||||||
newKnownRemoteVersion: remoteFrameworkCommitDate,
|
newKnownRemoteVersion: remoteFrameworkCommitDate,
|
||||||
|
@ -1001,6 +1001,17 @@ Future<void> _runFlutterTest(Directory workingDir, { String target }) async {
|
|||||||
'flutter_tools.dart',
|
'flutter_tools.dart',
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// While flutter test does get packages, it doesn't write version
|
||||||
|
// files anymore.
|
||||||
|
await Process.run(
|
||||||
|
'$dartSdkPath/bin/dart',
|
||||||
|
<String>[]
|
||||||
|
..addAll(dartVmFlags)
|
||||||
|
..add(flutterToolsPath)
|
||||||
|
..addAll(<String>['packages', 'get']),
|
||||||
|
workingDirectory: workingDir.path,
|
||||||
|
);
|
||||||
|
|
||||||
final List<String> args = <String>[]
|
final List<String> args = <String>[]
|
||||||
..addAll(dartVmFlags)
|
..addAll(dartVmFlags)
|
||||||
..add(flutterToolsPath)
|
..add(flutterToolsPath)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user