Unverified Commit 3fd36200 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Lazily download artifacts (III) (#27903)

parent d4a441a0
......@@ -134,4 +134,7 @@ class _FuchsiaAttachCommand extends AttachCommand {
Cache.flutterRoot = '$originalWorkingDirectory/third_party/dart-pkg/git/flutter';
return super.runCommand();
}
@override
Future<void> updateCache() async {}
}
......@@ -84,7 +84,6 @@ BuildApp() {
local framework_path="${FLUTTER_ROOT}/bin/cache/artifacts/engine/${artifact_variant}"
AssertExists "${framework_path}"
AssertExists "${project_path}"
local derived_dir="${SOURCE_ROOT}/Flutter"
......@@ -123,6 +122,12 @@ BuildApp() {
flutter_podspec="${FLUTTER_ENGINE}/out/${LOCAL_ENGINE}/Flutter.podspec"
fi
# If the framework path does not exist, ensure that it is downloaded.
if [[ ! -e "$1" ]]; then
FLUTTER_ALREADY_LOCKED = "true"
RunCommand "${FLUTTER_ROOT}/bin/flutter" precache --suppress-analytics
fi
if [[ -e "${project_path}/.ios" ]]; then
RunCommand rm -rf -- "${derived_dir}/engine"
mkdir "${derived_dir}/engine"
......
......@@ -37,7 +37,8 @@ Future<List<int>> _attempt(Uri url, { bool onlyHeaders = false }) async {
printTrace('Downloading: $url');
HttpClient httpClient;
if (context[HttpClientFactory] != null) {
httpClient = (context[HttpClientFactory] as HttpClientFactory)(); // ignore: avoid_as
final HttpClientFactory httpClientFactory = context[HttpClientFactory];
httpClient = httpClientFactory();
} else {
httpClient = HttpClient();
}
......@@ -64,9 +65,9 @@ Future<List<int>> _attempt(Uri url, { bool onlyHeaders = false }) async {
// If we're making a HEAD request, we're only checking to see if the URL is
// valid.
if (onlyHeaders) {
return (response.statusCode == 200) ? <int>[] : null;
return (response.statusCode == HttpStatus.ok) ? <int>[] : null;
}
if (response.statusCode != 200) {
if (response.statusCode != HttpStatus.ok) {
if (response.statusCode > 0 && response.statusCode < 500) {
throwToolExit(
'Download failed.\n'
......
This diff is collapsed.
......@@ -49,9 +49,15 @@ class BuildIOSCommand extends BuildSubCommand {
final String description = 'Build an iOS application bundle (Mac OS X host only).';
@override
Future<FlutterCommandResult> runCommand() async {
final bool forSimulator = argResults['simulator'];
Future<void> validateCommand() async {
defaultBuildMode = forSimulator ? BuildMode.debug : BuildMode.release;
return super.validateCommand();
}
bool get forSimulator => argResults['simulator'];
@override
Future<FlutterCommandResult> runCommand() async {
if (getCurrentHostPlatform() != HostPlatform.darwin_x64)
throwToolExit('Building for iOS is only supported on the Mac.');
......
......@@ -212,8 +212,6 @@ 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();
final String flutterRoot = fs.path.absolute(Cache.flutterRoot);
final String flutterPackagesDirectory = fs.path.join(flutterRoot, 'packages');
......
......@@ -223,8 +223,6 @@ class IdeConfigCommand extends FlutterCommand {
throwToolExit('Currently, the only supported IDE is IntelliJ\n$usage', exitCode: 2);
}
await Cache.instance.updateAll();
if (argResults['update-templates']) {
_handleTemplateUpdate();
return null;
......
......@@ -4,6 +4,7 @@
import 'dart:async';
import '../cache.dart';
import '../globals.dart';
import '../runner/flutter_command.dart';
......@@ -11,6 +12,8 @@ class PrecacheCommand extends FlutterCommand {
PrecacheCommand() {
argParser.addFlag('all-platforms', abbr: 'a', negatable: false,
help: 'Precache artifacts for all platforms.');
argParser.addFlag('force', abbr: 'f', negatable: false,
help: 'Force download of new cached artifacts');
}
@override
......@@ -24,14 +27,18 @@ class PrecacheCommand extends FlutterCommand {
@override
Future<FlutterCommandResult> runCommand() async {
if (argResults['all-platforms'])
if (argResults['all-platforms']) {
cache.includeAllPlatforms = true;
if (cache.isUpToDate())
}
final UpdateResult result = cache.isUpToDate(skipUnknown: false);
if (result.isUpToDate && !result.clobber && !argResults['force']) {
printStatus('Already up-to-date.');
else
await cache.updateAll();
return null;
} else {
await cache.updateAll(
skipUnknown: false,
clobber: argResults['force'] || result.clobber,
);
}
return const FlutterCommandResult(ExitStatus.success);
}
}
......@@ -327,30 +327,43 @@ abstract class FlutterCommand extends Command<void> {
}
BuildMode getBuildMode() {
final List<bool> modeFlags = <bool>[argResults['debug'], argResults['profile'], argResults['release']];
if (modeFlags.where((bool flag) => flag).length > 1)
bool debug;
bool profile;
bool release;
if (argParser.options.containsKey('debug')) {
debug = argResults['debug'];
} else {
debug = _defaultBuildMode == BuildMode.debug;
}
if (argParser.options.containsKey('profile')) {
profile = argResults['profile'];
} else {
profile = _defaultBuildMode == BuildMode.profile;
}
if (argParser.options.containsKey('release')) {
release = argResults['release'];
} else {
release = _defaultBuildMode == BuildMode.release;
}
if (debug && profile || debug && release || release && profile) {
throw UsageException('Only one of --debug, --profile, or --release can be specified.', null);
}
final bool dynamicFlag = argParser.options.containsKey('dynamic')
? argResults['dynamic']
: false;
if (argResults['debug']) {
if (dynamicFlag)
if (debug) {
if (dynamicFlag) {
throw ToolExit('Error: --dynamic requires --release or --profile.');
}
return BuildMode.debug;
}
if (argResults['profile'])
if (profile) {
return dynamicFlag ? BuildMode.dynamicProfile : BuildMode.profile;
if (argResults['release'])
}
if (release) {
return dynamicFlag ? BuildMode.dynamicRelease : BuildMode.release;
if (_defaultBuildMode == BuildMode.debug && dynamicFlag)
throw ToolExit('Error: --dynamic requires --release or --profile.');
if (_defaultBuildMode == BuildMode.release && dynamicFlag)
return BuildMode.dynamicRelease;
if (_defaultBuildMode == BuildMode.profile && dynamicFlag)
return BuildMode.dynamicProfile;
}
return _defaultBuildMode;
}
......@@ -388,7 +401,7 @@ abstract class FlutterCommand extends Command<void> {
'--patch-number (${argResults['patch-number']}) must be an int.', null);
}
String extraFrontEndOptions =
List<String> extraFrontEndOptions =
argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions)
? argResults[FlutterOptions.kExtraFrontEndOptions]
: null;
......@@ -397,9 +410,9 @@ abstract class FlutterCommand extends Command<void> {
for (String expFlag in argResults[FlutterOptions.kEnableExperiment]) {
final String flag = '--enable-experiment=' + expFlag;
if (extraFrontEndOptions != null) {
extraFrontEndOptions += ',' + flag;
extraFrontEndOptions.add(flag);
} else {
extraFrontEndOptions = flag;
extraFrontEndOptions = <String>[flag];
}
}
}
......@@ -425,9 +438,9 @@ abstract class FlutterCommand extends Command<void> {
baselineDir: argParser.options.containsKey('baseline-dir')
? argResults['baseline-dir']
: null,
extraFrontEndOptions: extraFrontEndOptions,
extraFrontEndOptions: extraFrontEndOptions?.join(', '),
extraGenSnapshotOptions: argParser.options.containsKey(FlutterOptions.kExtraGenSnapshotOptions)
? argResults[FlutterOptions.kExtraGenSnapshotOptions]
? argResults[FlutterOptions.kExtraGenSnapshotOptions]?.join(', ')
: null,
buildSharedLibrary: argParser.options.containsKey('build-shared-library')
? argResults['build-shared-library']
......@@ -517,6 +530,33 @@ abstract class FlutterCommand extends Command<void> {
);
}
/// A hook called to populate the cache with a particular target platform
/// or build mode.
///
/// If a command requires specific artifacts, it is it's responsibility to
/// request them here.
Future<void> updateCache() async {
// Download all artifacts unless told otherwise.
await cache.updateAll(
buildModes: <BuildMode>[
BuildMode.debug,
BuildMode.release,
BuildMode.profile,
BuildMode.dynamicProfile,
BuildMode.dynamicRelease,
],
targetPlatforms: <TargetPlatform>[
TargetPlatform.android_arm,
TargetPlatform.android_arm64,
TargetPlatform.android_x64,
TargetPlatform.android_x86,
TargetPlatform.ios,
],
clobber: false,
skipUnknown: true,
);
}
/// Perform validation then call [runCommand] to execute the command.
/// Return a [Future] that completes with an exit code
/// indicating whether execution was successful.
......@@ -527,11 +567,11 @@ abstract class FlutterCommand extends Command<void> {
@mustCallSuper
Future<FlutterCommandResult> verifyThenRunCommand(String commandPath) async {
await validateCommand();
// 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 updateCache();
}
if (shouldRunPub) {
await pubGet(context: PubContext.getVerifyContext(name));
......
This diff is collapsed.
......@@ -42,7 +42,12 @@ void main() {
testUsingContext('honors shouldUpdateCache true', () async {
final DummyFlutterCommand flutterCommand = DummyFlutterCommand(shouldUpdateCache: true);
await flutterCommand.run();
verify(cache.updateAll()).called(1);
verify(cache.updateAll(
buildModes: anyNamed('buildModes'),
clobber: anyNamed('clobber'),
skipUnknown: anyNamed('skipUnknown'),
targetPlatforms: anyNamed('targetPlatforms')
)).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