mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
[flutter_tools] remove all globals from cache and cache_test (#69505)
This commit is contained in:
parent
9b201dd074
commit
2fb53d83f2
@ -103,44 +103,37 @@ class Cache {
|
|||||||
Cache({
|
Cache({
|
||||||
@protected Directory rootOverride,
|
@protected Directory rootOverride,
|
||||||
@protected List<ArtifactSet> artifacts,
|
@protected List<ArtifactSet> artifacts,
|
||||||
// TODO(jonahwilliams): make required once migrated to context-free.
|
@required Logger logger,
|
||||||
Logger logger,
|
@required FileSystem fileSystem,
|
||||||
FileSystem fileSystem,
|
@required Platform platform,
|
||||||
Platform platform,
|
@required OperatingSystemUtils osUtils,
|
||||||
OperatingSystemUtils osUtils,
|
|
||||||
}) : _rootOverride = rootOverride,
|
}) : _rootOverride = rootOverride,
|
||||||
_logger = logger ?? globals.logger,
|
_logger = logger,
|
||||||
_fileSystem = fileSystem ?? globals.fs,
|
_fileSystem = fileSystem,
|
||||||
_platform = platform ?? globals.platform,
|
_platform = platform,
|
||||||
_osUtils = osUtils ?? globals.os {
|
_osUtils = osUtils,
|
||||||
// TODO(zra): Move to initializer list once logger and platform parameters
|
_net = Net(logger: logger, platform: platform),
|
||||||
// are required.
|
_fsUtils = FileSystemUtils(fileSystem: fileSystem, platform: platform) {
|
||||||
_net = Net(logger: _logger, platform: _platform);
|
|
||||||
_fsUtils = FileSystemUtils(fileSystem: _fileSystem, platform: _platform);
|
|
||||||
if (artifacts == null) {
|
if (artifacts == null) {
|
||||||
_artifacts.add(MaterialFonts(this));
|
_artifacts.add(MaterialFonts(this));
|
||||||
|
|
||||||
_artifacts.add(GradleWrapper(this));
|
_artifacts.add(GradleWrapper(this));
|
||||||
_artifacts.add(AndroidMavenArtifacts(this));
|
_artifacts.add(AndroidGenSnapshotArtifacts(this, platform: _platform));
|
||||||
_artifacts.add(AndroidGenSnapshotArtifacts(this));
|
|
||||||
_artifacts.add(AndroidInternalBuildArtifacts(this));
|
_artifacts.add(AndroidInternalBuildArtifacts(this));
|
||||||
|
_artifacts.add(IOSEngineArtifacts(this, platform: _platform));
|
||||||
_artifacts.add(IOSEngineArtifacts(this));
|
|
||||||
_artifacts.add(FlutterWebSdk(this, platform: _platform));
|
_artifacts.add(FlutterWebSdk(this, platform: _platform));
|
||||||
_artifacts.add(FlutterSdk(this));
|
_artifacts.add(FlutterSdk(this, platform: _platform));
|
||||||
_artifacts.add(WindowsEngineArtifacts(this, platform: _platform));
|
_artifacts.add(WindowsEngineArtifacts(this, platform: _platform));
|
||||||
_artifacts.add(MacOSEngineArtifacts(this));
|
_artifacts.add(MacOSEngineArtifacts(this, platform: _platform));
|
||||||
_artifacts.add(LinuxEngineArtifacts(this, platform: _platform));
|
_artifacts.add(LinuxEngineArtifacts(this, platform: _platform));
|
||||||
_artifacts.add(LinuxFuchsiaSDKArtifacts(this));
|
_artifacts.add(LinuxFuchsiaSDKArtifacts(this, platform: _platform));
|
||||||
_artifacts.add(MacOSFuchsiaSDKArtifacts(this));
|
_artifacts.add(MacOSFuchsiaSDKArtifacts(this, platform: _platform));
|
||||||
_artifacts.add(FlutterRunnerSDKArtifacts(this));
|
_artifacts.add(FlutterRunnerSDKArtifacts(this, platform: _platform));
|
||||||
_artifacts.add(FlutterRunnerDebugSymbols(this, platform: _platform));
|
_artifacts.add(FlutterRunnerDebugSymbols(this, platform: _platform));
|
||||||
for (final String artifactName in IosUsbArtifacts.artifactNames) {
|
for (final String artifactName in IosUsbArtifacts.artifactNames) {
|
||||||
_artifacts.add(IosUsbArtifacts(artifactName, this));
|
_artifacts.add(IosUsbArtifacts(artifactName, this, platform: _platform));
|
||||||
}
|
}
|
||||||
_artifacts.add(FontSubsetArtifacts(this));
|
_artifacts.add(FontSubsetArtifacts(this, platform: _platform));
|
||||||
_artifacts.add(PubDependencies(
|
_artifacts.add(PubDependencies(
|
||||||
fileSystem: _fileSystem,
|
|
||||||
logger: _logger,
|
logger: _logger,
|
||||||
// flutter root and pub must be lazily initialized to avoid accessing
|
// flutter root and pub must be lazily initialized to avoid accessing
|
||||||
// before the version is determined.
|
// before the version is determined.
|
||||||
@ -324,19 +317,18 @@ class Cache {
|
|||||||
/// (see [FlutterCommandRunner.runCommand]).
|
/// (see [FlutterCommandRunner.runCommand]).
|
||||||
///
|
///
|
||||||
/// This uses normal POSIX flock semantics.
|
/// This uses normal POSIX flock semantics.
|
||||||
static Future<void> lock() async {
|
Future<void> lock() async {
|
||||||
if (!_lockEnabled) {
|
if (!_lockEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assert(_lock == null);
|
assert(_lock == null);
|
||||||
final File lockFile =
|
final File lockFile =
|
||||||
globals.fs.file(globals.fs.path.join(flutterRoot, 'bin', 'cache', 'lockfile'));
|
_fileSystem.file(_fileSystem.path.join(flutterRoot, 'bin', 'cache', 'lockfile'));
|
||||||
try {
|
try {
|
||||||
_lock = lockFile.openSync(mode: FileMode.write);
|
_lock = lockFile.openSync(mode: FileMode.write);
|
||||||
} on FileSystemException catch (e) {
|
} on FileSystemException catch (e) {
|
||||||
globals.printError('Failed to open or create the artifact cache lockfile: "$e"');
|
_logger.printError('Failed to open or create the artifact cache lockfile: "$e"');
|
||||||
globals.printError('Please ensure you have permissions to create or open '
|
_logger.printError('Please ensure you have permissions to create or open ${lockFile.path}');
|
||||||
'${lockFile.path}');
|
|
||||||
throwToolExit('Failed to open or create the lockfile');
|
throwToolExit('Failed to open or create the lockfile');
|
||||||
}
|
}
|
||||||
bool locked = false;
|
bool locked = false;
|
||||||
@ -347,8 +339,8 @@ class Cache {
|
|||||||
locked = true;
|
locked = true;
|
||||||
} on FileSystemException {
|
} on FileSystemException {
|
||||||
if (!printed) {
|
if (!printed) {
|
||||||
globals.printTrace('Waiting to be able to obtain lock of Flutter binary artifacts directory: ${_lock.path}');
|
_logger.printTrace('Waiting to be able to obtain lock of Flutter binary artifacts directory: ${_lock.path}');
|
||||||
globals.printStatus('Waiting for another flutter command to release the startup lock...');
|
_logger.printStatus('Waiting for another flutter command to release the startup lock...');
|
||||||
printed = true;
|
printed = true;
|
||||||
}
|
}
|
||||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||||
@ -360,7 +352,7 @@ class Cache {
|
|||||||
///
|
///
|
||||||
/// This happens automatically on startup (see [FlutterCommand.verifyThenRunCommand])
|
/// This happens automatically on startup (see [FlutterCommand.verifyThenRunCommand])
|
||||||
/// after the command's required artifacts are updated.
|
/// after the command's required artifacts are updated.
|
||||||
static void releaseLock() {
|
void releaseLock() {
|
||||||
if (!_lockEnabled || _lock == null) {
|
if (!_lockEnabled || _lock == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -370,16 +362,15 @@ class Cache {
|
|||||||
|
|
||||||
/// Checks if the current process owns the lock for the cache directory at
|
/// Checks if the current process owns the lock for the cache directory at
|
||||||
/// this very moment; throws a [StateError] if it doesn't.
|
/// this very moment; throws a [StateError] if it doesn't.
|
||||||
static void checkLockAcquired([Platform platform]) {
|
void checkLockAcquired() {
|
||||||
if (_lockEnabled && _lock == null && (platform ?? globals.platform).environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
if (_lockEnabled && _lock == null && _platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
||||||
throw StateError(
|
throw StateError(
|
||||||
'The current process does not own the lock for the cache directory. This is a bug in Flutter CLI tools.',
|
'The current process does not own the lock for the cache directory. This is a bug in Flutter CLI tools.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _dartSdkVersion;
|
/// The current version of Dart used to build Flutter and run the tool.
|
||||||
|
|
||||||
String get dartSdkVersion {
|
String get dartSdkVersion {
|
||||||
if (_dartSdkVersion == null) {
|
if (_dartSdkVersion == null) {
|
||||||
// Make the version string more customer-friendly.
|
// Make the version string more customer-friendly.
|
||||||
@ -392,6 +383,7 @@ class Cache {
|
|||||||
}
|
}
|
||||||
return _dartSdkVersion;
|
return _dartSdkVersion;
|
||||||
}
|
}
|
||||||
|
String _dartSdkVersion;
|
||||||
|
|
||||||
/// The current version of the Flutter engine the flutter tool will download.
|
/// The current version of the Flutter engine the flutter tool will download.
|
||||||
String get engineRevision {
|
String get engineRevision {
|
||||||
@ -547,7 +539,7 @@ class Cache {
|
|||||||
|
|
||||||
Future<bool> isUpToDate() async {
|
Future<bool> isUpToDate() async {
|
||||||
for (final ArtifactSet artifact in _artifacts) {
|
for (final ArtifactSet artifact in _artifacts) {
|
||||||
if (!await artifact.isUpToDate()) {
|
if (!await artifact.isUpToDate(_fileSystem)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -564,11 +556,11 @@ class Cache {
|
|||||||
_logger.printTrace('Artifact $artifact is not required, skipping update.');
|
_logger.printTrace('Artifact $artifact is not required, skipping update.');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (await artifact.isUpToDate()) {
|
if (await artifact.isUpToDate(_fileSystem)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await artifact.update(_artifactUpdater);
|
await artifact.update(_artifactUpdater, _logger, _fileSystem, _osUtils);
|
||||||
} on SocketException catch (e) {
|
} on SocketException catch (e) {
|
||||||
if (_hostsBlockedInChina.contains(e.address?.host)) {
|
if (_hostsBlockedInChina.contains(e.address?.host)) {
|
||||||
_logger.printError(
|
_logger.printError(
|
||||||
@ -588,15 +580,15 @@ class Cache {
|
|||||||
bool includeAllPlatforms = true,
|
bool includeAllPlatforms = true,
|
||||||
}) async {
|
}) async {
|
||||||
final bool includeAllPlatformsState = this.includeAllPlatforms;
|
final bool includeAllPlatformsState = this.includeAllPlatforms;
|
||||||
bool allAvailible = true;
|
bool allAvailable = true;
|
||||||
this.includeAllPlatforms = includeAllPlatforms;
|
this.includeAllPlatforms = includeAllPlatforms;
|
||||||
for (final ArtifactSet cachedArtifact in _artifacts) {
|
for (final ArtifactSet cachedArtifact in _artifacts) {
|
||||||
if (cachedArtifact is EngineCachedArtifact) {
|
if (cachedArtifact is EngineCachedArtifact) {
|
||||||
allAvailible &= await cachedArtifact.checkForArtifacts(engineVersion);
|
allAvailable &= await cachedArtifact.checkForArtifacts(engineVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.includeAllPlatforms = includeAllPlatformsState;
|
this.includeAllPlatforms = includeAllPlatformsState;
|
||||||
return allAvailible;
|
return allAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> doesRemoteExist(String message, Uri url) async {
|
Future<bool> doesRemoteExist(String message, Uri url) async {
|
||||||
@ -621,7 +613,7 @@ abstract class ArtifactSet {
|
|||||||
final DevelopmentArtifact developmentArtifact;
|
final DevelopmentArtifact developmentArtifact;
|
||||||
|
|
||||||
/// [true] if the artifact is up to date.
|
/// [true] if the artifact is up to date.
|
||||||
Future<bool> isUpToDate();
|
Future<bool> isUpToDate(FileSystem fileSystem);
|
||||||
|
|
||||||
/// The environment variables (if any) required to consume the artifacts.
|
/// The environment variables (if any) required to consume the artifacts.
|
||||||
Map<String, String> get environment {
|
Map<String, String> get environment {
|
||||||
@ -629,7 +621,12 @@ abstract class ArtifactSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the artifact.
|
/// Updates the artifact.
|
||||||
Future<void> update(ArtifactUpdater artifactUpdater);
|
Future<void> update(
|
||||||
|
ArtifactUpdater artifactUpdater,
|
||||||
|
Logger logger,
|
||||||
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
);
|
||||||
|
|
||||||
/// The canonical name of the artifact.
|
/// The canonical name of the artifact.
|
||||||
String get name;
|
String get name;
|
||||||
@ -665,34 +662,39 @@ abstract class CachedArtifact extends ArtifactSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> isUpToDate() async {
|
Future<bool> isUpToDate(FileSystem fileSystem) async {
|
||||||
if (!location.existsSync()) {
|
if (!location.existsSync()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (version != cache.getStampFor(stampName)) {
|
if (version != cache.getStampFor(stampName)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isUpToDateInner();
|
return isUpToDateInner(fileSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> update(ArtifactUpdater artifactUpdater) async {
|
Future<void> update(
|
||||||
|
ArtifactUpdater artifactUpdater,
|
||||||
|
Logger logger,
|
||||||
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
if (!location.existsSync()) {
|
if (!location.existsSync()) {
|
||||||
try {
|
try {
|
||||||
location.createSync(recursive: true);
|
location.createSync(recursive: true);
|
||||||
} on FileSystemException catch (err) {
|
} on FileSystemException catch (err) {
|
||||||
globals.printError(err.toString());
|
logger.printError(err.toString());
|
||||||
throwToolExit(
|
throwToolExit(
|
||||||
'Failed to create directory for flutter cache at ${location.path}. '
|
'Failed to create directory for flutter cache at ${location.path}. '
|
||||||
'Flutter may be missing permissions in its cache directory.'
|
'Flutter may be missing permissions in its cache directory.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await updateInner(artifactUpdater);
|
await updateInner(artifactUpdater, fileSystem, operatingSystemUtils);
|
||||||
try {
|
try {
|
||||||
cache.setStampFor(stampName, version);
|
cache.setStampFor(stampName, version);
|
||||||
} on FileSystemException catch (err) {
|
} on FileSystemException catch (err) {
|
||||||
globals.printError(
|
logger.printError(
|
||||||
'The new artifact "$name" was downloaded, but Flutter failed to update '
|
'The new artifact "$name" was downloaded, but Flutter failed to update '
|
||||||
'its stamp file, receiving the error "$err". '
|
'its stamp file, receiving the error "$err". '
|
||||||
'Flutter can continue, but the artifact may be re-downloaded on '
|
'Flutter can continue, but the artifact may be re-downloaded on '
|
||||||
@ -703,10 +705,13 @@ abstract class CachedArtifact extends ArtifactSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Hook method for extra checks for being up-to-date.
|
/// Hook method for extra checks for being up-to-date.
|
||||||
bool isUpToDateInner() => true;
|
bool isUpToDateInner(FileSystem fileSystem) => true;
|
||||||
|
|
||||||
/// Template method to perform artifact update.
|
Future<void> updateInner(
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater);
|
ArtifactUpdater artifactUpdater,
|
||||||
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
);
|
||||||
|
|
||||||
Uri _toStorageUri(String path) => Uri.parse('${cache.storageBaseUrl}/$path');
|
Uri _toStorageUri(String path) => Uri.parse('${cache.storageBaseUrl}/$path');
|
||||||
}
|
}
|
||||||
@ -720,24 +725,23 @@ class PubDependencies extends ArtifactSet {
|
|||||||
PubDependencies({
|
PubDependencies({
|
||||||
// Needs to be lazy to avoid reading from the cache before the root is initialized.
|
// Needs to be lazy to avoid reading from the cache before the root is initialized.
|
||||||
@required String Function() flutterRoot,
|
@required String Function() flutterRoot,
|
||||||
@required FileSystem fileSystem,
|
|
||||||
@required Logger logger,
|
@required Logger logger,
|
||||||
@required Pub Function() pub,
|
@required Pub Function() pub,
|
||||||
}) : _logger = logger,
|
}) : _logger = logger,
|
||||||
_fileSystem = fileSystem,
|
|
||||||
_flutterRoot = flutterRoot,
|
_flutterRoot = flutterRoot,
|
||||||
_pub = pub,
|
_pub = pub,
|
||||||
super(DevelopmentArtifact.universal);
|
super(DevelopmentArtifact.universal);
|
||||||
|
|
||||||
final String Function() _flutterRoot;
|
final String Function() _flutterRoot;
|
||||||
final FileSystem _fileSystem;
|
|
||||||
final Logger _logger;
|
final Logger _logger;
|
||||||
final Pub Function() _pub;
|
final Pub Function() _pub;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> isUpToDate() async {
|
Future<bool> isUpToDate(
|
||||||
final File toolPackageConfig = _fileSystem.file(
|
FileSystem fileSystem,
|
||||||
_fileSystem.path.join(_flutterRoot(), 'packages', 'flutter_tools', kPackagesFileName),
|
) async {
|
||||||
|
final File toolPackageConfig = fileSystem.file(
|
||||||
|
fileSystem.path.join(_flutterRoot(), 'packages', 'flutter_tools', kPackagesFileName),
|
||||||
);
|
);
|
||||||
if (!toolPackageConfig.existsSync()) {
|
if (!toolPackageConfig.existsSync()) {
|
||||||
return false;
|
return false;
|
||||||
@ -751,7 +755,7 @@ class PubDependencies extends ArtifactSet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (final Package package in packageConfig.packages) {
|
for (final Package package in packageConfig.packages) {
|
||||||
if (!_fileSystem.directory(package.packageUriRoot).existsSync()) {
|
if (!fileSystem.directory(package.packageUriRoot).existsSync()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -762,10 +766,15 @@ class PubDependencies extends ArtifactSet {
|
|||||||
String get name => 'pub_dependencies';
|
String get name => 'pub_dependencies';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> update(ArtifactUpdater artifactUpdater) async {
|
Future<void> update(
|
||||||
|
ArtifactUpdater artifactUpdater,
|
||||||
|
Logger logger,
|
||||||
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
await _pub().get(
|
await _pub().get(
|
||||||
context: PubContext.pubGet,
|
context: PubContext.pubGet,
|
||||||
directory: _fileSystem.path.join(_flutterRoot(), 'packages', 'flutter_tools'),
|
directory: fileSystem.path.join(_flutterRoot(), 'packages', 'flutter_tools'),
|
||||||
generateSyntheticPackage: false,
|
generateSyntheticPackage: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -780,7 +789,11 @@ class MaterialFonts extends CachedArtifact {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) {
|
Future<void> updateInner(
|
||||||
|
ArtifactUpdater artifactUpdater,
|
||||||
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) {
|
||||||
final Uri archiveUri = _toStorageUri(version);
|
final Uri archiveUri = _toStorageUri(version);
|
||||||
return artifactUpdater.downloadZipArchive('Downloading Material fonts...', archiveUri, location);
|
return artifactUpdater.downloadZipArchive('Downloading Material fonts...', archiveUri, location);
|
||||||
}
|
}
|
||||||
@ -791,8 +804,8 @@ class MaterialFonts extends CachedArtifact {
|
|||||||
///
|
///
|
||||||
/// This SDK references code within the regular Dart sdk to reduce download size.
|
/// This SDK references code within the regular Dart sdk to reduce download size.
|
||||||
class FlutterWebSdk extends CachedArtifact {
|
class FlutterWebSdk extends CachedArtifact {
|
||||||
FlutterWebSdk(Cache cache, {Platform platform})
|
FlutterWebSdk(Cache cache, {@required Platform platform})
|
||||||
: _platform = platform ?? globals.platform,
|
: _platform = platform,
|
||||||
super(
|
super(
|
||||||
'flutter_web_sdk',
|
'flutter_web_sdk',
|
||||||
cache,
|
cache,
|
||||||
@ -808,7 +821,11 @@ class FlutterWebSdk extends CachedArtifact {
|
|||||||
String get version => cache.getVersionFor('engine');
|
String get version => cache.getVersionFor('engine');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) async {
|
Future<void> updateInner(
|
||||||
|
ArtifactUpdater artifactUpdater,
|
||||||
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
String platformName = 'flutter-web-sdk-';
|
String platformName = 'flutter-web-sdk-';
|
||||||
if (_platform.isMacOS) {
|
if (_platform.isMacOS) {
|
||||||
platformName += 'darwin-x64';
|
platformName += 'darwin-x64';
|
||||||
@ -859,24 +876,24 @@ abstract class EngineCachedArtifact extends CachedArtifact {
|
|||||||
List<String> getPackageDirs();
|
List<String> getPackageDirs();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isUpToDateInner() {
|
bool isUpToDateInner(FileSystem fileSystem) {
|
||||||
final Directory pkgDir = cache.getCacheDir('pkg');
|
final Directory pkgDir = cache.getCacheDir('pkg');
|
||||||
for (final String pkgName in getPackageDirs()) {
|
for (final String pkgName in getPackageDirs()) {
|
||||||
final String pkgPath = globals.fs.path.join(pkgDir.path, pkgName);
|
final String pkgPath = fileSystem.path.join(pkgDir.path, pkgName);
|
||||||
if (!globals.fs.directory(pkgPath).existsSync()) {
|
if (!fileSystem.directory(pkgPath).existsSync()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final List<String> toolsDir in getBinaryDirs()) {
|
for (final List<String> toolsDir in getBinaryDirs()) {
|
||||||
final Directory dir = globals.fs.directory(globals.fs.path.join(location.path, toolsDir[0]));
|
final Directory dir = fileSystem.directory(fileSystem.path.join(location.path, toolsDir[0]));
|
||||||
if (!dir.existsSync()) {
|
if (!dir.existsSync()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final String licenseDir in getLicenseDirs()) {
|
for (final String licenseDir in getLicenseDirs()) {
|
||||||
final File file = globals.fs.file(globals.fs.path.join(location.path, licenseDir, 'LICENSE'));
|
final File file = fileSystem.file(fileSystem.path.join(location.path, licenseDir, 'LICENSE'));
|
||||||
if (!file.existsSync()) {
|
if (!file.existsSync()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -885,7 +902,11 @@ abstract class EngineCachedArtifact extends CachedArtifact {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) async {
|
Future<void> updateInner(
|
||||||
|
ArtifactUpdater artifactUpdater,
|
||||||
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
final String url = '${cache.storageBaseUrl}/flutter_infra/flutter/$version/';
|
final String url = '${cache.storageBaseUrl}/flutter_infra/flutter/$version/';
|
||||||
|
|
||||||
final Directory pkgDir = cache.getCacheDir('pkg');
|
final Directory pkgDir = cache.getCacheDir('pkg');
|
||||||
@ -896,28 +917,28 @@ abstract class EngineCachedArtifact extends CachedArtifact {
|
|||||||
for (final List<String> toolsDir in getBinaryDirs()) {
|
for (final List<String> toolsDir in getBinaryDirs()) {
|
||||||
final String cacheDir = toolsDir[0];
|
final String cacheDir = toolsDir[0];
|
||||||
final String urlPath = toolsDir[1];
|
final String urlPath = toolsDir[1];
|
||||||
final Directory dir = globals.fs.directory(globals.fs.path.join(location.path, cacheDir));
|
final Directory dir = fileSystem.directory(fileSystem.path.join(location.path, cacheDir));
|
||||||
|
|
||||||
// Avoid printing things like 'Downloading linux-x64 tools...' multiple times.
|
// Avoid printing things like 'Downloading linux-x64 tools...' multiple times.
|
||||||
final String friendlyName = urlPath.replaceAll('/artifacts.zip', '').replaceAll('.zip', '');
|
final String friendlyName = urlPath.replaceAll('/artifacts.zip', '').replaceAll('.zip', '');
|
||||||
await artifactUpdater.downloadZipArchive('Downloading $friendlyName tools...', Uri.parse(url + urlPath), dir);
|
await artifactUpdater.downloadZipArchive('Downloading $friendlyName tools...', Uri.parse(url + urlPath), dir);
|
||||||
|
|
||||||
_makeFilesExecutable(dir);
|
_makeFilesExecutable(dir, operatingSystemUtils);
|
||||||
|
|
||||||
const List<String> frameworkNames = <String>['Flutter', 'FlutterMacOS'];
|
const List<String> frameworkNames = <String>['Flutter', 'FlutterMacOS'];
|
||||||
for (final String frameworkName in frameworkNames) {
|
for (final String frameworkName in frameworkNames) {
|
||||||
final File frameworkZip = globals.fs.file(globals.fs.path.join(dir.path, '$frameworkName.framework.zip'));
|
final File frameworkZip = fileSystem.file(fileSystem.path.join(dir.path, '$frameworkName.framework.zip'));
|
||||||
if (frameworkZip.existsSync()) {
|
if (frameworkZip.existsSync()) {
|
||||||
final Directory framework = globals.fs.directory(globals.fs.path.join(dir.path, '$frameworkName.framework'));
|
final Directory framework = fileSystem.directory(fileSystem.path.join(dir.path, '$frameworkName.framework'));
|
||||||
framework.createSync();
|
framework.createSync();
|
||||||
globals.os.unzip(frameworkZip, framework);
|
operatingSystemUtils.unzip(frameworkZip, framework);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final File licenseSource = cache.getLicenseFile();
|
final File licenseSource = cache.getLicenseFile();
|
||||||
for (final String licenseDir in getLicenseDirs()) {
|
for (final String licenseDir in getLicenseDirs()) {
|
||||||
final String licenseDestinationPath = globals.fs.path.join(location.path, licenseDir, 'LICENSE');
|
final String licenseDestinationPath = fileSystem.path.join(location.path, licenseDir, 'LICENSE');
|
||||||
await licenseSource.copy(licenseDestinationPath);
|
await licenseSource.copy(licenseDestinationPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -928,8 +949,7 @@ abstract class EngineCachedArtifact extends CachedArtifact {
|
|||||||
|
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
for (final String pkgName in getPackageDirs()) {
|
for (final String pkgName in getPackageDirs()) {
|
||||||
exists = await cache.doesRemoteExist('Checking package $pkgName is available...',
|
exists = await cache.doesRemoteExist('Checking package $pkgName is available...', Uri.parse(url + pkgName + '.zip'));
|
||||||
Uri.parse(url + pkgName + '.zip'));
|
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -947,16 +967,14 @@ abstract class EngineCachedArtifact extends CachedArtifact {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _makeFilesExecutable(Directory dir) {
|
void _makeFilesExecutable(Directory dir, OperatingSystemUtils operatingSystemUtils) {
|
||||||
globals.os.chmod(dir, 'a+r,a+x');
|
operatingSystemUtils.chmod(dir, 'a+r,a+x');
|
||||||
for (final FileSystemEntity entity in dir.listSync(recursive: true)) {
|
for (final File file in dir.listSync(recursive: true).whereType<File>()) {
|
||||||
if (entity is File) {
|
final FileStat stat = file.statSync();
|
||||||
final FileStat stat = entity.statSync();
|
final bool isUserExecutable = ((stat.mode >> 6) & 0x1) == 1;
|
||||||
final bool isUserExecutable = ((stat.mode >> 6) & 0x1) == 1;
|
if (file.basename == 'flutter_tester' || isUserExecutable) {
|
||||||
if (entity.basename == 'flutter_tester' || isUserExecutable) {
|
// Make the file readable and executable by all users.
|
||||||
// Make the file readable and executable by all users.
|
operatingSystemUtils.chmod(file, 'a+r,a+x');
|
||||||
globals.os.chmod(entity, 'a+r,a+x');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -964,11 +982,16 @@ abstract class EngineCachedArtifact extends CachedArtifact {
|
|||||||
|
|
||||||
/// A cached artifact containing the dart:ui source code.
|
/// A cached artifact containing the dart:ui source code.
|
||||||
class FlutterSdk extends EngineCachedArtifact {
|
class FlutterSdk extends EngineCachedArtifact {
|
||||||
FlutterSdk(Cache cache) : super(
|
FlutterSdk(Cache cache, {
|
||||||
'flutter_sdk',
|
@required Platform platform,
|
||||||
cache,
|
}) : _platform = platform,
|
||||||
DevelopmentArtifact.universal,
|
super(
|
||||||
);
|
'flutter_sdk',
|
||||||
|
cache,
|
||||||
|
DevelopmentArtifact.universal,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Platform _platform;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<String> getPackageDirs() => const <String>['sky_engine'];
|
List<String> getPackageDirs() => const <String>['sky_engine'];
|
||||||
@ -983,11 +1006,11 @@ class FlutterSdk extends EngineCachedArtifact {
|
|||||||
<String>['linux-x64', 'linux-x64/artifacts.zip'],
|
<String>['linux-x64', 'linux-x64/artifacts.zip'],
|
||||||
<String>['darwin-x64', 'darwin-x64/artifacts.zip'],
|
<String>['darwin-x64', 'darwin-x64/artifacts.zip'],
|
||||||
]
|
]
|
||||||
else if (globals.platform.isWindows)
|
else if (_platform.isWindows)
|
||||||
<String>['windows-x64', 'windows-x64/artifacts.zip']
|
<String>['windows-x64', 'windows-x64/artifacts.zip']
|
||||||
else if (globals.platform.isMacOS)
|
else if (_platform.isMacOS)
|
||||||
<String>['darwin-x64', 'darwin-x64/artifacts.zip']
|
<String>['darwin-x64', 'darwin-x64/artifacts.zip']
|
||||||
else if (globals.platform.isLinux)
|
else if (_platform.isLinux)
|
||||||
<String>['linux-x64', 'linux-x64/artifacts.zip'],
|
<String>['linux-x64', 'linux-x64/artifacts.zip'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -997,18 +1020,23 @@ class FlutterSdk extends EngineCachedArtifact {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MacOSEngineArtifacts extends EngineCachedArtifact {
|
class MacOSEngineArtifacts extends EngineCachedArtifact {
|
||||||
MacOSEngineArtifacts(Cache cache) : super(
|
MacOSEngineArtifacts(Cache cache, {
|
||||||
'macos-sdk',
|
@required Platform platform,
|
||||||
cache,
|
}) : _platform = platform,
|
||||||
DevelopmentArtifact.macOS,
|
super(
|
||||||
);
|
'macos-sdk',
|
||||||
|
cache,
|
||||||
|
DevelopmentArtifact.macOS,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Platform _platform;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<String> getPackageDirs() => const <String>[];
|
List<String> getPackageDirs() => const <String>[];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<List<String>> getBinaryDirs() {
|
List<List<String>> getBinaryDirs() {
|
||||||
if (globals.platform.isMacOS || ignorePlatformFiltering) {
|
if (_platform.isMacOS || ignorePlatformFiltering) {
|
||||||
return _macOSDesktopBinaryDirs;
|
return _macOSDesktopBinaryDirs;
|
||||||
}
|
}
|
||||||
return const <List<String>>[];
|
return const <List<String>>[];
|
||||||
@ -1076,11 +1104,16 @@ class LinuxEngineArtifacts extends EngineCachedArtifact {
|
|||||||
|
|
||||||
/// The artifact used to generate snapshots for Android builds.
|
/// The artifact used to generate snapshots for Android builds.
|
||||||
class AndroidGenSnapshotArtifacts extends EngineCachedArtifact {
|
class AndroidGenSnapshotArtifacts extends EngineCachedArtifact {
|
||||||
AndroidGenSnapshotArtifacts(Cache cache) : super(
|
AndroidGenSnapshotArtifacts(Cache cache, {
|
||||||
'android-sdk',
|
@required Platform platform,
|
||||||
cache,
|
}) : _platform = platform,
|
||||||
DevelopmentArtifact.androidGenSnapshot,
|
super(
|
||||||
);
|
'android-sdk',
|
||||||
|
cache,
|
||||||
|
DevelopmentArtifact.androidGenSnapshot,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Platform _platform;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<String> getPackageDirs() => const <String>[];
|
List<String> getPackageDirs() => const <String>[];
|
||||||
@ -1093,11 +1126,11 @@ class AndroidGenSnapshotArtifacts extends EngineCachedArtifact {
|
|||||||
..._linuxBinaryDirs,
|
..._linuxBinaryDirs,
|
||||||
..._windowsBinaryDirs,
|
..._windowsBinaryDirs,
|
||||||
..._dartSdks,
|
..._dartSdks,
|
||||||
] else if (globals.platform.isWindows)
|
] else if (_platform.isWindows)
|
||||||
..._windowsBinaryDirs
|
..._windowsBinaryDirs
|
||||||
else if (globals.platform.isMacOS)
|
else if (_platform.isMacOS)
|
||||||
..._osxBinaryDirs
|
..._osxBinaryDirs
|
||||||
else if (globals.platform.isLinux)
|
else if (_platform.isLinux)
|
||||||
..._linuxBinaryDirs,
|
..._linuxBinaryDirs,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -1106,6 +1139,64 @@ class AndroidGenSnapshotArtifacts extends EngineCachedArtifact {
|
|||||||
List<String> getLicenseDirs() { return <String>[]; }
|
List<String> getLicenseDirs() { return <String>[]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A cached artifact containing the Maven dependencies used to build Android projects.
|
||||||
|
class AndroidMavenArtifacts extends ArtifactSet {
|
||||||
|
AndroidMavenArtifacts(this.cache, {
|
||||||
|
@required Platform platform,
|
||||||
|
}) : _platform = platform,
|
||||||
|
super(DevelopmentArtifact.androidMaven);
|
||||||
|
|
||||||
|
final Platform _platform;
|
||||||
|
final Cache cache;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> update(
|
||||||
|
ArtifactUpdater artifactUpdater,
|
||||||
|
Logger logger,
|
||||||
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
|
final Directory tempDir = cache.getRoot().createTempSync(
|
||||||
|
'flutter_gradle_wrapper.',
|
||||||
|
);
|
||||||
|
gradleUtils.injectGradleWrapperIfNeeded(tempDir);
|
||||||
|
|
||||||
|
final Status status = logger.startProgress('Downloading Android Maven dependencies...');
|
||||||
|
final File gradle = tempDir.childFile(
|
||||||
|
_platform.isWindows ? 'gradlew.bat' : 'gradlew',
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
final String gradleExecutable = gradle.absolute.path;
|
||||||
|
final String flutterSdk = globals.fsUtils.escapePath(Cache.flutterRoot);
|
||||||
|
final RunResult processResult = await globals.processUtils.run(
|
||||||
|
<String>[
|
||||||
|
gradleExecutable,
|
||||||
|
'-b', globals.fs.path.join(flutterSdk, 'packages', 'flutter_tools', 'gradle', 'resolve_dependencies.gradle'),
|
||||||
|
'--project-cache-dir', tempDir.path,
|
||||||
|
'resolveDependencies',
|
||||||
|
],
|
||||||
|
environment: gradleEnvironment);
|
||||||
|
if (processResult.exitCode != 0) {
|
||||||
|
logger.printError('Failed to download the Android dependencies');
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
status.stop();
|
||||||
|
tempDir.deleteSync(recursive: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> isUpToDate(FileSystem fileSystem) async {
|
||||||
|
// The dependencies are downloaded and cached by Gradle.
|
||||||
|
// The tool doesn't know if the dependencies are already cached at this point.
|
||||||
|
// Therefore, call Gradle to figure this out.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get name => 'android-maven-artifacts';
|
||||||
|
}
|
||||||
|
|
||||||
/// Artifacts used for internal builds. The flutter tool builds Android projects
|
/// Artifacts used for internal builds. The flutter tool builds Android projects
|
||||||
/// using the artifacts cached by [AndroidMavenArtifacts].
|
/// using the artifacts cached by [AndroidMavenArtifacts].
|
||||||
class AndroidInternalBuildArtifacts extends EngineCachedArtifact {
|
class AndroidInternalBuildArtifacts extends EngineCachedArtifact {
|
||||||
@ -1127,73 +1218,29 @@ class AndroidInternalBuildArtifacts extends EngineCachedArtifact {
|
|||||||
List<String> getLicenseDirs() { return <String>[]; }
|
List<String> getLicenseDirs() { return <String>[]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A cached artifact containing the Maven dependencies used to build Android projects.
|
|
||||||
class AndroidMavenArtifacts extends ArtifactSet {
|
|
||||||
AndroidMavenArtifacts(this.cache) : super(DevelopmentArtifact.androidMaven);
|
|
||||||
|
|
||||||
final Cache cache;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> update(ArtifactUpdater artifactUpdater) async {
|
|
||||||
final Directory tempDir = cache.getRoot().createTempSync(
|
|
||||||
'flutter_gradle_wrapper.',
|
|
||||||
);
|
|
||||||
gradleUtils.injectGradleWrapperIfNeeded(tempDir);
|
|
||||||
|
|
||||||
final Status status = globals.logger.startProgress('Downloading Android Maven dependencies...');
|
|
||||||
final File gradle = tempDir.childFile(
|
|
||||||
globals.platform.isWindows ? 'gradlew.bat' : 'gradlew',
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
final String gradleExecutable = gradle.absolute.path;
|
|
||||||
final String flutterSdk = globals.fsUtils.escapePath(Cache.flutterRoot);
|
|
||||||
final RunResult processResult = await globals.processUtils.run(
|
|
||||||
<String>[
|
|
||||||
gradleExecutable,
|
|
||||||
'-b', globals.fs.path.join(flutterSdk, 'packages', 'flutter_tools', 'gradle', 'resolve_dependencies.gradle'),
|
|
||||||
'--project-cache-dir', tempDir.path,
|
|
||||||
'resolveDependencies',
|
|
||||||
],
|
|
||||||
environment: gradleEnvironment);
|
|
||||||
if (processResult.exitCode != 0) {
|
|
||||||
globals.printError('Failed to download the Android dependencies');
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
status.stop();
|
|
||||||
tempDir.deleteSync(recursive: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> isUpToDate() async {
|
|
||||||
// The dependencies are downloaded and cached by Gradle.
|
|
||||||
// The tool doesn't know if the dependencies are already cached at this point.
|
|
||||||
// Therefore, call Gradle to figure this out.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get name => 'android-maven-artifacts';
|
|
||||||
}
|
|
||||||
|
|
||||||
class IOSEngineArtifacts extends EngineCachedArtifact {
|
class IOSEngineArtifacts extends EngineCachedArtifact {
|
||||||
IOSEngineArtifacts(Cache cache) : super(
|
IOSEngineArtifacts(Cache cache, {
|
||||||
'ios-sdk',
|
@required Platform platform,
|
||||||
cache,
|
}) : _platform = platform,
|
||||||
DevelopmentArtifact.iOS,
|
super(
|
||||||
);
|
'ios-sdk',
|
||||||
|
cache,
|
||||||
|
DevelopmentArtifact.iOS,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Platform _platform;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<List<String>> getBinaryDirs() {
|
List<List<String>> getBinaryDirs() {
|
||||||
return <List<String>>[
|
return <List<String>>[
|
||||||
if (globals.platform.isMacOS || ignorePlatformFiltering)
|
if (_platform.isMacOS || ignorePlatformFiltering)
|
||||||
..._iosBinaryDirs,
|
..._iosBinaryDirs,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<String> getLicenseDirs() {
|
List<String> getLicenseDirs() {
|
||||||
if (globals.platform.isMacOS || ignorePlatformFiltering) {
|
if (_platform.isMacOS || ignorePlatformFiltering) {
|
||||||
return const <String>['ios', 'ios-profile', 'ios-release'];
|
return const <String>['ios', 'ios-profile', 'ios-release'];
|
||||||
}
|
}
|
||||||
return const <String>[];
|
return const <String>[];
|
||||||
@ -1218,32 +1265,36 @@ class GradleWrapper extends CachedArtifact {
|
|||||||
|
|
||||||
List<String> get _gradleScripts => <String>['gradlew', 'gradlew.bat'];
|
List<String> get _gradleScripts => <String>['gradlew', 'gradlew.bat'];
|
||||||
|
|
||||||
String get _gradleWrapper => globals.fs.path.join('gradle', 'wrapper', 'gradle-wrapper.jar');
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) {
|
Future<void> updateInner(
|
||||||
|
ArtifactUpdater artifactUpdater,
|
||||||
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
final Uri archiveUri = _toStorageUri(version);
|
final Uri archiveUri = _toStorageUri(version);
|
||||||
return artifactUpdater.downloadZippedTarball('Downloading Gradle Wrapper...', archiveUri, location).then<void>((_) {
|
await artifactUpdater.downloadZippedTarball('Downloading Gradle Wrapper...', archiveUri, location);
|
||||||
// Delete property file, allowing templates to provide it.
|
// Delete property file, allowing templates to provide it.
|
||||||
globals.fs.file(globals.fs.path.join(location.path, 'gradle', 'wrapper', 'gradle-wrapper.properties')).deleteSync();
|
fileSystem.file(fileSystem.path.join(location.path, 'gradle', 'wrapper', 'gradle-wrapper.properties')).deleteSync();
|
||||||
// Remove NOTICE file. Should not be part of the template.
|
// Remove NOTICE file. Should not be part of the template.
|
||||||
globals.fs.file(globals.fs.path.join(location.path, 'NOTICE')).deleteSync();
|
fileSystem.file(fileSystem.path.join(location.path, 'NOTICE')).deleteSync();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isUpToDateInner() {
|
bool isUpToDateInner(
|
||||||
final Directory wrapperDir = cache.getCacheDir(globals.fs.path.join('artifacts', 'gradle_wrapper'));
|
FileSystem fileSystem,
|
||||||
if (!globals.fs.directory(wrapperDir).existsSync()) {
|
) {
|
||||||
|
final String gradleWrapper = fileSystem.path.join('gradle', 'wrapper', 'gradle-wrapper.jar');
|
||||||
|
final Directory wrapperDir = cache.getCacheDir(fileSystem.path.join('artifacts', 'gradle_wrapper'));
|
||||||
|
if (!fileSystem.directory(wrapperDir).existsSync()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (final String scriptName in _gradleScripts) {
|
for (final String scriptName in _gradleScripts) {
|
||||||
final File scriptFile = globals.fs.file(globals.fs.path.join(wrapperDir.path, scriptName));
|
final File scriptFile = fileSystem.file(fileSystem.path.join(wrapperDir.path, scriptName));
|
||||||
if (!scriptFile.existsSync()) {
|
if (!scriptFile.existsSync()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final File gradleWrapperJar = globals.fs.file(globals.fs.path.join(wrapperDir.path, _gradleWrapper));
|
final File gradleWrapperJar = fileSystem.file(fileSystem.path.join(wrapperDir.path, gradleWrapper));
|
||||||
if (!gradleWrapperJar.existsSync()) {
|
if (!gradleWrapperJar.existsSync()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1251,8 +1302,7 @@ class GradleWrapper extends CachedArtifact {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const String _cipdBaseUrl =
|
const String _cipdBaseUrl = 'https://chrome-infra-packages.appspot.com/dl';
|
||||||
'https://chrome-infra-packages.appspot.com/dl';
|
|
||||||
|
|
||||||
/// Common functionality for pulling Fuchsia SDKs.
|
/// Common functionality for pulling Fuchsia SDKs.
|
||||||
abstract class _FuchsiaSDKArtifacts extends CachedArtifact {
|
abstract class _FuchsiaSDKArtifacts extends CachedArtifact {
|
||||||
@ -1278,11 +1328,16 @@ abstract class _FuchsiaSDKArtifacts extends CachedArtifact {
|
|||||||
|
|
||||||
/// The pre-built flutter runner for Fuchsia development.
|
/// The pre-built flutter runner for Fuchsia development.
|
||||||
class FlutterRunnerSDKArtifacts extends CachedArtifact {
|
class FlutterRunnerSDKArtifacts extends CachedArtifact {
|
||||||
FlutterRunnerSDKArtifacts(Cache cache) : super(
|
FlutterRunnerSDKArtifacts(Cache cache, {
|
||||||
'flutter_runner',
|
@required Platform platform,
|
||||||
cache,
|
}) : _platform = platform,
|
||||||
DevelopmentArtifact.flutterRunner,
|
super(
|
||||||
);
|
'flutter_runner',
|
||||||
|
cache,
|
||||||
|
DevelopmentArtifact.flutterRunner,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Platform _platform;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Directory get location => cache.getArtifactDirectory('flutter_runner');
|
Directory get location => cache.getArtifactDirectory('flutter_runner');
|
||||||
@ -1291,13 +1346,16 @@ class FlutterRunnerSDKArtifacts extends CachedArtifact {
|
|||||||
String get version => cache.getVersionFor('engine');
|
String get version => cache.getVersionFor('engine');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) async {
|
Future<void> updateInner(
|
||||||
if (!globals.platform.isLinux && !globals.platform.isMacOS) {
|
ArtifactUpdater artifactUpdater,
|
||||||
return Future<void>.value();
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
|
if (!_platform.isLinux && !_platform.isMacOS) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
final String url = '$_cipdBaseUrl/flutter/fuchsia/+/git_revision:$version';
|
final String url = '$_cipdBaseUrl/flutter/fuchsia/+/git_revision:$version';
|
||||||
await artifactUpdater.downloadZipArchive('Downloading package flutter runner...',
|
await artifactUpdater.downloadZipArchive('Downloading package flutter runner...', Uri.parse(url), location);
|
||||||
Uri.parse(url), location);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1349,7 +1407,11 @@ class FlutterRunnerDebugSymbols extends CachedArtifact {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) async {
|
Future<void> updateInner(
|
||||||
|
ArtifactUpdater artifactUpdater,
|
||||||
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
if (!_platform.isLinux && !_platform.isMacOS) {
|
if (!_platform.isLinux && !_platform.isMacOS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1360,12 +1422,21 @@ class FlutterRunnerDebugSymbols extends CachedArtifact {
|
|||||||
|
|
||||||
/// The Fuchsia core SDK for Linux.
|
/// The Fuchsia core SDK for Linux.
|
||||||
class LinuxFuchsiaSDKArtifacts extends _FuchsiaSDKArtifacts {
|
class LinuxFuchsiaSDKArtifacts extends _FuchsiaSDKArtifacts {
|
||||||
LinuxFuchsiaSDKArtifacts(Cache cache) : super(cache, 'linux');
|
LinuxFuchsiaSDKArtifacts(Cache cache, {
|
||||||
|
@required Platform platform,
|
||||||
|
}) : _platform = platform,
|
||||||
|
super(cache, 'linux');
|
||||||
|
|
||||||
|
final Platform _platform;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) {
|
Future<void> updateInner(
|
||||||
if (!globals.platform.isLinux) {
|
ArtifactUpdater artifactUpdater,
|
||||||
return Future<void>.value();
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
|
if (!_platform.isLinux) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return _doUpdate(artifactUpdater);
|
return _doUpdate(artifactUpdater);
|
||||||
}
|
}
|
||||||
@ -1373,12 +1444,21 @@ class LinuxFuchsiaSDKArtifacts extends _FuchsiaSDKArtifacts {
|
|||||||
|
|
||||||
/// The Fuchsia core SDK for MacOS.
|
/// The Fuchsia core SDK for MacOS.
|
||||||
class MacOSFuchsiaSDKArtifacts extends _FuchsiaSDKArtifacts {
|
class MacOSFuchsiaSDKArtifacts extends _FuchsiaSDKArtifacts {
|
||||||
MacOSFuchsiaSDKArtifacts(Cache cache) : super(cache, 'mac');
|
MacOSFuchsiaSDKArtifacts(Cache cache, {
|
||||||
|
@required Platform platform,
|
||||||
|
}) : _platform = platform,
|
||||||
|
super(cache, 'mac');
|
||||||
|
|
||||||
|
final Platform _platform;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) async {
|
Future<void> updateInner(
|
||||||
if (!globals.platform.isMacOS) {
|
ArtifactUpdater artifactUpdater,
|
||||||
return Future<void>.value();
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
|
if (!_platform.isMacOS) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return _doUpdate(artifactUpdater);
|
return _doUpdate(artifactUpdater);
|
||||||
}
|
}
|
||||||
@ -1386,7 +1466,12 @@ class MacOSFuchsiaSDKArtifacts extends _FuchsiaSDKArtifacts {
|
|||||||
|
|
||||||
/// Cached artifacts for font subsetting.
|
/// Cached artifacts for font subsetting.
|
||||||
class FontSubsetArtifacts extends EngineCachedArtifact {
|
class FontSubsetArtifacts extends EngineCachedArtifact {
|
||||||
FontSubsetArtifacts(Cache cache) : super(artifactName, cache, DevelopmentArtifact.universal);
|
FontSubsetArtifacts(Cache cache, {
|
||||||
|
@required Platform platform,
|
||||||
|
}) : _platform = platform,
|
||||||
|
super(artifactName, cache, DevelopmentArtifact.universal);
|
||||||
|
|
||||||
|
final Platform _platform;
|
||||||
|
|
||||||
static const String artifactName = 'font-subset';
|
static const String artifactName = 'font-subset';
|
||||||
|
|
||||||
@ -1400,9 +1485,9 @@ class FontSubsetArtifacts extends EngineCachedArtifact {
|
|||||||
if (cache.includeAllPlatforms) {
|
if (cache.includeAllPlatforms) {
|
||||||
return artifacts.values.toList();
|
return artifacts.values.toList();
|
||||||
} else {
|
} else {
|
||||||
final List<String> binaryDirs = artifacts[globals.platform.operatingSystem];
|
final List<String> binaryDirs = artifacts[_platform.operatingSystem];
|
||||||
if (binaryDirs == null) {
|
if (binaryDirs == null) {
|
||||||
throwToolExit('Unsupported operating system: ${globals.platform.operatingSystem}');
|
throwToolExit('Unsupported operating system: ${_platform.operatingSystem}');
|
||||||
}
|
}
|
||||||
return <List<String>>[binaryDirs];
|
return <List<String>>[binaryDirs];
|
||||||
}
|
}
|
||||||
@ -1417,12 +1502,16 @@ class FontSubsetArtifacts extends EngineCachedArtifact {
|
|||||||
|
|
||||||
/// Cached iOS/USB binary artifacts.
|
/// Cached iOS/USB binary artifacts.
|
||||||
class IosUsbArtifacts extends CachedArtifact {
|
class IosUsbArtifacts extends CachedArtifact {
|
||||||
IosUsbArtifacts(String name, Cache cache) : super(
|
IosUsbArtifacts(String name, Cache cache, {
|
||||||
name,
|
@required Platform platform,
|
||||||
cache,
|
}) : _platform = platform,
|
||||||
// This is universal to ensure every command checks for them first
|
super(
|
||||||
DevelopmentArtifact.universal,
|
name,
|
||||||
);
|
cache,
|
||||||
|
DevelopmentArtifact.universal,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Platform _platform;
|
||||||
|
|
||||||
static const List<String> artifactNames = <String>[
|
static const List<String> artifactNames = <String>[
|
||||||
'libimobiledevice',
|
'libimobiledevice',
|
||||||
@ -1454,7 +1543,7 @@ class IosUsbArtifacts extends CachedArtifact {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isUpToDateInner() {
|
bool isUpToDateInner(FileSystem fileSystem) {
|
||||||
final List<String> executables =_kExecutables[name];
|
final List<String> executables =_kExecutables[name];
|
||||||
if (executables == null) {
|
if (executables == null) {
|
||||||
return true;
|
return true;
|
||||||
@ -1468,14 +1557,18 @@ class IosUsbArtifacts extends CachedArtifact {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) {
|
Future<void> updateInner(
|
||||||
if (!globals.platform.isMacOS && !ignorePlatformFiltering) {
|
ArtifactUpdater artifactUpdater,
|
||||||
return Future<void>.value();
|
FileSystem fileSystem,
|
||||||
|
OperatingSystemUtils operatingSystemUtils,
|
||||||
|
) async {
|
||||||
|
if (!_platform.isMacOS && !ignorePlatformFiltering) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (location.existsSync()) {
|
if (location.existsSync()) {
|
||||||
location.deleteSync(recursive: true);
|
location.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
return artifactUpdater.downloadZipArchive('Downloading $name...', archiveUri, location);
|
await artifactUpdater.downloadZipArchive('Downloading $name...', archiveUri, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
@ -1808,7 +1901,7 @@ class ArtifactUpdater {
|
|||||||
try {
|
try {
|
||||||
file.deleteSync();
|
file.deleteSync();
|
||||||
} on FileSystemException catch (e) {
|
} on FileSystemException catch (e) {
|
||||||
globals.printError('Failed to delete "${file.path}". Please delete manually. $e');
|
_logger.printError('Failed to delete "${file.path}". Please delete manually. $e');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (Directory directory = file.parent; directory.absolute.path != _tempStorage.absolute.path; directory = directory.parent) {
|
for (Directory directory = file.parent; directory.absolute.path != _tempStorage.absolute.path; directory = directory.parent) {
|
||||||
|
@ -130,7 +130,7 @@ class PrecacheCommand extends FlutterCommand {
|
|||||||
Future<FlutterCommandResult> runCommand() async {
|
Future<FlutterCommandResult> runCommand() async {
|
||||||
// Re-lock the cache.
|
// Re-lock the cache.
|
||||||
if (_platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
if (_platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
||||||
await Cache.lock();
|
await _cache.lock();
|
||||||
}
|
}
|
||||||
if (boolArg('force')) {
|
if (boolArg('force')) {
|
||||||
_cache.clearStampFiles();
|
_cache.clearStampFiles();
|
||||||
|
@ -120,6 +120,7 @@ Future<T> runInContext<T>(
|
|||||||
fileSystem: globals.fs,
|
fileSystem: globals.fs,
|
||||||
logger: globals.logger,
|
logger: globals.logger,
|
||||||
platform: globals.platform,
|
platform: globals.platform,
|
||||||
|
osUtils: globals.os,
|
||||||
),
|
),
|
||||||
CocoaPods: () => CocoaPods(
|
CocoaPods: () => CocoaPods(
|
||||||
fileSystem: globals.fs,
|
fileSystem: globals.fs,
|
||||||
|
@ -962,7 +962,7 @@ abstract class FlutterCommand extends Command<void> {
|
|||||||
|
|
||||||
void _registerSignalHandlers(String commandPath, DateTime startTime) {
|
void _registerSignalHandlers(String commandPath, DateTime startTime) {
|
||||||
final SignalHandler handler = (io.ProcessSignal s) {
|
final SignalHandler handler = (io.ProcessSignal s) {
|
||||||
Cache.releaseLock();
|
globals.cache.releaseLock();
|
||||||
_sendPostUsage(
|
_sendPostUsage(
|
||||||
commandPath,
|
commandPath,
|
||||||
const FlutterCommandResult(ExitStatus.killed),
|
const FlutterCommandResult(ExitStatus.killed),
|
||||||
@ -1035,7 +1035,7 @@ abstract class FlutterCommand extends Command<void> {
|
|||||||
await globals.cache.updateAll(<DevelopmentArtifact>{DevelopmentArtifact.universal});
|
await globals.cache.updateAll(<DevelopmentArtifact>{DevelopmentArtifact.universal});
|
||||||
await globals.cache.updateAll(await requiredArtifacts);
|
await globals.cache.updateAll(await requiredArtifacts);
|
||||||
}
|
}
|
||||||
Cache.releaseLock();
|
globals.cache.releaseLock();
|
||||||
|
|
||||||
await validateCommand();
|
await validateCommand();
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
|||||||
globals.logger.quiet = topLevelResults['quiet'] as bool;
|
globals.logger.quiet = topLevelResults['quiet'] as bool;
|
||||||
|
|
||||||
if (globals.platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
if (globals.platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
|
||||||
await Cache.lock();
|
await globals.cache.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topLevelResults['suppress-analytics'] as bool) {
|
if (topLevelResults['suppress-analytics'] as bool) {
|
||||||
|
@ -484,7 +484,7 @@ class FlutterVersion {
|
|||||||
/// Returns null if the cached version is out-of-date or missing, and we are
|
/// Returns null if the cached version is out-of-date or missing, and we are
|
||||||
/// unable to reach the server to get the latest version.
|
/// unable to reach the server to get the latest version.
|
||||||
Future<DateTime> _getLatestAvailableFlutterDate() async {
|
Future<DateTime> _getLatestAvailableFlutterDate() async {
|
||||||
Cache.checkLockAcquired();
|
globals.cache.checkLockAcquired();
|
||||||
final VersionCheckStamp versionCheckStamp = await VersionCheckStamp.load();
|
final VersionCheckStamp versionCheckStamp = await VersionCheckStamp.load();
|
||||||
|
|
||||||
if (versionCheckStamp.lastTimeVersionWasChecked != null) {
|
if (versionCheckStamp.lastTimeVersionWasChecked != null) {
|
||||||
|
@ -20,7 +20,7 @@ void main() {
|
|||||||
setUp(() {
|
setUp(() {
|
||||||
cache = MockCache();
|
cache = MockCache();
|
||||||
// Release lock between test cases.
|
// Release lock between test cases.
|
||||||
Cache.releaseLock();
|
cache.releaseLock();
|
||||||
|
|
||||||
when(cache.isUpToDate()).thenAnswer((Invocation _) => Future<bool>.value(false));
|
when(cache.isUpToDate()).thenAnswer((Invocation _) => Future<bool>.value(false));
|
||||||
when(cache.updateAll(any)).thenAnswer((Invocation invocation) {
|
when(cache.updateAll(any)).thenAnswer((Invocation invocation) {
|
||||||
@ -39,9 +39,8 @@ void main() {
|
|||||||
);
|
);
|
||||||
await createTestCommandRunner(command).run(const <String>['precache']);
|
await createTestCommandRunner(command).run(const <String>['precache']);
|
||||||
|
|
||||||
expect(Cache.isLocked(), isTrue);
|
|
||||||
// Do not throw StateError, lock is acquired.
|
// Do not throw StateError, lock is acquired.
|
||||||
expect(() => Cache.checkLockAcquired(platform), returnsNormally);
|
expect(() => cache.checkLockAcquired(), returnsNormally);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('precache should not re-entrantly acquire lock', () async {
|
testUsingContext('precache should not re-entrantly acquire lock', () async {
|
||||||
@ -62,7 +61,7 @@ void main() {
|
|||||||
|
|
||||||
expect(Cache.isLocked(), isFalse);
|
expect(Cache.isLocked(), isFalse);
|
||||||
// Do not throw StateError, acquired reentrantly with FLUTTER_ALREADY_LOCKED.
|
// Do not throw StateError, acquired reentrantly with FLUTTER_ALREADY_LOCKED.
|
||||||
expect(() => Cache.checkLockAcquired(platform), returnsNormally);
|
expect(() => cache.checkLockAcquired(), returnsNormally);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('precache downloads web artifacts on dev branch when feature is enabled.', () async {
|
testUsingContext('precache downloads web artifacts on dev branch when feature is enabled.', () async {
|
||||||
|
@ -1024,7 +1024,7 @@ plugin1=${plugin1.path}
|
|||||||
when(mockAndroidSdk.directory).thenReturn('irrelevant');
|
when(mockAndroidSdk.directory).thenReturn('irrelevant');
|
||||||
|
|
||||||
final Directory rootDirectory = fileSystem.currentDirectory;
|
final Directory rootDirectory = fileSystem.currentDirectory;
|
||||||
cache = Cache(
|
cache = Cache.test(
|
||||||
rootOverride: rootDirectory,
|
rootOverride: rootDirectory,
|
||||||
fileSystem: fileSystem,
|
fileSystem: fileSystem,
|
||||||
);
|
);
|
||||||
|
@ -72,7 +72,7 @@ void main() {
|
|||||||
'zipStorePath=wrapper/dists\n'
|
'zipStorePath=wrapper/dists\n'
|
||||||
'distributionUrl=https\\://services.gradle.org/distributions/gradle-5.6.2-all.zip\n');
|
'distributionUrl=https\\://services.gradle.org/distributions/gradle-5.6.2-all.zip\n');
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Cache: () => Cache(rootOverride: tempDir),
|
Cache: () => Cache.test(rootOverride: tempDir, fileSystem: memoryFileSystem),
|
||||||
FileSystem: () => memoryFileSystem,
|
FileSystem: () => memoryFileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
});
|
});
|
||||||
@ -113,7 +113,7 @@ void main() {
|
|||||||
'zipStorePath=wrapper/dists\n'
|
'zipStorePath=wrapper/dists\n'
|
||||||
'distributionUrl=https\\://services.gradle.org/distributions/gradle-5.6.2-all.zip\n');
|
'distributionUrl=https\\://services.gradle.org/distributions/gradle-5.6.2-all.zip\n');
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Cache: () => Cache(rootOverride: tempDir),
|
Cache: () => Cache.test(rootOverride: tempDir, fileSystem: memoryFileSystem),
|
||||||
FileSystem: () => memoryFileSystem,
|
FileSystem: () => memoryFileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
});
|
});
|
||||||
|
@ -14,29 +14,16 @@ import 'package:flutter_tools/src/base/os.dart';
|
|||||||
import 'package:flutter_tools/src/base/platform.dart';
|
import 'package:flutter_tools/src/base/platform.dart';
|
||||||
import 'package:flutter_tools/src/cache.dart';
|
import 'package:flutter_tools/src/cache.dart';
|
||||||
import 'package:flutter_tools/src/dart/pub.dart';
|
import 'package:flutter_tools/src/dart/pub.dart';
|
||||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
import 'package:process/process.dart';
|
import 'package:process/process.dart';
|
||||||
|
|
||||||
import '../src/common.dart';
|
import '../src/common.dart';
|
||||||
import '../src/context.dart';
|
import '../src/context.dart';
|
||||||
import '../src/testbed.dart';
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('$Cache.checkLockAcquired', () {
|
group('Cache.checkLockAcquired', () {
|
||||||
MockFileSystem mockFileSystem;
|
|
||||||
MemoryFileSystem memoryFileSystem;
|
|
||||||
MockFile mockFile;
|
|
||||||
MockRandomAccessFile mockRandomAccessFile;
|
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
mockFileSystem = MockFileSystem();
|
|
||||||
memoryFileSystem = MemoryFileSystem.test();
|
|
||||||
mockFile = MockFile();
|
|
||||||
mockRandomAccessFile = MockRandomAccessFile();
|
|
||||||
when(mockFileSystem.path).thenReturn(memoryFileSystem.path);
|
|
||||||
|
|
||||||
Cache.enableLocking();
|
Cache.enableLocking();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -44,145 +31,146 @@ void main() {
|
|||||||
// Restore locking to prevent potential side-effects in
|
// Restore locking to prevent potential side-effects in
|
||||||
// tests outside this group (this option is globally shared).
|
// tests outside this group (this option is globally shared).
|
||||||
Cache.enableLocking();
|
Cache.enableLocking();
|
||||||
Cache.releaseLock();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should throw when locking is not acquired', () {
|
testWithoutContext('should throw when locking is not acquired', () {
|
||||||
expect(Cache.checkLockAcquired, throwsStateError);
|
final Cache cache = Cache.test();
|
||||||
|
|
||||||
|
expect(cache.checkLockAcquired, throwsStateError);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not throw when locking is disabled', () {
|
testWithoutContext('should not throw when locking is disabled', () {
|
||||||
|
final Cache cache = Cache.test();
|
||||||
Cache.disableLocking();
|
Cache.disableLocking();
|
||||||
Cache.checkLockAcquired();
|
|
||||||
|
expect(cache.checkLockAcquired, returnsNormally);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('should not throw when lock is acquired', () async {
|
testWithoutContext('should not throw when lock is acquired', () async {
|
||||||
when(mockFileSystem.file(argThat(endsWith('lockfile')))).thenReturn(mockFile);
|
Cache.flutterRoot = '';
|
||||||
when(mockFile.openSync(mode: anyNamed('mode'))).thenReturn(mockRandomAccessFile);
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
await Cache.lock();
|
final Cache cache = Cache.test(fileSystem: fileSystem);
|
||||||
Cache.checkLockAcquired();
|
fileSystem.file(fileSystem.path.join('bin', 'cache', 'lockfile'))
|
||||||
Cache.releaseLock();
|
.createSync(recursive: true);
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => mockFileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('throws tool exit when lockfile open fails', () async {
|
await cache.lock();
|
||||||
when(mockFileSystem.file(argThat(endsWith('lockfile')))).thenReturn(mockFile);
|
|
||||||
when(mockFile.openSync(mode: anyNamed('mode'))).thenThrow(const FileSystemException());
|
|
||||||
expect(() async => await Cache.lock(), throwsToolExit());
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => mockFileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('should not throw when FLUTTER_ALREADY_LOCKED is set', () async {
|
expect(cache.checkLockAcquired, returnsNormally);
|
||||||
Cache.checkLockAcquired();
|
expect(cache.releaseLock, returnsNormally);
|
||||||
}, overrides: <Type, Generator>{
|
}, skip: true); // TODO(jonahwilliams): implement support for lock so this can be tested with the memory file system.
|
||||||
Platform: () => FakePlatform()..environment = <String, String>{'FLUTTER_ALREADY_LOCKED': 'true'},
|
|
||||||
|
testWithoutContext('throws tool exit when lockfile open fails', () async {
|
||||||
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
|
final Cache cache = Cache.test(fileSystem: fileSystem);
|
||||||
|
fileSystem.file(fileSystem.path.join('bin', 'cache', 'lockfile'))
|
||||||
|
.createSync(recursive: true);
|
||||||
|
|
||||||
|
expect(() async => await cache.lock(), throwsToolExit());
|
||||||
|
}, skip: true); // TODO(jonahwilliams): implement support for lock so this can be tested with the memory file system.
|
||||||
|
|
||||||
|
testWithoutContext('should not throw when FLUTTER_ALREADY_LOCKED is set', () {
|
||||||
|
final Cache cache = Cache.test(platform: FakePlatform(environment: <String, String>{
|
||||||
|
'FLUTTER_ALREADY_LOCKED': 'true',
|
||||||
|
}));
|
||||||
|
|
||||||
|
expect(cache.checkLockAcquired, returnsNormally);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Cache', () {
|
group('Cache', () {
|
||||||
MockCache mockCache;
|
testWithoutContext('Continues on failed stamp file update', () async {
|
||||||
Cache cache;
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
MemoryFileSystem memoryFileSystem;
|
final BufferLogger logger = BufferLogger.test();
|
||||||
ProcessManager fakeProcessManager;
|
final Cache mockCache = MockCache();
|
||||||
|
final Directory artifactDir = fileSystem.systemTempDirectory.createTempSync('flutter_cache_test_artifact.');
|
||||||
|
final Directory downloadDir = fileSystem.systemTempDirectory.createTempSync('flutter_cache_test_download.');
|
||||||
|
|
||||||
setUp(() {
|
|
||||||
fakeProcessManager = FakeProcessManager.any();
|
|
||||||
mockCache = MockCache();
|
|
||||||
cache = Cache.test(
|
|
||||||
fileSystem: memoryFileSystem,
|
|
||||||
processManager: fakeProcessManager,
|
|
||||||
);
|
|
||||||
memoryFileSystem = MemoryFileSystem.test();
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('Continues on failed stamp file update', () async {
|
|
||||||
final Directory artifactDir = globals.fs.systemTempDirectory.createTempSync('flutter_cache_test_artifact.');
|
|
||||||
final Directory downloadDir = globals.fs.systemTempDirectory.createTempSync('flutter_cache_test_download.');
|
|
||||||
when(mockCache.getArtifactDirectory(any)).thenReturn(artifactDir);
|
when(mockCache.getArtifactDirectory(any)).thenReturn(artifactDir);
|
||||||
when(mockCache.getDownloadDir()).thenReturn(downloadDir);
|
when(mockCache.getDownloadDir()).thenReturn(downloadDir);
|
||||||
when(mockCache.setStampFor(any, any)).thenAnswer((_) {
|
when(mockCache.setStampFor(any, any)).thenAnswer((_) {
|
||||||
throw const FileSystemException('stamp write failed');
|
throw const FileSystemException('stamp write failed');
|
||||||
});
|
});
|
||||||
final FakeSimpleArtifact artifact = FakeSimpleArtifact(mockCache);
|
final FakeSimpleArtifact artifact = FakeSimpleArtifact(mockCache);
|
||||||
await artifact.update(MockArtifactUpdater());
|
await artifact.update(MockArtifactUpdater(), logger, fileSystem, MockOperatingSystemUtils());
|
||||||
expect(testLogger.errorText, contains('stamp write failed'));
|
|
||||||
}, overrides: <Type, Generator>{
|
expect(logger.errorText, contains('stamp write failed'));
|
||||||
Cache: () => mockCache,
|
|
||||||
FileSystem: () => memoryFileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('Gradle wrapper should not be up to date, if some cached artifact is not available', () {
|
testWithoutContext('Gradle wrapper should not be up to date, if some cached artifact is not available', () {
|
||||||
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
|
final Cache cache = Cache.test(fileSystem: fileSystem, processManager: FakeProcessManager.any());
|
||||||
final GradleWrapper gradleWrapper = GradleWrapper(cache);
|
final GradleWrapper gradleWrapper = GradleWrapper(cache);
|
||||||
final Directory directory = cache.getCacheDir(globals.fs.path.join('artifacts', 'gradle_wrapper'));
|
final Directory directory = cache.getCacheDir(fileSystem.path.join('artifacts', 'gradle_wrapper'));
|
||||||
globals.fs.file(globals.fs.path.join(directory.path, 'gradle', 'wrapper', 'gradle-wrapper.jar')).createSync(recursive: true);
|
fileSystem.file(fileSystem.path.join(directory.path, 'gradle', 'wrapper', 'gradle-wrapper.jar')).createSync(recursive: true);
|
||||||
|
|
||||||
expect(gradleWrapper.isUpToDateInner(), false);
|
expect(gradleWrapper.isUpToDateInner(fileSystem), false);
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Cache: () => cache,
|
|
||||||
FileSystem: () => memoryFileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('Gradle wrapper should be up to date, only if all cached artifact are available', () {
|
testWithoutContext('Gradle wrapper should be up to date, only if all cached artifact are available', () {
|
||||||
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
|
final Cache cache = Cache.test(fileSystem: fileSystem, processManager: FakeProcessManager.any());
|
||||||
final GradleWrapper gradleWrapper = GradleWrapper(cache);
|
final GradleWrapper gradleWrapper = GradleWrapper(cache);
|
||||||
final Directory directory = cache.getCacheDir(globals.fs.path.join('artifacts', 'gradle_wrapper'));
|
final Directory directory = cache.getCacheDir(fileSystem.path.join('artifacts', 'gradle_wrapper'));
|
||||||
globals.fs.file(globals.fs.path.join(directory.path, 'gradle', 'wrapper', 'gradle-wrapper.jar')).createSync(recursive: true);
|
fileSystem.file(fileSystem.path.join(directory.path, 'gradle', 'wrapper', 'gradle-wrapper.jar')).createSync(recursive: true);
|
||||||
globals.fs.file(globals.fs.path.join(directory.path, 'gradlew')).createSync(recursive: true);
|
fileSystem.file(fileSystem.path.join(directory.path, 'gradlew')).createSync(recursive: true);
|
||||||
globals.fs.file(globals.fs.path.join(directory.path, 'gradlew.bat')).createSync(recursive: true);
|
fileSystem.file(fileSystem.path.join(directory.path, 'gradlew.bat')).createSync(recursive: true);
|
||||||
|
|
||||||
expect(gradleWrapper.isUpToDateInner(), true);
|
expect(gradleWrapper.isUpToDateInner(fileSystem), true);
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Cache: () => cache,
|
|
||||||
FileSystem: () => memoryFileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('should not be up to date, if some cached artifact is not', () async {
|
testWithoutContext('should not be up to date, if some cached artifact is not', () async {
|
||||||
final CachedArtifact artifact1 = MockCachedArtifact();
|
final CachedArtifact artifact1 = MockCachedArtifact();
|
||||||
final CachedArtifact artifact2 = MockCachedArtifact();
|
final CachedArtifact artifact2 = MockCachedArtifact();
|
||||||
when(artifact1.isUpToDate()).thenAnswer((Invocation _) => Future<bool>.value(true));
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
when(artifact2.isUpToDate()).thenAnswer((Invocation _) => Future<bool>.value(false));
|
|
||||||
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
|
when(artifact1.isUpToDate(fileSystem)).thenAnswer((Invocation _) => Future<bool>.value(true));
|
||||||
|
when(artifact2.isUpToDate(fileSystem)).thenAnswer((Invocation _) => Future<bool>.value(false));
|
||||||
|
final Cache cache = Cache.test(
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
artifacts: <CachedArtifact>[artifact1, artifact2],
|
||||||
|
processManager: FakeProcessManager.any(),
|
||||||
|
);
|
||||||
|
|
||||||
expect(await cache.isUpToDate(), isFalse);
|
expect(await cache.isUpToDate(), isFalse);
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
FileSystem: () => MemoryFileSystem.test(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('should be up to date, if all cached artifacts are', () async {
|
testWithoutContext('should be up to date, if all cached artifacts are', () async {
|
||||||
final CachedArtifact artifact1 = MockCachedArtifact();
|
final CachedArtifact artifact1 = MockCachedArtifact();
|
||||||
final CachedArtifact artifact2 = MockCachedArtifact();
|
final CachedArtifact artifact2 = MockCachedArtifact();
|
||||||
when(artifact1.isUpToDate()).thenAnswer((Invocation _) => Future<bool>.value(true));
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
when(artifact2.isUpToDate()).thenAnswer((Invocation _) => Future<bool>.value(true));
|
|
||||||
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
|
when(artifact1.isUpToDate(fileSystem)).thenAnswer((Invocation _) => Future<bool>.value(true));
|
||||||
|
when(artifact2.isUpToDate(fileSystem)).thenAnswer((Invocation _) => Future<bool>.value(true));
|
||||||
|
final Cache cache = Cache.test(
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
artifacts: <CachedArtifact>[artifact1, artifact2],
|
||||||
|
processManager: FakeProcessManager.any(),
|
||||||
|
);
|
||||||
|
|
||||||
expect(await cache.isUpToDate(), isTrue);
|
expect(await cache.isUpToDate(), isTrue);
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
FileSystem: () => MemoryFileSystem.test(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('should update cached artifacts which are not up to date', () async {
|
testWithoutContext('should update cached artifacts which are not up to date', () async {
|
||||||
final CachedArtifact artifact1 = MockCachedArtifact();
|
final CachedArtifact artifact1 = MockCachedArtifact();
|
||||||
final CachedArtifact artifact2 = MockCachedArtifact();
|
final CachedArtifact artifact2 = MockCachedArtifact();
|
||||||
when(artifact1.isUpToDate()).thenAnswer((Invocation _) => Future<bool>.value(true));
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
when(artifact2.isUpToDate()).thenAnswer((Invocation _) => Future<bool>.value(false));
|
|
||||||
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
|
when(artifact1.isUpToDate(fileSystem)).thenAnswer((Invocation _) => Future<bool>.value(true));
|
||||||
|
when(artifact2.isUpToDate(fileSystem)).thenAnswer((Invocation _) => Future<bool>.value(false));
|
||||||
|
final Cache cache = Cache.test(
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
artifacts: <CachedArtifact>[artifact1, artifact2],
|
||||||
|
processManager: FakeProcessManager.any(),
|
||||||
|
);
|
||||||
|
|
||||||
await cache.updateAll(<DevelopmentArtifact>{
|
await cache.updateAll(<DevelopmentArtifact>{
|
||||||
null,
|
null,
|
||||||
});
|
});
|
||||||
verifyNever(artifact1.update(any));
|
verifyNever(artifact1.update(any, any, any, any));
|
||||||
verify(artifact2.update(any));
|
verify(artifact2.update(any, any, any, any));
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
FileSystem: () => MemoryFileSystem.test(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext("getter dyLdLibEntry concatenates the output of each artifact's dyLdLibEntry getter", () async {
|
testWithoutContext("getter dyLdLibEntry concatenates the output of each artifact's dyLdLibEntry getter", () async {
|
||||||
final IosUsbArtifacts artifact1 = MockIosUsbArtifacts();
|
final IosUsbArtifacts artifact1 = MockIosUsbArtifacts();
|
||||||
final IosUsbArtifacts artifact2 = MockIosUsbArtifacts();
|
final IosUsbArtifacts artifact2 = MockIosUsbArtifacts();
|
||||||
final IosUsbArtifacts artifact3 = MockIosUsbArtifacts();
|
final IosUsbArtifacts artifact3 = MockIosUsbArtifacts();
|
||||||
@ -198,7 +186,10 @@ void main() {
|
|||||||
.thenReturn(<String, String>{
|
.thenReturn(<String, String>{
|
||||||
'DYLD_LIBRARY_PATH': '',
|
'DYLD_LIBRARY_PATH': '',
|
||||||
});
|
});
|
||||||
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2, artifact3]);
|
final Cache cache = Cache.test(
|
||||||
|
artifacts: <CachedArtifact>[artifact1, artifact2, artifact3],
|
||||||
|
processManager: FakeProcessManager.any(),
|
||||||
|
);
|
||||||
|
|
||||||
expect(cache.dyLdLibEntry.key, 'DYLD_LIBRARY_PATH');
|
expect(cache.dyLdLibEntry.key, 'DYLD_LIBRARY_PATH');
|
||||||
expect(
|
expect(
|
||||||
@ -207,45 +198,47 @@ void main() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('failed storage.googleapis.com download shows China warning', () async {
|
testWithoutContext('failed storage.googleapis.com download shows China warning', () async {
|
||||||
final CachedArtifact artifact1 = MockCachedArtifact();
|
final CachedArtifact artifact1 = MockCachedArtifact();
|
||||||
final CachedArtifact artifact2 = MockCachedArtifact();
|
final CachedArtifact artifact2 = MockCachedArtifact();
|
||||||
when(artifact1.isUpToDate()).thenAnswer((Invocation _) => Future<bool>.value(false));
|
when(artifact1.isUpToDate(any)).thenAnswer((Invocation _) => Future<bool>.value(false));
|
||||||
when(artifact2.isUpToDate()).thenAnswer((Invocation _) => Future<bool>.value(false));
|
when(artifact2.isUpToDate(any)).thenAnswer((Invocation _) => Future<bool>.value(false));
|
||||||
final MockInternetAddress address = MockInternetAddress();
|
final MockInternetAddress address = MockInternetAddress();
|
||||||
when(address.host).thenReturn('storage.googleapis.com');
|
when(address.host).thenReturn('storage.googleapis.com');
|
||||||
when(artifact1.update(any)).thenThrow(SocketException(
|
when(artifact1.update(any, any, any, any)).thenThrow(SocketException(
|
||||||
'Connection reset by peer',
|
'Connection reset by peer',
|
||||||
address: address,
|
address: address,
|
||||||
));
|
));
|
||||||
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
|
final BufferLogger logger = BufferLogger.test();
|
||||||
|
final Cache cache = Cache.test(
|
||||||
|
artifacts: <CachedArtifact>[artifact1, artifact2],
|
||||||
|
processManager: FakeProcessManager.any(),
|
||||||
|
logger: logger,
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
await cache.updateAll(<DevelopmentArtifact>{
|
await cache.updateAll(<DevelopmentArtifact>{
|
||||||
null,
|
null,
|
||||||
});
|
});
|
||||||
fail('Mock thrown exception expected');
|
fail('Mock thrown exception expected');
|
||||||
} on Exception {
|
} on Exception {
|
||||||
verify(artifact1.update(any));
|
verify(artifact1.update(any, any, any, any));
|
||||||
// Don't continue when retrieval fails.
|
// Don't continue when retrieval fails.
|
||||||
verifyNever(artifact2.update(any));
|
verifyNever(artifact2.update(any, any, any, any));
|
||||||
expect(
|
expect(
|
||||||
testLogger.errorText,
|
logger.errorText,
|
||||||
contains('https://flutter.dev/community/china'),
|
contains('https://flutter.dev/community/china'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
FileSystem: () => MemoryFileSystem.test(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('Invalid URI for FLUTTER_STORAGE_BASE_URL throws ToolExit', () async {
|
testWithoutContext('Invalid URI for FLUTTER_STORAGE_BASE_URL throws ToolExit', () async {
|
||||||
final Cache cache = Cache();
|
final Cache cache = Cache.test(
|
||||||
|
platform: FakePlatform(environment: <String, String>{
|
||||||
|
'FLUTTER_STORAGE_BASE_URL': ' http://foo',
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
expect(() => cache.storageBaseUrl, throwsToolExit());
|
expect(() => cache.storageBaseUrl, throwsToolExit());
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Platform: () => FakePlatform(environment: <String, String>{
|
|
||||||
'FLUTTER_STORAGE_BASE_URL': ' http://foo',
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -255,176 +248,96 @@ void main() {
|
|||||||
expect(flattenNameSubdirs(Uri.parse('https://www.flutter.dev'), MemoryFileSystem.test()), 'www.flutter.dev');
|
expect(flattenNameSubdirs(Uri.parse('https://www.flutter.dev'), MemoryFileSystem.test()), 'www.flutter.dev');
|
||||||
});
|
});
|
||||||
|
|
||||||
group('EngineCachedArtifact', () {
|
testWithoutContext('EngineCachedArtifact makes binary dirs readable and executable by all', () async {
|
||||||
FakePlatform fakePlatform;
|
final OperatingSystemUtils operatingSystemUtils = MockOperatingSystemUtils();
|
||||||
MemoryFileSystem fileSystem;
|
final MockCache cache = MockCache();
|
||||||
MockCache mockCache;
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
MockOperatingSystemUtils mockOperatingSystemUtils;
|
final Directory artifactDir = fileSystem.systemTempDirectory.createTempSync('flutter_cache_test_artifact.');
|
||||||
|
final Directory downloadDir = fileSystem.systemTempDirectory.createTempSync('flutter_cache_test_download.');
|
||||||
|
|
||||||
setUp(() {
|
when(cache.getArtifactDirectory(any)).thenReturn(artifactDir);
|
||||||
fakePlatform = FakePlatform(environment: const <String, String>{}, operatingSystem: 'linux');
|
when(cache.getDownloadDir()).thenReturn(downloadDir);
|
||||||
mockCache = MockCache();
|
artifactDir.childDirectory('bin_dir').createSync();
|
||||||
mockOperatingSystemUtils = MockOperatingSystemUtils();
|
artifactDir.childFile('unused_url_path').createSync();
|
||||||
fileSystem = MemoryFileSystem.test();
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('makes binary dirs readable and executable by all', () async {
|
final FakeCachedArtifact artifact = FakeCachedArtifact(
|
||||||
final Directory artifactDir = fileSystem.systemTempDirectory.createTempSync('flutter_cache_test_artifact.');
|
cache: cache,
|
||||||
final Directory downloadDir = fileSystem.systemTempDirectory.createTempSync('flutter_cache_test_download.');
|
binaryDirs: <List<String>>[
|
||||||
when(mockCache.getArtifactDirectory(any)).thenReturn(artifactDir);
|
<String>['bin_dir', 'unused_url_path'],
|
||||||
when(mockCache.getDownloadDir()).thenReturn(downloadDir);
|
],
|
||||||
artifactDir.childDirectory('bin_dir').createSync();
|
requiredArtifacts: DevelopmentArtifact.universal,
|
||||||
artifactDir.childFile('unused_url_path').createSync();
|
);
|
||||||
|
await artifact.updateInner(MockArtifactUpdater(), fileSystem, operatingSystemUtils);
|
||||||
|
final Directory dir = fileSystem.systemTempDirectory
|
||||||
|
.listSync(recursive: true)
|
||||||
|
.whereType<Directory>()
|
||||||
|
.singleWhere((Directory directory) => directory.basename == 'bin_dir', orElse: () => null);
|
||||||
|
|
||||||
final FakeCachedArtifact artifact = FakeCachedArtifact(
|
expect(dir, isNotNull);
|
||||||
cache: mockCache,
|
expect(dir.path, artifactDir.childDirectory('bin_dir').path);
|
||||||
binaryDirs: <List<String>>[
|
verify(operatingSystemUtils.chmod(argThat(hasPath(dir.path)), 'a+r,a+x'));
|
||||||
<String>['bin_dir', 'unused_url_path'],
|
|
||||||
],
|
|
||||||
requiredArtifacts: DevelopmentArtifact.universal,
|
|
||||||
);
|
|
||||||
await artifact.updateInner(MockArtifactUpdater());
|
|
||||||
final Directory dir = fileSystem.systemTempDirectory
|
|
||||||
.listSync(recursive: true)
|
|
||||||
.whereType<Directory>()
|
|
||||||
.singleWhere((Directory directory) => directory.basename == 'bin_dir', orElse: () => null);
|
|
||||||
expect(dir, isNotNull);
|
|
||||||
expect(dir.path, artifactDir.childDirectory('bin_dir').path);
|
|
||||||
verify(mockOperatingSystemUtils.chmod(argThat(hasPath(dir.path)), 'a+r,a+x'));
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Cache: () => mockCache,
|
|
||||||
FileSystem: () => fileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
OperatingSystemUtils: () => mockOperatingSystemUtils,
|
|
||||||
Platform: () => fakePlatform,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
group('AndroidMavenArtifacts', () {
|
testWithoutContext('IosUsbArtifacts verifies executables for libimobiledevice in isUpToDateInner', () async {
|
||||||
MemoryFileSystem memoryFileSystem;
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
MockProcessManager processManager;
|
final Cache cache = Cache.test(fileSystem: fileSystem, processManager: FakeProcessManager.any());
|
||||||
Cache cache;
|
final IosUsbArtifacts iosUsbArtifacts = IosUsbArtifacts('libimobiledevice', cache, platform: FakePlatform(operatingSystem: 'macos'));
|
||||||
|
iosUsbArtifacts.location.createSync();
|
||||||
|
final File ideviceScreenshotFile = iosUsbArtifacts.location.childFile('idevicescreenshot')
|
||||||
|
..createSync();
|
||||||
|
iosUsbArtifacts.location.childFile('idevicesyslog')
|
||||||
|
.createSync();
|
||||||
|
|
||||||
setUp(() {
|
expect(iosUsbArtifacts.isUpToDateInner(fileSystem), true);
|
||||||
memoryFileSystem = MemoryFileSystem.test();
|
|
||||||
processManager = MockProcessManager();
|
|
||||||
cache = Cache.test(
|
|
||||||
fileSystem: memoryFileSystem,
|
|
||||||
processManager: FakeProcessManager.any(),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('development artifact', () async {
|
ideviceScreenshotFile.deleteSync();
|
||||||
final AndroidMavenArtifacts mavenArtifacts = AndroidMavenArtifacts(cache);
|
|
||||||
expect(mavenArtifacts.developmentArtifact, DevelopmentArtifact.androidMaven);
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('update', () async {
|
expect(iosUsbArtifacts.isUpToDateInner(fileSystem), false);
|
||||||
final AndroidMavenArtifacts mavenArtifacts = AndroidMavenArtifacts(cache);
|
|
||||||
expect(await mavenArtifacts.isUpToDate(), isFalse);
|
|
||||||
|
|
||||||
final Directory gradleWrapperDir = cache.getArtifactDirectory('gradle_wrapper')..createSync(recursive: true);
|
|
||||||
gradleWrapperDir.childFile('gradlew').writeAsStringSync('irrelevant');
|
|
||||||
gradleWrapperDir.childFile('gradlew.bat').writeAsStringSync('irrelevant');
|
|
||||||
|
|
||||||
when(globals.processManager.run(any, environment: captureAnyNamed('environment')))
|
|
||||||
.thenAnswer((Invocation invocation) {
|
|
||||||
final List<String> args = invocation.positionalArguments[0] as List<String>;
|
|
||||||
expect(args.length, 6);
|
|
||||||
expect(args[1], '-b');
|
|
||||||
expect(args[2].endsWith('resolve_dependencies.gradle'), isTrue);
|
|
||||||
expect(args[5], 'resolveDependencies');
|
|
||||||
expect(invocation.namedArguments[#environment], gradleEnvironment);
|
|
||||||
return Future<ProcessResult>.value(ProcessResult(0, 0, '', ''));
|
|
||||||
});
|
|
||||||
|
|
||||||
await mavenArtifacts.update(MockArtifactUpdater());
|
|
||||||
|
|
||||||
expect(await mavenArtifacts.isUpToDate(), isFalse);
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Cache: () => cache,
|
|
||||||
FileSystem: () => memoryFileSystem,
|
|
||||||
ProcessManager: () => processManager,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
group('macOS artifacts', () {
|
testWithoutContext('IosUsbArtifacts verifies iproxy for usbmuxd in isUpToDateInner', () async {
|
||||||
Cache cache;
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
|
final Cache cache = Cache.test(fileSystem: fileSystem, processManager: FakeProcessManager.any());
|
||||||
|
final IosUsbArtifacts iosUsbArtifacts = IosUsbArtifacts('usbmuxd', cache, platform: FakePlatform(operatingSystem: 'macos'));
|
||||||
|
iosUsbArtifacts.location.createSync();
|
||||||
|
final File iproxy = iosUsbArtifacts.location.childFile('iproxy')
|
||||||
|
..createSync();
|
||||||
|
|
||||||
setUp(() {
|
expect(iosUsbArtifacts.isUpToDateInner(fileSystem), true);
|
||||||
cache = Cache.test(
|
|
||||||
processManager: FakeProcessManager.any(),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('verifies executables for libimobiledevice in isUpToDateInner', () async {
|
iproxy.deleteSync();
|
||||||
final IosUsbArtifacts iosUsbArtifacts = IosUsbArtifacts('libimobiledevice', cache);
|
|
||||||
iosUsbArtifacts.location.createSync();
|
|
||||||
final File ideviceScreenshotFile = iosUsbArtifacts.location.childFile('idevicescreenshot')
|
|
||||||
..createSync();
|
|
||||||
iosUsbArtifacts.location.childFile('idevicesyslog')
|
|
||||||
.createSync();
|
|
||||||
|
|
||||||
expect(iosUsbArtifacts.isUpToDateInner(), true);
|
expect(iosUsbArtifacts.isUpToDateInner(fileSystem), false);
|
||||||
|
|
||||||
ideviceScreenshotFile.deleteSync();
|
|
||||||
|
|
||||||
expect(iosUsbArtifacts.isUpToDateInner(), false);
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Cache: () => cache,
|
|
||||||
FileSystem: () => MemoryFileSystem.test(),
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('verifies iproxy for usbmuxd in isUpToDateInner', () async {
|
|
||||||
final IosUsbArtifacts iosUsbArtifacts = IosUsbArtifacts('usbmuxd', cache);
|
|
||||||
iosUsbArtifacts.location.createSync();
|
|
||||||
final File iproxy = iosUsbArtifacts.location.childFile('iproxy')
|
|
||||||
..createSync();
|
|
||||||
|
|
||||||
expect(iosUsbArtifacts.isUpToDateInner(), true);
|
|
||||||
|
|
||||||
iproxy.deleteSync();
|
|
||||||
|
|
||||||
expect(iosUsbArtifacts.isUpToDateInner(), false);
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Cache: () => cache,
|
|
||||||
FileSystem: () => MemoryFileSystem.test(),
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('Does not verify executables for openssl in isUpToDateInner', () async {
|
|
||||||
final IosUsbArtifacts iosUsbArtifacts = IosUsbArtifacts('openssl', cache);
|
|
||||||
iosUsbArtifacts.location.createSync();
|
|
||||||
|
|
||||||
expect(iosUsbArtifacts.isUpToDateInner(), true);
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Cache: () => cache,
|
|
||||||
FileSystem: () => MemoryFileSystem.test(),
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('use unsigned when specified', () async {
|
|
||||||
cache.useUnsignedMacBinaries = true;
|
|
||||||
|
|
||||||
final IosUsbArtifacts iosUsbArtifacts = IosUsbArtifacts('name', cache);
|
|
||||||
expect(iosUsbArtifacts.archiveUri.toString(), contains('/unsigned/'));
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Cache: () => cache,
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('not use unsigned when not specified', () async {
|
|
||||||
cache.useUnsignedMacBinaries = false;
|
|
||||||
|
|
||||||
final IosUsbArtifacts iosUsbArtifacts = IosUsbArtifacts('name', cache);
|
|
||||||
expect(iosUsbArtifacts.archiveUri.toString(), isNot(contains('/unsigned/')));
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
Cache: () => cache,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('Downloads Flutter runner debug symbols', () async {
|
testWithoutContext('IosUsbArtifacts does not verify executables for openssl in isUpToDateInner', () async {
|
||||||
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
|
final Cache cache = Cache.test(fileSystem: fileSystem, processManager: FakeProcessManager.any());
|
||||||
|
final IosUsbArtifacts iosUsbArtifacts = IosUsbArtifacts('openssl', cache, platform: FakePlatform(operatingSystem: 'macos'));
|
||||||
|
iosUsbArtifacts.location.createSync();
|
||||||
|
|
||||||
|
expect(iosUsbArtifacts.isUpToDateInner(fileSystem), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('IosUsbArtifacts uses unsigned when specified', () async {
|
||||||
|
final Cache cache = Cache.test();
|
||||||
|
cache.useUnsignedMacBinaries = true;
|
||||||
|
|
||||||
|
final IosUsbArtifacts iosUsbArtifacts = IosUsbArtifacts('name', cache, platform: FakePlatform(operatingSystem: 'macos'));
|
||||||
|
expect(iosUsbArtifacts.archiveUri.toString(), contains('/unsigned/'));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('IosUsbArtifacts does not use unsigned when not specified', () async {
|
||||||
|
final Cache cache = Cache.test();
|
||||||
|
final IosUsbArtifacts iosUsbArtifacts = IosUsbArtifacts('name', cache, platform: FakePlatform(operatingSystem: 'macos'));
|
||||||
|
|
||||||
|
expect(iosUsbArtifacts.archiveUri.toString(), isNot(contains('/unsigned/')));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('FlutterRunnerDebugSymbols downloads Flutter runner debug symbols', () async {
|
||||||
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
final Cache cache = Cache.test(
|
final Cache cache = Cache.test(
|
||||||
|
fileSystem: fileSystem,
|
||||||
processManager: FakeProcessManager.any(),
|
processManager: FakeProcessManager.any(),
|
||||||
);
|
);
|
||||||
final MockVersionedPackageResolver mockPackageResolver = MockVersionedPackageResolver();
|
final MockVersionedPackageResolver mockPackageResolver = MockVersionedPackageResolver();
|
||||||
@ -435,7 +348,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
when(mockPackageResolver.resolveUrl(any, any)).thenReturn('');
|
when(mockPackageResolver.resolveUrl(any, any)).thenReturn('');
|
||||||
|
|
||||||
await flutterRunnerDebugSymbols.updateInner(MockArtifactUpdater());
|
await flutterRunnerDebugSymbols.updateInner(MockArtifactUpdater(), fileSystem, MockOperatingSystemUtils());
|
||||||
|
|
||||||
verifyInOrder(<void>[
|
verifyInOrder(<void>[
|
||||||
mockPackageResolver.resolveUrl('fuchsia-debug-symbols-x64', any),
|
mockPackageResolver.resolveUrl('fuchsia-debug-symbols-x64', any),
|
||||||
@ -443,70 +356,64 @@ void main() {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('FontSubset in univeral artifacts', () {
|
testWithoutContext('FontSubset in universal artifacts', () {
|
||||||
final Cache cache = Cache.test();
|
final Cache cache = Cache.test();
|
||||||
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache);
|
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache, platform: FakePlatform(operatingSystem: 'linux'));
|
||||||
|
|
||||||
expect(artifacts.developmentArtifact, DevelopmentArtifact.universal);
|
expect(artifacts.developmentArtifact, DevelopmentArtifact.universal);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('FontSubset artifacts on linux', () {
|
testWithoutContext('FontSubset artifacts on linux', () {
|
||||||
final Cache cache = Cache.test();
|
final Cache cache = Cache.test();
|
||||||
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache);
|
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache, platform: FakePlatform(operatingSystem: 'linux'));
|
||||||
cache.includeAllPlatforms = false;
|
cache.includeAllPlatforms = false;
|
||||||
|
|
||||||
expect(artifacts.getBinaryDirs(), <List<String>>[<String>['linux-x64', 'linux-x64/font-subset.zip']]);
|
expect(artifacts.getBinaryDirs(), <List<String>>[<String>['linux-x64', 'linux-x64/font-subset.zip']]);
|
||||||
}, overrides: <Type, Generator> {
|
|
||||||
Platform: () => FakePlatform(operatingSystem: 'linux'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('FontSubset artifacts on windows', () {
|
testWithoutContext('FontSubset artifacts on windows', () {
|
||||||
final Cache cache = Cache.test();
|
final Cache cache = Cache.test();
|
||||||
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache);
|
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache, platform: FakePlatform(operatingSystem: 'windows'));
|
||||||
cache.includeAllPlatforms = false;
|
cache.includeAllPlatforms = false;
|
||||||
|
|
||||||
expect(artifacts.getBinaryDirs(), <List<String>>[<String>['windows-x64', 'windows-x64/font-subset.zip']]);
|
expect(artifacts.getBinaryDirs(), <List<String>>[<String>['windows-x64', 'windows-x64/font-subset.zip']]);
|
||||||
}, overrides: <Type, Generator> {
|
|
||||||
Platform: () => FakePlatform(operatingSystem: 'windows'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('FontSubset artifacts on macos', () {
|
testWithoutContext('FontSubset artifacts on macos', () {
|
||||||
final Cache cache = Cache.test();
|
final Cache cache = Cache.test();
|
||||||
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache);
|
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache, platform: FakePlatform(operatingSystem: 'macos'));
|
||||||
cache.includeAllPlatforms = false;
|
cache.includeAllPlatforms = false;
|
||||||
|
|
||||||
expect(artifacts.getBinaryDirs(), <List<String>>[<String>['darwin-x64', 'darwin-x64/font-subset.zip']]);
|
expect(artifacts.getBinaryDirs(), <List<String>>[<String>['darwin-x64', 'darwin-x64/font-subset.zip']]);
|
||||||
}, overrides: <Type, Generator> {
|
|
||||||
Platform: () => FakePlatform(operatingSystem: 'macos'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('FontSubset artifacts on fuchsia', () {
|
testWithoutContext('FontSubset artifacts on fuchsia', () {
|
||||||
final Cache cache = Cache.test();
|
final Cache cache = Cache.test();
|
||||||
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache);
|
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache, platform: FakePlatform(operatingSystem: 'fuchsia'));
|
||||||
cache.includeAllPlatforms = false;
|
cache.includeAllPlatforms = false;
|
||||||
expect(artifacts.getBinaryDirs, throwsToolExit(message: 'Unsupported operating system: ${globals.platform.operatingSystem}'));
|
|
||||||
}, overrides: <Type, Generator> {
|
expect(artifacts.getBinaryDirs, throwsToolExit(message: 'Unsupported operating system: fuchsia'));
|
||||||
Platform: () => FakePlatform(operatingSystem: 'fuchsia'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('FontSubset artifacts for all platforms', () {
|
testWithoutContext('FontSubset artifacts for all platforms', () {
|
||||||
final Cache cache = Cache.test();
|
final Cache cache = Cache.test();
|
||||||
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache);
|
final FontSubsetArtifacts artifacts = FontSubsetArtifacts(cache, platform: FakePlatform(operatingSystem: 'fuchsia'));
|
||||||
cache.includeAllPlatforms = true;
|
cache.includeAllPlatforms = true;
|
||||||
|
|
||||||
expect(artifacts.getBinaryDirs(), <List<String>>[
|
expect(artifacts.getBinaryDirs(), <List<String>>[
|
||||||
<String>['darwin-x64', 'darwin-x64/font-subset.zip'],
|
<String>['darwin-x64', 'darwin-x64/font-subset.zip'],
|
||||||
<String>['linux-x64', 'linux-x64/font-subset.zip'],
|
<String>['linux-x64', 'linux-x64/font-subset.zip'],
|
||||||
<String>['windows-x64', 'windows-x64/font-subset.zip'],
|
<String>['windows-x64', 'windows-x64/font-subset.zip'],
|
||||||
]);
|
]);
|
||||||
}, overrides: <Type, Generator> {
|
|
||||||
Platform: () => FakePlatform(operatingSystem: 'fuchsia'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('macOS desktop artifacts ignore filtering when requested', () {
|
testWithoutContext('macOS desktop artifacts ignore filtering when requested', () {
|
||||||
final Cache cache = Cache.test();
|
final Cache cache = Cache.test();
|
||||||
final MacOSEngineArtifacts artifacts = MacOSEngineArtifacts(cache);
|
final MacOSEngineArtifacts artifacts = MacOSEngineArtifacts(cache, platform: FakePlatform(operatingSystem: 'linux'));
|
||||||
cache.includeAllPlatforms = false;
|
cache.includeAllPlatforms = false;
|
||||||
cache.platformOverrideArtifacts = <String>{'macos'};
|
cache.platformOverrideArtifacts = <String>{'macos'};
|
||||||
|
|
||||||
expect(artifacts.getBinaryDirs(), isNotEmpty);
|
expect(artifacts.getBinaryDirs(), isNotEmpty);
|
||||||
}, overrides: <Type, Generator> {
|
|
||||||
Platform: () => FakePlatform(operatingSystem: 'linux'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('Windows desktop artifacts ignore filtering when requested', () {
|
testWithoutContext('Windows desktop artifacts ignore filtering when requested', () {
|
||||||
@ -652,7 +559,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
webStuff.childFile('bar').createSync(recursive: true);
|
webStuff.childFile('bar').createSync(recursive: true);
|
||||||
|
|
||||||
webSdk.updateInner(artifactUpdater);
|
webSdk.updateInner(artifactUpdater, fileSystem, MockOperatingSystemUtils());
|
||||||
|
|
||||||
expect(webStuff.childFile('foo'), exists);
|
expect(webStuff.childFile('foo'), exists);
|
||||||
expect(webStuff.childFile('bar'), isNot(exists));
|
expect(webStuff.childFile('bar'), isNot(exists));
|
||||||
@ -690,12 +597,11 @@ void main() {
|
|||||||
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
|
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
|
||||||
final PubDependencies pubDependencies = PubDependencies(
|
final PubDependencies pubDependencies = PubDependencies(
|
||||||
flutterRoot: () => '',
|
flutterRoot: () => '',
|
||||||
fileSystem: fileSystem,
|
|
||||||
logger: logger,
|
logger: logger,
|
||||||
pub: () => MockPub(),
|
pub: () => MockPub(),
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(await pubDependencies.isUpToDate(), false); // no package config
|
expect(await pubDependencies.isUpToDate(fileSystem), false); // no package config
|
||||||
|
|
||||||
fileSystem.file('packages/flutter_tools/.packages')
|
fileSystem.file('packages/flutter_tools/.packages')
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
@ -719,12 +625,12 @@ void main() {
|
|||||||
}
|
}
|
||||||
''');
|
''');
|
||||||
|
|
||||||
expect(await pubDependencies.isUpToDate(), false); // dependencies are missing.
|
expect(await pubDependencies.isUpToDate(fileSystem), false); // dependencies are missing.
|
||||||
|
|
||||||
fileSystem.file('.pub-cache/hosted/pub.dartlang.org/example-7.0.0/lib/foo.dart')
|
fileSystem.file('.pub-cache/hosted/pub.dartlang.org/example-7.0.0/lib/foo.dart')
|
||||||
.createSync(recursive: true);
|
.createSync(recursive: true);
|
||||||
|
|
||||||
expect(await pubDependencies.isUpToDate(), true);
|
expect(await pubDependencies.isUpToDate(fileSystem), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('PubDependencies updates via pub get', () async {
|
testWithoutContext('PubDependencies updates via pub get', () async {
|
||||||
@ -733,18 +639,65 @@ void main() {
|
|||||||
final MockPub pub = MockPub();
|
final MockPub pub = MockPub();
|
||||||
final PubDependencies pubDependencies = PubDependencies(
|
final PubDependencies pubDependencies = PubDependencies(
|
||||||
flutterRoot: () => '',
|
flutterRoot: () => '',
|
||||||
fileSystem: fileSystem,
|
|
||||||
logger: logger,
|
logger: logger,
|
||||||
pub: () => pub,
|
pub: () => pub,
|
||||||
);
|
);
|
||||||
|
|
||||||
await pubDependencies.update(MockArtifactUpdater());
|
await pubDependencies.update(MockArtifactUpdater(), logger, fileSystem, MockOperatingSystemUtils());
|
||||||
|
|
||||||
verify(pub.get(
|
verify(pub.get(
|
||||||
context: PubContext.pubGet,
|
context: PubContext.pubGet,
|
||||||
directory: 'packages/flutter_tools',
|
directory: 'packages/flutter_tools',
|
||||||
)).called(1);
|
)).called(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('AndroidMavenArtifacts', () {
|
||||||
|
MemoryFileSystem memoryFileSystem;
|
||||||
|
MockProcessManager processManager;
|
||||||
|
Cache cache;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
memoryFileSystem = MemoryFileSystem.test();
|
||||||
|
processManager = MockProcessManager();
|
||||||
|
cache = Cache.test(
|
||||||
|
fileSystem: memoryFileSystem,
|
||||||
|
processManager: FakeProcessManager.any(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('development artifact', () async {
|
||||||
|
final AndroidMavenArtifacts mavenArtifacts = AndroidMavenArtifacts(cache, platform: FakePlatform(operatingSystem: 'linux'));
|
||||||
|
expect(mavenArtifacts.developmentArtifact, DevelopmentArtifact.androidMaven);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('update', () async {
|
||||||
|
final AndroidMavenArtifacts mavenArtifacts = AndroidMavenArtifacts(cache, platform: FakePlatform(operatingSystem: 'linux'));
|
||||||
|
expect(await mavenArtifacts.isUpToDate(memoryFileSystem), isFalse);
|
||||||
|
|
||||||
|
final Directory gradleWrapperDir = cache.getArtifactDirectory('gradle_wrapper')..createSync(recursive: true);
|
||||||
|
gradleWrapperDir.childFile('gradlew').writeAsStringSync('irrelevant');
|
||||||
|
gradleWrapperDir.childFile('gradlew.bat').writeAsStringSync('irrelevant');
|
||||||
|
|
||||||
|
when(processManager.run(any, environment: captureAnyNamed('environment')))
|
||||||
|
.thenAnswer((Invocation invocation) {
|
||||||
|
final List<String> args = invocation.positionalArguments[0] as List<String>;
|
||||||
|
expect(args.length, 6);
|
||||||
|
expect(args[1], '-b');
|
||||||
|
expect(args[2].endsWith('resolve_dependencies.gradle'), isTrue);
|
||||||
|
expect(args[5], 'resolveDependencies');
|
||||||
|
expect(invocation.namedArguments[#environment], gradleEnvironment);
|
||||||
|
return Future<ProcessResult>.value(ProcessResult(0, 0, '', ''));
|
||||||
|
});
|
||||||
|
|
||||||
|
await mavenArtifacts.update(MockArtifactUpdater(), BufferLogger.test(), memoryFileSystem, MockOperatingSystemUtils());
|
||||||
|
|
||||||
|
expect(await mavenArtifacts.isUpToDate(memoryFileSystem), isFalse);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
Cache: () => cache,
|
||||||
|
FileSystem: () => memoryFileSystem,
|
||||||
|
ProcessManager: () => processManager,
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeCachedArtifact extends EngineCachedArtifact {
|
class FakeCachedArtifact extends EngineCachedArtifact {
|
||||||
@ -779,9 +732,7 @@ class FakeSimpleArtifact extends CachedArtifact {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) async {
|
Future<void> updateInner(ArtifactUpdater artifactUpdater, FileSystem fileSystem, OperatingSystemUtils operatingSystemUtils) async { }
|
||||||
// nop.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeDownloadedArtifact extends CachedArtifact {
|
class FakeDownloadedArtifact extends CachedArtifact {
|
||||||
@ -794,7 +745,7 @@ class FakeDownloadedArtifact extends CachedArtifact {
|
|||||||
final File downloadedFile;
|
final File downloadedFile;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateInner(ArtifactUpdater artifactUpdater) async {}
|
Future<void> updateInner(ArtifactUpdater artifactUpdater, FileSystem fileSystem, OperatingSystemUtils operatingSystemUtils) async { }
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockArtifactUpdater extends Mock implements ArtifactUpdater {}
|
class MockArtifactUpdater extends Mock implements ArtifactUpdater {}
|
||||||
|
@ -771,7 +771,12 @@ void _testInMemory(String description, Future<void> testMethod()) {
|
|||||||
testFileSystem.file('.packages').writeAsStringSync('\n');
|
testFileSystem.file('.packages').writeAsStringSync('\n');
|
||||||
// Transfer needed parts of the Flutter installation folder
|
// Transfer needed parts of the Flutter installation folder
|
||||||
// to the in-memory file system used during testing.
|
// to the in-memory file system used during testing.
|
||||||
transfer(Cache().getArtifactDirectory('gradle_wrapper'), testFileSystem);
|
transfer(Cache(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
osUtils: globals.os,
|
||||||
|
platform: globals.platform,
|
||||||
|
).getArtifactDirectory('gradle_wrapper'), testFileSystem);
|
||||||
transfer(globals.fs.directory(Cache.flutterRoot)
|
transfer(globals.fs.directory(Cache.flutterRoot)
|
||||||
.childDirectory('packages')
|
.childDirectory('packages')
|
||||||
.childDirectory('flutter_tools')
|
.childDirectory('flutter_tools')
|
||||||
@ -801,7 +806,12 @@ void _testInMemory(String description, Future<void> testMethod()) {
|
|||||||
overrides: <Type, Generator>{
|
overrides: <Type, Generator>{
|
||||||
FileSystem: () => testFileSystem,
|
FileSystem: () => testFileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Cache: () => Cache(),
|
Cache: () => Cache(
|
||||||
|
logger: globals.logger,
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
osUtils: globals.os,
|
||||||
|
platform: globals.platform,
|
||||||
|
),
|
||||||
FlutterProjectFactory: () => flutterProjectFactory,
|
FlutterProjectFactory: () => flutterProjectFactory,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -57,7 +57,7 @@ void main() {
|
|||||||
testUsingContext('honors shouldUpdateCache false', () async {
|
testUsingContext('honors shouldUpdateCache false', () async {
|
||||||
final DummyFlutterCommand flutterCommand = DummyFlutterCommand(shouldUpdateCache: false);
|
final DummyFlutterCommand flutterCommand = DummyFlutterCommand(shouldUpdateCache: false);
|
||||||
await flutterCommand.run();
|
await flutterCommand.run();
|
||||||
verifyZeroInteractions(cache);
|
verifyNever(cache.updateAll(any));
|
||||||
expect(flutterCommand.deprecated, isFalse);
|
expect(flutterCommand.deprecated, isFalse);
|
||||||
expect(flutterCommand.hidden, isFalse);
|
expect(flutterCommand.hidden, isFalse);
|
||||||
},
|
},
|
||||||
@ -352,7 +352,7 @@ void main() {
|
|||||||
final Completer<void> checkLockCompleter = Completer<void>();
|
final Completer<void> checkLockCompleter = Completer<void>();
|
||||||
final DummyFlutterCommand flutterCommand =
|
final DummyFlutterCommand flutterCommand =
|
||||||
DummyFlutterCommand(commandFunction: () async {
|
DummyFlutterCommand(commandFunction: () async {
|
||||||
await Cache.lock();
|
await globals.cache.lock();
|
||||||
checkLockCompleter.complete();
|
checkLockCompleter.complete();
|
||||||
final Completer<void> c = Completer<void>();
|
final Completer<void> c = Completer<void>();
|
||||||
await c.future;
|
await c.future;
|
||||||
@ -362,13 +362,13 @@ void main() {
|
|||||||
unawaited(flutterCommand.run());
|
unawaited(flutterCommand.run());
|
||||||
await checkLockCompleter.future;
|
await checkLockCompleter.future;
|
||||||
|
|
||||||
Cache.checkLockAcquired();
|
globals.cache.checkLockAcquired();
|
||||||
|
|
||||||
signalController.add(mockSignal);
|
signalController.add(mockSignal);
|
||||||
await completer.future;
|
await completer.future;
|
||||||
|
|
||||||
await Cache.lock();
|
await globals.cache.lock();
|
||||||
Cache.releaseLock();
|
globals.cache.releaseLock();
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
ProcessInfo: () => mockProcessInfo,
|
ProcessInfo: () => mockProcessInfo,
|
||||||
Signals: () => FakeSignals(
|
Signals: () => FakeSignals(
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter_tools/src/base/file_system.dart';
|
||||||
|
import 'package:flutter_tools/src/base/logger.dart';
|
||||||
|
import 'package:flutter_tools/src/base/os.dart';
|
||||||
import 'package:flutter_tools/src/cache.dart';
|
import 'package:flutter_tools/src/cache.dart';
|
||||||
import 'package:flutter_tools/src/device.dart';
|
import 'package:flutter_tools/src/device.dart';
|
||||||
|
|
||||||
@ -51,12 +54,12 @@ class FakeDyldEnvironmentArtifact extends ArtifactSet {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> isUpToDate() => Future<bool>.value(true);
|
Future<bool> isUpToDate(FileSystem fileSystem) => Future<bool>.value(true);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get name => 'fake';
|
String get name => 'fake';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> update(ArtifactUpdater artifactUpdater) async {
|
Future<void> update(ArtifactUpdater artifactUpdater, Logger logger, FileSystem fileSystem, OperatingSystemUtils operatingSystemUtils) async {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -897,5 +897,14 @@ class FakeCache implements Cache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void clearStampFiles() {}
|
void clearStampFiles() { }
|
||||||
|
|
||||||
|
@override
|
||||||
|
void checkLockAcquired() { }
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> lock() async { }
|
||||||
|
|
||||||
|
@override
|
||||||
|
void releaseLock() { }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user