[flutter_tools] make precache force blow away stamp files (#61003)
update flutter precache --force to delete all stamp files. In the event that a user is hitting a cache issue, this should be easier than re-downloading all artifacts or manually blowing away the cache. This is probably how it should have worked in the first place
This commit is contained in:
parent
77310c152f
commit
07e2d6f63b
@ -48,6 +48,7 @@ import 'src/commands/train.dart';
|
||||
import 'src/commands/update_packages.dart';
|
||||
import 'src/commands/upgrade.dart';
|
||||
import 'src/commands/version.dart';
|
||||
import 'src/features.dart';
|
||||
import 'src/globals.dart' as globals;
|
||||
import 'src/runner/flutter_command.dart';
|
||||
import 'src/web/compile.dart';
|
||||
@ -98,7 +99,13 @@ Future<void> main(List<String> args) async {
|
||||
LogsCommand(),
|
||||
MakeHostAppEditableCommand(),
|
||||
PackagesCommand(),
|
||||
PrecacheCommand(verboseHelp: verboseHelp),
|
||||
PrecacheCommand(
|
||||
verboseHelp: verboseHelp,
|
||||
cache: globals.cache,
|
||||
logger: globals.logger,
|
||||
platform: globals.platform,
|
||||
featureFlags: featureFlags,
|
||||
),
|
||||
RunCommand(verboseHelp: verboseHelp),
|
||||
ScreenshotCommand(),
|
||||
ShellCompletionCommand(),
|
||||
|
@ -37,6 +37,7 @@ class DevelopmentArtifact {
|
||||
/// Artifacts required for Android development.
|
||||
static const DevelopmentArtifact androidGenSnapshot = DevelopmentArtifact._('android_gen_snapshot');
|
||||
static const DevelopmentArtifact androidMaven = DevelopmentArtifact._('android_maven');
|
||||
|
||||
// Artifacts used for internal builds.
|
||||
static const DevelopmentArtifact androidInternalBuild = DevelopmentArtifact._('android_internal_build');
|
||||
|
||||
@ -243,8 +244,8 @@ class Cache {
|
||||
|
||||
/// Checks if the current process owns the lock for the cache directory at
|
||||
/// this very moment; throws a [StateError] if it doesn't.
|
||||
static void checkLockAcquired() {
|
||||
if (_lockEnabled && _lock == null && globals.platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
||||
static void checkLockAcquired([Platform platform]) {
|
||||
if (_lockEnabled && _lock == null && (platform ?? globals.platform).environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
||||
throw StateError(
|
||||
'The current process does not own the lock for the cache directory. This is a bug in Flutter CLI tools.',
|
||||
);
|
||||
@ -372,6 +373,21 @@ class Cache {
|
||||
return versionFile.existsSync() ? versionFile.readAsStringSync().trim() : null;
|
||||
}
|
||||
|
||||
/// Delete all stamp files maintained by the cache.
|
||||
void clearStampFiles() {
|
||||
try {
|
||||
getStampFileFor('flutter_tools').deleteSync();
|
||||
for (final ArtifactSet artifact in _artifacts) {
|
||||
final File file = getStampFileFor(artifact.stampName);
|
||||
if (file.existsSync()) {
|
||||
file.deleteSync();
|
||||
}
|
||||
}
|
||||
} on FileSystemException catch (err) {
|
||||
_logger.printError('Failed to delete some stamp files: $err');
|
||||
}
|
||||
}
|
||||
|
||||
String getStampFor(String artifactName) {
|
||||
final File stampFile = getStampFileFor(artifactName);
|
||||
return stampFile.existsSync() ? stampFile.readAsStringSync().trim() : null;
|
||||
@ -508,6 +524,13 @@ abstract class ArtifactSet {
|
||||
|
||||
/// Updates the artifact.
|
||||
Future<void> update();
|
||||
|
||||
/// The canonical name of the artifact.
|
||||
String get name;
|
||||
|
||||
// The name of the stamp file. Defaults to the same as the
|
||||
// artifact name.
|
||||
String get stampName => name;
|
||||
}
|
||||
|
||||
/// An artifact set managed by the cache.
|
||||
@ -520,11 +543,10 @@ abstract class CachedArtifact extends ArtifactSet {
|
||||
|
||||
final Cache cache;
|
||||
|
||||
/// The canonical name of the artifact.
|
||||
@override
|
||||
final String name;
|
||||
|
||||
// The name of the stamp file. Defaults to the same as the
|
||||
// artifact name.
|
||||
@override
|
||||
String get stampName => name;
|
||||
|
||||
Directory get location => cache.getArtifactDirectory(name);
|
||||
@ -1043,6 +1065,9 @@ class AndroidMavenArtifacts extends ArtifactSet {
|
||||
// Therefore, call Gradle to figure this out.
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
String get name => 'android-maven-artifacts';
|
||||
}
|
||||
|
||||
class IOSEngineArtifacts extends EngineCachedArtifact {
|
||||
|
@ -4,18 +4,36 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../base/common.dart';
|
||||
import '../base/logger.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../cache.dart';
|
||||
import '../features.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../runner/flutter_command.dart';
|
||||
import '../version.dart';
|
||||
|
||||
/// The flutter precache command allows downloading of cache artifacts without
|
||||
/// the use of device/artifact autodetection.
|
||||
class PrecacheCommand extends FlutterCommand {
|
||||
PrecacheCommand({bool verboseHelp = false}) {
|
||||
PrecacheCommand({
|
||||
bool verboseHelp = false,
|
||||
@required Cache cache,
|
||||
@required Platform platform,
|
||||
@required Logger logger,
|
||||
@required FeatureFlags featureFlags,
|
||||
FlutterVersion flutterVersion, // flutter version cannot be injected.
|
||||
}) : _cache = cache,
|
||||
_platform = platform,
|
||||
_logger = logger,
|
||||
_featureFlags = featureFlags,
|
||||
_flutterVersion = flutterVersion {
|
||||
argParser.addFlag('all-platforms', abbr: 'a', negatable: false,
|
||||
help: 'Precache artifacts for all host platforms.');
|
||||
argParser.addFlag('force', abbr: 'f', negatable: false,
|
||||
help: 'Force downloading of artifacts.');
|
||||
help: 'Force re-downloading of artifacts.');
|
||||
argParser.addFlag('android', negatable: true, defaultsTo: true,
|
||||
help: 'Precache artifacts for Android development.',
|
||||
hide: verboseHelp);
|
||||
@ -48,6 +66,12 @@ class PrecacheCommand extends FlutterCommand {
|
||||
help: 'Precache the unsigned mac binaries when available.', hide: true);
|
||||
}
|
||||
|
||||
final Cache _cache;
|
||||
final Logger _logger;
|
||||
final Platform _platform;
|
||||
final FeatureFlags _featureFlags;
|
||||
final FlutterVersion _flutterVersion;
|
||||
|
||||
@override
|
||||
final String name = 'precache';
|
||||
|
||||
@ -112,26 +136,29 @@ class PrecacheCommand extends FlutterCommand {
|
||||
@override
|
||||
Future<FlutterCommandResult> runCommand() async {
|
||||
// Re-lock the cache.
|
||||
if (globals.platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
||||
if (_platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
||||
await Cache.lock();
|
||||
}
|
||||
if (boolArg('force')) {
|
||||
_cache.clearStampFiles();
|
||||
}
|
||||
|
||||
final bool includeAllPlatforms = boolArg('all-platforms');
|
||||
if (includeAllPlatforms) {
|
||||
globals.cache.includeAllPlatforms = true;
|
||||
_cache.includeAllPlatforms = true;
|
||||
}
|
||||
if (boolArg('use-unsigned-mac-binaries')) {
|
||||
globals.cache.useUnsignedMacBinaries = true;
|
||||
_cache.useUnsignedMacBinaries = true;
|
||||
}
|
||||
globals.cache.platformOverrideArtifacts = _explicitArtifactSelections();
|
||||
_cache.platformOverrideArtifacts = _explicitArtifactSelections();
|
||||
final Map<String, String> umbrellaForArtifact = _umbrellaForArtifactMap();
|
||||
final Set<DevelopmentArtifact> requiredArtifacts = <DevelopmentArtifact>{};
|
||||
for (final DevelopmentArtifact artifact in DevelopmentArtifact.values) {
|
||||
// Don't include unstable artifacts on stable branches.
|
||||
if (!globals.flutterVersion.isMaster && artifact.unstable) {
|
||||
if (!(_flutterVersion ?? globals.flutterVersion).isMaster && artifact.unstable) {
|
||||
continue;
|
||||
}
|
||||
if (artifact.feature != null && !featureFlags.isEnabled(artifact.feature)) {
|
||||
if (artifact.feature != null && !_featureFlags.isEnabled(artifact.feature)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -140,11 +167,10 @@ class PrecacheCommand extends FlutterCommand {
|
||||
requiredArtifacts.add(artifact);
|
||||
}
|
||||
}
|
||||
final bool forceUpdate = boolArg('force');
|
||||
if (forceUpdate || !globals.cache.isUpToDate()) {
|
||||
await globals.cache.updateAll(requiredArtifacts);
|
||||
if (!_cache.isUpToDate()) {
|
||||
await _cache.updateAll(requiredArtifacts);
|
||||
} else {
|
||||
globals.printStatus('Already up-to-date.');
|
||||
_logger.printStatus('Already up-to-date.');
|
||||
}
|
||||
return FlutterCommandResult.success();
|
||||
}
|
||||
|
@ -2,10 +2,10 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/precache.dart';
|
||||
import 'package:flutter_tools/src/features.dart';
|
||||
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
||||
import 'package:flutter_tools/src/version.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
@ -38,38 +38,53 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('precache should acquire lock', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final Platform platform = FakePlatform(environment: <String, String>{});
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
platform: platform,
|
||||
featureFlags: TestFeatureFlags(),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache']);
|
||||
|
||||
expect(Cache.isLocked(), isTrue);
|
||||
// Do not throw StateError, lock is acquired.
|
||||
Cache.checkLockAcquired();
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
expect(() => Cache.checkLockAcquired(platform), returnsNormally);
|
||||
});
|
||||
|
||||
testUsingContext('precache should not re-entrantly acquire lock', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache']);
|
||||
|
||||
expect(Cache.isLocked(), isFalse);
|
||||
// Do not throw StateError, acquired reentrantly with FLUTTER_ALREADY_LOCKED.
|
||||
Cache.checkLockAcquired();
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
Platform: () => FakePlatform(
|
||||
final Platform platform = FakePlatform(
|
||||
operatingSystem: 'windows',
|
||||
environment: <String, String>{
|
||||
'FLUTTER_ROOT': 'flutter',
|
||||
'FLUTTER_ALREADY_LOCKED': 'true',
|
||||
},
|
||||
),
|
||||
);
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(),
|
||||
platform: platform,
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache']);
|
||||
|
||||
expect(Cache.isLocked(), isFalse);
|
||||
// Do not throw StateError, acquired reentrantly with FLUTTER_ALREADY_LOCKED.
|
||||
expect(() => Cache.checkLockAcquired(platform), returnsNormally);
|
||||
});
|
||||
|
||||
testUsingContext('precache downloads web artifacts on dev branch when feature is enabled.', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(isWebEnabled: true),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache', '--web', '--no-android', '--no-ios']);
|
||||
|
||||
@ -77,26 +92,32 @@ void main() {
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.web,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
|
||||
});
|
||||
|
||||
testUsingContext('precache does not download web artifacts on dev branch when feature is enabled.', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(isWebEnabled: false),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache', '--web', '--no-android', '--no-ios']);
|
||||
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: false),
|
||||
});
|
||||
|
||||
testUsingContext('precache downloads macOS artifacts on dev branch when macOS is enabled.', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(isMacOSEnabled: true),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache', '--macos', '--no-android', '--no-ios']);
|
||||
|
||||
@ -104,26 +125,32 @@ void main() {
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.macOS,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
|
||||
});
|
||||
|
||||
testUsingContext('precache does not download macOS artifacts on dev branch when feature is enabled.', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(isMacOSEnabled: false),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache', '--macos', '--no-android', '--no-ios']);
|
||||
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: false),
|
||||
});
|
||||
|
||||
testUsingContext('precache downloads Windows artifacts on dev branch when feature is enabled.', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(isWindowsEnabled: true),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache', '--windows', '--no-android', '--no-ios']);
|
||||
|
||||
@ -131,26 +158,32 @@ void main() {
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.windows,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||
});
|
||||
|
||||
testUsingContext('precache does not download Windows artifacts on dev branch when feature is enabled.', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(isWindowsEnabled: false),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache', '--windows', '--no-android', '--no-ios']);
|
||||
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: false),
|
||||
});
|
||||
|
||||
testUsingContext('precache downloads Linux artifacts on dev branch when feature is enabled.', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(isLinuxEnabled: true),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache', '--linux', '--no-android', '--no-ios']);
|
||||
|
||||
@ -158,39 +191,53 @@ void main() {
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.linux,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
|
||||
});
|
||||
|
||||
testUsingContext('precache does not download Linux artifacts on dev branch when feature is enabled.', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(isLinuxEnabled: false),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache', '--linux', '--no-android', '--no-ios']);
|
||||
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: false),
|
||||
});
|
||||
|
||||
testUsingContext('precache exits if requesting mismatched artifacts.', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(isWebEnabled: false),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
|
||||
expect(createTestCommandRunner(command).run(const <String>['precache',
|
||||
'--no-android',
|
||||
'--android_gen_snapshot',
|
||||
]), throwsToolExit(message: '--android_gen_snapshot requires --android'));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: false),
|
||||
});
|
||||
|
||||
testUsingContext('precache adds artifact flags to requested artifacts', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: masterFlutterVersion,
|
||||
featureFlags: TestFeatureFlags(
|
||||
isWebEnabled: true,
|
||||
isLinuxEnabled: true,
|
||||
isMacOSEnabled: true,
|
||||
isWindowsEnabled: true,
|
||||
),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>[
|
||||
@ -218,19 +265,16 @@ void main() {
|
||||
DevelopmentArtifact.fuchsia,
|
||||
DevelopmentArtifact.flutterRunner,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(
|
||||
isWebEnabled: true,
|
||||
isLinuxEnabled: true,
|
||||
isMacOSEnabled: true,
|
||||
isWindowsEnabled: true,
|
||||
),
|
||||
FlutterVersion: () => masterFlutterVersion,
|
||||
});
|
||||
|
||||
testUsingContext('precache expands android artifacts when the android flag is used', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>[
|
||||
@ -245,12 +289,16 @@ void main() {
|
||||
DevelopmentArtifact.androidMaven,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
});
|
||||
|
||||
testUsingContext('precache adds artifact flags to requested android artifacts', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>[
|
||||
@ -267,12 +315,16 @@ void main() {
|
||||
DevelopmentArtifact.androidMaven,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
});
|
||||
|
||||
testUsingContext('precache adds artifact flags to requested artifacts on stable', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>[
|
||||
@ -296,14 +348,16 @@ void main() {
|
||||
DevelopmentArtifact.androidMaven,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FlutterVersion: () => flutterVersion,
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: false),
|
||||
});
|
||||
|
||||
testUsingContext('precache downloads iOS and Android artifacts by default', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
|
||||
await createTestCommandRunner(command).run(
|
||||
@ -319,12 +373,21 @@ void main() {
|
||||
DevelopmentArtifact.androidMaven,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
});
|
||||
|
||||
testUsingContext('precache --all-platforms gets all artifacts', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: masterFlutterVersion,
|
||||
featureFlags: TestFeatureFlags(
|
||||
isWebEnabled: true,
|
||||
isLinuxEnabled: true,
|
||||
isMacOSEnabled: true,
|
||||
isWindowsEnabled: true,
|
||||
),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
|
||||
await createTestCommandRunner(command).run(
|
||||
@ -347,19 +410,16 @@ void main() {
|
||||
DevelopmentArtifact.fuchsia,
|
||||
DevelopmentArtifact.flutterRunner,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FeatureFlags: () => TestFeatureFlags(
|
||||
isWebEnabled: true,
|
||||
isLinuxEnabled: true,
|
||||
isMacOSEnabled: true,
|
||||
isWindowsEnabled: true,
|
||||
),
|
||||
FlutterVersion: () => masterFlutterVersion,
|
||||
});
|
||||
|
||||
testUsingContext('precache with default artifacts does not override platform filtering', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: masterFlutterVersion,
|
||||
featureFlags: TestFeatureFlags(),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
|
||||
await createTestCommandRunner(command).run(
|
||||
@ -369,13 +429,24 @@ void main() {
|
||||
);
|
||||
|
||||
verify(cache.platformOverrideArtifacts = <String>{});
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FlutterVersion: () => masterFlutterVersion,
|
||||
});
|
||||
|
||||
testUsingContext('precache with explicit artifact options overrides platform filtering', () async {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: masterFlutterVersion,
|
||||
featureFlags: TestFeatureFlags(
|
||||
isMacOSEnabled: true,
|
||||
),
|
||||
platform: FakePlatform(
|
||||
operatingSystem: 'windows',
|
||||
environment: <String, String>{
|
||||
'FLUTTER_ROOT': 'flutter',
|
||||
'FLUTTER_ALREADY_LOCKED': 'true',
|
||||
},
|
||||
),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
|
||||
await createTestCommandRunner(command).run(
|
||||
@ -392,39 +463,23 @@ void main() {
|
||||
DevelopmentArtifact.macOS,
|
||||
}));
|
||||
verify(cache.platformOverrideArtifacts = <String>{'macos'});
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FlutterVersion: () => masterFlutterVersion,
|
||||
FeatureFlags: () => TestFeatureFlags(
|
||||
isMacOSEnabled: true,
|
||||
),
|
||||
Platform: () => FakePlatform(
|
||||
operatingSystem: 'windows',
|
||||
environment: <String, String>{
|
||||
'FLUTTER_ROOT': 'flutter',
|
||||
'FLUTTER_ALREADY_LOCKED': 'true',
|
||||
},
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('precache downloads artifacts when --force is provided', () async {
|
||||
testUsingContext('precache deletes artifact stampfiles when --force is provided', () async {
|
||||
when(cache.isUpToDate()).thenReturn(true);
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
final PrecacheCommand command = PrecacheCommand(
|
||||
cache: cache,
|
||||
logger: BufferLogger.test(),
|
||||
flutterVersion: flutterVersion,
|
||||
featureFlags: TestFeatureFlags(
|
||||
isMacOSEnabled: true,
|
||||
),
|
||||
platform: FakePlatform(environment: <String, String>{}),
|
||||
);
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache', '--force']);
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.iOS,
|
||||
DevelopmentArtifact.androidGenSnapshot,
|
||||
DevelopmentArtifact.androidMaven,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FlutterVersion: () => flutterVersion,
|
||||
FeatureFlags: () => TestFeatureFlags(
|
||||
isMacOSEnabled: true,
|
||||
),
|
||||
|
||||
verify(cache.clearStampFiles()).called(1);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import 'package:flutter_tools/src/android/gradle_utils.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart' show InternetAddress, SocketException;
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/net.dart';
|
||||
import 'package:flutter_tools/src/base/os.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
@ -241,13 +242,13 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('Invalid URI for FLUTTER_STORAGE_BASE_URL throws ToolExit', () async {
|
||||
when(globals.platform.environment).thenReturn(const <String, String>{
|
||||
'FLUTTER_STORAGE_BASE_URL': ' http://foo',
|
||||
});
|
||||
final Cache cache = Cache();
|
||||
|
||||
expect(() => cache.storageBaseUrl, throwsToolExit());
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => MockPlatform(),
|
||||
Platform: () => FakePlatform(environment: <String, String>{
|
||||
'FLUTTER_STORAGE_BASE_URL': ' http://foo',
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
@ -624,6 +625,83 @@ void main() {
|
||||
contains(contains('release')),
|
||||
]));
|
||||
});
|
||||
|
||||
testWithoutContext('Cache can delete stampfiles of artifacts', () {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
final ArtifactSet artifactSet = MockIosUsbArtifacts();
|
||||
final BufferLogger logger = BufferLogger.test();
|
||||
|
||||
when(artifactSet.stampName).thenReturn('STAMP');
|
||||
final Cache cache = Cache(
|
||||
artifacts: <ArtifactSet>[
|
||||
artifactSet,
|
||||
],
|
||||
logger: logger,
|
||||
fileSystem: fileSystem,
|
||||
platform: FakePlatform(),
|
||||
osUtils: MockOperatingSystemUtils(),
|
||||
rootOverride: fileSystem.currentDirectory,
|
||||
);
|
||||
final File toolStampFile = fileSystem.file('bin/cache/flutter_tools.stamp');
|
||||
final File stampFile = cache.getStampFileFor(artifactSet.stampName);
|
||||
stampFile.createSync(recursive: true);
|
||||
toolStampFile.createSync(recursive: true);
|
||||
|
||||
cache.clearStampFiles();
|
||||
|
||||
expect(logger.errorText, isEmpty);
|
||||
expect(stampFile, isNot(exists));
|
||||
expect(toolStampFile, isNot(exists));
|
||||
});
|
||||
|
||||
testWithoutContext('Cache does not attempt to delete already missing stamp files', () {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
final ArtifactSet artifactSet = MockIosUsbArtifacts();
|
||||
final BufferLogger logger = BufferLogger.test();
|
||||
|
||||
when(artifactSet.stampName).thenReturn('STAMP');
|
||||
final Cache cache = Cache(
|
||||
artifacts: <ArtifactSet>[
|
||||
artifactSet,
|
||||
],
|
||||
logger: logger,
|
||||
fileSystem: fileSystem,
|
||||
platform: FakePlatform(),
|
||||
osUtils: MockOperatingSystemUtils(),
|
||||
rootOverride: fileSystem.currentDirectory,
|
||||
);
|
||||
final File toolStampFile = fileSystem.file('bin/cache/flutter_tools.stamp');
|
||||
final File stampFile = cache.getStampFileFor(artifactSet.stampName);
|
||||
toolStampFile.createSync(recursive: true);
|
||||
|
||||
cache.clearStampFiles();
|
||||
|
||||
expect(logger.errorText, isEmpty);
|
||||
expect(stampFile, isNot(exists));
|
||||
expect(toolStampFile, isNot(exists));
|
||||
});
|
||||
|
||||
testWithoutContext('Cache catches file system exception from missing tool stamp file', () {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
final ArtifactSet artifactSet = MockIosUsbArtifacts();
|
||||
final BufferLogger logger = BufferLogger.test();
|
||||
|
||||
when(artifactSet.stampName).thenReturn('STAMP');
|
||||
final Cache cache = Cache(
|
||||
artifacts: <ArtifactSet>[
|
||||
artifactSet,
|
||||
],
|
||||
logger: logger,
|
||||
fileSystem: fileSystem,
|
||||
platform: FakePlatform(),
|
||||
osUtils: MockOperatingSystemUtils(),
|
||||
rootOverride: fileSystem.currentDirectory,
|
||||
);
|
||||
|
||||
cache.clearStampFiles();
|
||||
|
||||
expect(logger.errorText, contains('Failed to delete some stamp files'));
|
||||
});
|
||||
}
|
||||
|
||||
class FakeCachedArtifact extends EngineCachedArtifact {
|
||||
@ -689,7 +767,6 @@ class MockIosUsbArtifacts extends Mock implements IosUsbArtifacts {}
|
||||
class MockInternetAddress extends Mock implements InternetAddress {}
|
||||
class MockCache extends Mock implements Cache {}
|
||||
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
|
||||
class MockPlatform extends Mock implements Platform {}
|
||||
class MockVersionedPackageResolver extends Mock implements VersionedPackageResolver {}
|
||||
|
||||
class MockHttpClientRequest extends Mock implements HttpClientRequest {}
|
||||
|
@ -934,4 +934,7 @@ class FakeCache implements Cache {
|
||||
Future<bool> doesRemoteExist(String message, Uri url) async {
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
void clearStampFiles() {}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user