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

Lazy cache 4 (#29785)

parent 6e50ccc8
......@@ -85,7 +85,6 @@ class AOTSnapshotter {
if (fs.file('pubspec.yaml').existsSync()) {
flutterProject = await FlutterProject.current();
}
final FlutterEngine engine = FlutterEngine(cache);
if (!_isValidAotPlatform(platform, buildMode)) {
printError('${getNameForTargetPlatform(platform)} does not support AOT compilation.');
return 1;
......@@ -187,7 +186,7 @@ class AOTSnapshotter {
'entryPoint': mainPath,
'sharedLib': buildSharedLibrary.toString(),
'extraGenSnapshotOptions': extraGenSnapshotOptions.join(' '),
'engineHash': engine.version,
'engineHash': Cache.instance.engineRevision,
'buildersUsed': '${flutterProject != null ? flutterProject.hasBuilders : false}',
},
depfilePaths: <String>[],
......
This diff is collapsed.
......@@ -64,6 +64,11 @@ class AnalyzeCommand extends FlutterCommand {
@override
String get description => "Analyze the project's Dart code.";
@override
Set<DevelopmentArtifact> get requiredArtifacts => const <DevelopmentArtifact>{
DevelopmentArtifact.universal,
};
@override
bool get shouldRunPub {
// If they're not analyzing the current project.
......
......@@ -8,7 +8,7 @@ import '../base/common.dart';
import '../base/logger.dart';
import '../build_info.dart';
import '../globals.dart';
import '../runner/flutter_command.dart' show FlutterCommandResult;
import '../runner/flutter_command.dart' show DevelopmentArtifact, FlutterCommandResult;
import '../web/compile.dart';
import 'build.dart';
......@@ -19,6 +19,12 @@ class BuildWebCommand extends BuildSubCommand {
defaultBuildMode = BuildMode.release;
}
@override
Set<DevelopmentArtifact> get requiredArtifacts => const <DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.web,
};
@override
final String name = 'web';
......
......@@ -245,7 +245,7 @@ class CreateCommand extends FlutterCommand {
throwToolExit('Neither the --flutter-root command line flag nor the FLUTTER_ROOT environment '
'variable was specified. Unable to find package:flutter.', exitCode: 2);
await Cache.instance.updateAll();
await Cache.instance.updateAll(<DevelopmentArtifact>{ DevelopmentArtifact.universal });
final String flutterRoot = fs.path.absolute(Cache.flutterRoot);
......
......@@ -223,7 +223,7 @@ class IdeConfigCommand extends FlutterCommand {
throwToolExit('Currently, the only supported IDE is IntelliJ\n$usage', exitCode: 2);
}
await Cache.instance.updateAll();
await Cache.instance.updateAll(<DevelopmentArtifact>{ DevelopmentArtifact.universal });
if (argResults['update-templates']) {
_handleTemplateUpdate();
......
......@@ -4,6 +4,7 @@
import 'dart:async';
import '../cache.dart';
import '../globals.dart';
import '../runner/flutter_command.dart';
......@@ -11,6 +12,12 @@ class PrecacheCommand extends FlutterCommand {
PrecacheCommand() {
argParser.addFlag('all-platforms', abbr: 'a', negatable: false,
help: 'Precache artifacts for all platforms.');
argParser.addFlag('android', negatable: true, defaultsTo: true,
help: 'Precache artifacts for Android development');
argParser.addFlag('ios', negatable: true, defaultsTo: true,
help: 'Precache artifacts for iOS developemnt');
argParser.addFlag('web', negatable: true, defaultsTo: false,
help: 'Precache artifacts for web development');
}
@override
......@@ -24,14 +31,25 @@ class PrecacheCommand extends FlutterCommand {
@override
Future<FlutterCommandResult> runCommand() async {
if (argResults['all-platforms'])
if (argResults['all-platforms']) {
cache.includeAllPlatforms = true;
if (cache.isUpToDate())
}
final Set<DevelopmentArtifact> requiredArtifacts = <DevelopmentArtifact>{ DevelopmentArtifact.universal };
if (argResults['android']) {
requiredArtifacts.add(DevelopmentArtifact.android);
}
if (argResults['ios']) {
requiredArtifacts.add(DevelopmentArtifact.iOS);
}
if (argResults['web']) {
requiredArtifacts.add(DevelopmentArtifact.web);
}
if (cache.isUpToDate(requiredArtifacts)) {
printStatus('Already up-to-date.');
else
await cache.updateAll();
} else {
await cache.updateAll(requiredArtifacts);
}
return null;
}
}
......@@ -232,7 +232,6 @@ class KernelCompiler {
if (fs.file('pubspec.yaml').existsSync()) {
flutterProject = await FlutterProject.current();
}
final FlutterEngine engine = FlutterEngine(cache);
// TODO(cbracken): eliminate pathFilter.
// Currently the compiler emits buildbot paths for the core libs in the
......@@ -246,7 +245,7 @@ class KernelCompiler {
'entryPoint': mainPath,
'trackWidgetCreation': trackWidgetCreation.toString(),
'linkPlatformKernelIn': linkPlatformKernelIn.toString(),
'engineHash': engine.version,
'engineHash': Cache.instance.engineRevision,
'buildersUsed': '${flutterProject != null ? flutterProject.hasBuilders : false}',
},
depfilePaths: <String>[depFilePath],
......
......@@ -170,9 +170,7 @@ class Doctor {
}
Future<bool> checkRemoteArtifacts(String engineRevision) async {
final Cache cache = Cache();
final FlutterEngine engine = FlutterEngine(cache);
return await engine.areRemoteArtifactsAvailable(engineVersion: engineRevision);
return Cache.instance.areRemoteArtifactsAvailable(engineVersion: engineRevision);
}
/// Print information about the state of installed tooling.
......
......@@ -19,6 +19,7 @@ import '../base/user_messages.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../bundle.dart' as bundle;
import '../cache.dart';
import '../dart/package_map.dart';
import '../dart/pub.dart';
import '../device.dart';
......@@ -28,6 +29,8 @@ import '../project.dart';
import '../usage.dart';
import 'flutter_command_runner.dart';
export '../cache.dart' show DevelopmentArtifact;
enum ExitStatus {
success,
warning,
......@@ -530,8 +533,9 @@ abstract class FlutterCommand extends Command<void> {
// Populate the cache. We call this before pub get below so that the sky_engine
// package is available in the flutter cache for pub to find.
if (shouldUpdateCache)
await cache.updateAll();
if (shouldUpdateCache) {
await cache.updateAll(requiredArtifacts);
}
if (shouldRunPub) {
await pubGet(context: PubContext.getVerifyContext(name));
......@@ -549,6 +553,16 @@ abstract class FlutterCommand extends Command<void> {
return await runCommand();
}
/// The set of development artifacts required for this command.
///
/// Defaults to [DevelopmentArtifact.universal],
/// [DevelopmentArtifact.android], and [DevelopmentArtifact.iOS].
Set<DevelopmentArtifact> get requiredArtifacts => const <DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.iOS,
DevelopmentArtifact.android,
};
/// Subclasses must implement this to execute the command.
/// Optionally provide a [FlutterCommandResult] to send more details about the
/// execution for analytics.
......
......@@ -84,34 +84,34 @@ void main() {
test('should not be up to date, if some cached artifact is not', () {
final CachedArtifact artifact1 = MockCachedArtifact();
final CachedArtifact artifact2 = MockCachedArtifact();
when(artifact1.isUpToDate()).thenReturn(true);
when(artifact2.isUpToDate()).thenReturn(false);
when(artifact1.isUpToDate(const <DevelopmentArtifact>{})).thenReturn(true);
when(artifact2.isUpToDate(const <DevelopmentArtifact>{})).thenReturn(false);
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
expect(cache.isUpToDate(), isFalse);
expect(cache.isUpToDate(const <DevelopmentArtifact>{}), isFalse);
});
test('should be up to date, if all cached artifacts are', () {
final CachedArtifact artifact1 = MockCachedArtifact();
final CachedArtifact artifact2 = MockCachedArtifact();
when(artifact1.isUpToDate()).thenReturn(true);
when(artifact2.isUpToDate()).thenReturn(true);
when(artifact1.isUpToDate(const <DevelopmentArtifact>{})).thenReturn(true);
when(artifact2.isUpToDate(const <DevelopmentArtifact>{})).thenReturn(true);
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
expect(cache.isUpToDate(), isTrue);
expect(cache.isUpToDate(const <DevelopmentArtifact>{}), isTrue);
});
test('should update cached artifacts which are not up to date', () async {
final CachedArtifact artifact1 = MockCachedArtifact();
final CachedArtifact artifact2 = MockCachedArtifact();
when(artifact1.isUpToDate()).thenReturn(true);
when(artifact2.isUpToDate()).thenReturn(false);
when(artifact1.isUpToDate(const <DevelopmentArtifact>{})).thenReturn(true);
when(artifact2.isUpToDate(const <DevelopmentArtifact>{})).thenReturn(false);
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
await cache.updateAll();
await cache.updateAll(const <DevelopmentArtifact>{});
verifyNever(artifact1.update());
verify(artifact2.update());
});
testUsingContext('failed storage.googleapis.com download shows China warning', () async {
final CachedArtifact artifact1 = MockCachedArtifact();
final CachedArtifact artifact2 = MockCachedArtifact();
when(artifact1.isUpToDate()).thenReturn(false);
when(artifact2.isUpToDate()).thenReturn(false);
when(artifact1.isUpToDate(const <DevelopmentArtifact>{})).thenReturn(false);
when(artifact2.isUpToDate(const <DevelopmentArtifact>{})).thenReturn(false);
final MockInternetAddress address = MockInternetAddress();
when(address.host).thenReturn('storage.googleapis.com');
when(artifact1.update()).thenThrow(SocketException(
......@@ -120,7 +120,7 @@ void main() {
));
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
try {
await cache.updateAll();
await cache.updateAll(const <DevelopmentArtifact>{});
fail('Mock thrown exception expected');
} catch (e) {
verify(artifact1.update());
......
......@@ -42,7 +42,7 @@ void main() {
testUsingContext('honors shouldUpdateCache true', () async {
final DummyFlutterCommand flutterCommand = DummyFlutterCommand(shouldUpdateCache: true);
await flutterCommand.run();
verify(cache.updateAll()).called(1);
verify(cache.updateAll(any)).called(1);
},
overrides: <Type, Generator>{
Cache: () => cache,
......
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