forked from firka/flutter
Always use user-level pub cache (#121802)
Use the pub cache resolved by pub itself. To add packages to the flutter.zip download they are packaged as tar.gz and added to the pub-cache on first run by using `pub cache preload`.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -51,7 +51,7 @@ analysis_benchmark.json
|
||||
.flutter-plugins-dependencies
|
||||
**/generated_plugin_registrant.dart
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub-preload-cache/
|
||||
.pub/
|
||||
build/
|
||||
flutter_*.png
|
||||
|
||||
@@ -22,8 +22,6 @@ SET script_path=%flutter_tools_dir%\bin\flutter_tools.dart
|
||||
SET dart_sdk_path=%cache_dir%\dart-sdk
|
||||
SET engine_stamp=%cache_dir%\engine-dart-sdk.stamp
|
||||
SET engine_version_path=%FLUTTER_ROOT%\bin\internal\engine.version
|
||||
SET pub_cache_path=%FLUTTER_ROOT%\.pub-cache
|
||||
|
||||
SET dart=%dart_sdk_path%\bin\dart.exe
|
||||
|
||||
REM Ensure that bin/cache exists.
|
||||
|
||||
@@ -149,9 +149,6 @@ function upgrade_flutter () (
|
||||
export PUB_SUMMARY_ONLY=1
|
||||
fi
|
||||
export PUB_ENVIRONMENT="$PUB_ENVIRONMENT:flutter_install"
|
||||
if [[ -d "$FLUTTER_ROOT/.pub-cache" ]]; then
|
||||
export PUB_CACHE="${PUB_CACHE:-"$FLUTTER_ROOT/.pub-cache"}"
|
||||
fi
|
||||
pub_upgrade_with_retry
|
||||
|
||||
# Move the old snapshot - we can't just overwrite it as the VM might currently have it
|
||||
|
||||
@@ -8,11 +8,13 @@ import 'dart:io' hide Platform;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:convert/convert.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:crypto/src/digest_sink.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:platform/platform.dart' show LocalPlatform, Platform;
|
||||
import 'package:pool/pool.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
const String gobMirror =
|
||||
@@ -189,7 +191,7 @@ class ArchiveCreator {
|
||||
subprocessOutput: subprocessOutput,
|
||||
platform: platform,
|
||||
)..environment['PUB_CACHE'] = path.join(
|
||||
flutterRoot.absolute.path, '.pub-cache',
|
||||
tempDir.path, '.pub-cache',
|
||||
);
|
||||
final String flutterExecutable = path.join(
|
||||
flutterRoot.absolute.path,
|
||||
@@ -426,6 +428,104 @@ class ArchiveCreator {
|
||||
await _unzipArchive(gitFile, workingDirectory: minGitPath);
|
||||
}
|
||||
|
||||
/// Downloads an archive of every package that is present in the temporary
|
||||
/// pub-cache from pub.dev. Stores the archives in
|
||||
/// $flutterRoot/.pub-preload-cache.
|
||||
///
|
||||
/// These archives will be installed in the user-level cache on first
|
||||
/// following flutter command that accesses the cache.
|
||||
///
|
||||
/// Precondition: all packages currently in the PUB_CACHE of [_processRunner]
|
||||
/// are installed from pub.dev.
|
||||
Future<void> _downloadPubPackageArchives() async {
|
||||
final Pool pool = Pool(10); // Number of simultaneous downloads.
|
||||
final http.Client client = http.Client();
|
||||
final Directory preloadCache = Directory(path.join(flutterRoot.path, '.pub-preload-cache'));
|
||||
preloadCache.createSync(recursive: true);
|
||||
/// Fetch a single package.
|
||||
Future<void> fetchPackageArchive(String name, String version) async {
|
||||
await pool.withResource(() async {
|
||||
stderr.write('Fetching package archive for $name-$version.\n');
|
||||
int retries = 7;
|
||||
while (true) {
|
||||
retries-=1;
|
||||
try {
|
||||
final Uri packageListingUrl =
|
||||
Uri.parse('https://pub.dev/api/packages/$name');
|
||||
// Fetch the package listing to obtain the package download url.
|
||||
final http.Response packageListingResponse =
|
||||
await client.get(packageListingUrl);
|
||||
if (packageListingResponse.statusCode != 200) {
|
||||
throw Exception('Downloading $packageListingUrl failed. Status code ${packageListingResponse.statusCode}.');
|
||||
}
|
||||
final dynamic decodedPackageListing = json.decode(packageListingResponse.body);
|
||||
if (decodedPackageListing is! Map) {
|
||||
throw const FormatException('Package listing should be a map');
|
||||
}
|
||||
final dynamic versions = decodedPackageListing['versions'];
|
||||
if (versions is! List) {
|
||||
throw const FormatException('.versions should be a list');
|
||||
}
|
||||
final Map<String, dynamic> versionDescription = versions.firstWhere(
|
||||
(dynamic description) {
|
||||
if (description is! Map) {
|
||||
throw const FormatException('.versions elements should be maps');
|
||||
}
|
||||
return description['version'] == version;
|
||||
},
|
||||
orElse: () => throw FormatException('Could not find $name-$version in package listing')
|
||||
) as Map<String, dynamic>;
|
||||
final dynamic downloadUrl = versionDescription['archive_url'];
|
||||
if (downloadUrl is! String) {
|
||||
throw const FormatException('archive_url should be a string');
|
||||
}
|
||||
final dynamic archiveSha256 = versionDescription['archive_sha256'];
|
||||
if (archiveSha256 is! String) {
|
||||
throw const FormatException('archive_sha256 should be a string');
|
||||
}
|
||||
final http.Request request = http.Request('get', Uri.parse(downloadUrl));
|
||||
final http.StreamedResponse response = await client.send(request);
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Downloading ${request.url} failed. Status code ${response.statusCode}.');
|
||||
}
|
||||
final File archiveFile = File(
|
||||
path.join(preloadCache.path, '$name-$version.tar.gz'),
|
||||
);
|
||||
await response.stream.pipe(archiveFile.openWrite());
|
||||
final Stream<List<int>> archiveStream = archiveFile.openRead();
|
||||
final Digest r = await sha256.bind(archiveStream).first;
|
||||
if (hex.encode(r.bytes) != archiveSha256) {
|
||||
throw Exception('Hash mismatch of downloaded archive');
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
stderr.write('Failed downloading $name-$version. $e\n');
|
||||
if (retries > 0) {
|
||||
stderr.write('Retrying download of $name-$version...');
|
||||
// Retry.
|
||||
continue;
|
||||
} else {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
final Map<String, dynamic> cacheDescription =
|
||||
json.decode(await _runFlutter(<String>['pub', 'cache', 'list'])) as Map<String, dynamic>;
|
||||
final Map<String, dynamic> packages = cacheDescription['packages'] as Map<String, dynamic>;
|
||||
final List<Future<void>> downloads = <Future<void>>[];
|
||||
for (final MapEntry<String, dynamic> package in packages.entries) {
|
||||
final String name = package.key;
|
||||
final Map<String, dynamic> versions = package.value as Map<String, dynamic>;
|
||||
for (final String version in versions.keys) {
|
||||
downloads.add(fetchPackageArchive(name, version));
|
||||
}
|
||||
}
|
||||
await Future.wait(downloads);
|
||||
client.close();
|
||||
}
|
||||
|
||||
/// Prepare the archive repo so that it has all of the caches warmed up and
|
||||
/// is configured for the user to begin working.
|
||||
Future<void> _populateCaches() async {
|
||||
@@ -446,7 +546,7 @@ class ArchiveCreator {
|
||||
workingDirectory: tempDir,
|
||||
);
|
||||
}
|
||||
|
||||
await _downloadPubPackageArchives();
|
||||
// Yes, we could just skip all .packages files when constructing
|
||||
// the archive, but some are checked in, and we don't want to skip
|
||||
// those.
|
||||
@@ -795,8 +895,8 @@ class ArchivePublisher {
|
||||
}
|
||||
}
|
||||
|
||||
/// Prepares a flutter git repo to be packaged up for distribution.
|
||||
/// It mainly serves to populate the .pub-cache with any appropriate Dart
|
||||
/// Prepares a flutter git repo to be packaged up for distribution. It mainly
|
||||
/// serves to populate the .pub-preload-cache with any appropriate Dart
|
||||
/// packages, and the flutter cache in bin/cache with the appropriate
|
||||
/// dependencies and snapshots.
|
||||
///
|
||||
|
||||
@@ -143,6 +143,7 @@ void main() {
|
||||
'$flutter create --template=app ${createBase}app': null,
|
||||
'$flutter create --template=package ${createBase}package': null,
|
||||
'$flutter create --template=plugin ${createBase}plugin': null,
|
||||
'$flutter pub cache list': <ProcessResult>[ProcessResult(0,0,'{"packages":{}}','')],
|
||||
'git clean -f -x -- **/.packages': null,
|
||||
'git clean -f -x -- **/.dart_tool/': null,
|
||||
if (platform.isMacOS) 'codesign -vvvv --check-notarization ${path.join(tempDir.path, 'flutter', 'bin', 'cache', 'dart-sdk', 'bin', 'dart')}': null,
|
||||
@@ -180,6 +181,7 @@ void main() {
|
||||
'$flutter create --template=app ${createBase}app': null,
|
||||
'$flutter create --template=package ${createBase}package': null,
|
||||
'$flutter create --template=plugin ${createBase}plugin': null,
|
||||
'$flutter pub cache list': <ProcessResult>[ProcessResult(0,0,'{"packages":{}}','')],
|
||||
'git clean -f -x -- **/.packages': null,
|
||||
'git clean -f -x -- **/.dart_tool/': null,
|
||||
if (platform.isMacOS) 'codesign -vvvv --check-notarization ${path.join(tempDir.path, 'flutter', 'bin', 'cache', 'dart-sdk', 'bin', 'dart')}': null,
|
||||
@@ -228,6 +230,7 @@ void main() {
|
||||
'$flutter create --template=app ${createBase}app': null,
|
||||
'$flutter create --template=package ${createBase}package': null,
|
||||
'$flutter create --template=plugin ${createBase}plugin': null,
|
||||
'$flutter pub cache list': <ProcessResult>[ProcessResult(0,0,'{"packages":{}}','')],
|
||||
'git clean -f -x -- **/.packages': null,
|
||||
'git clean -f -x -- **/.dart_tool/': null,
|
||||
if (platform.isMacOS) 'codesign -vvvv --check-notarization ${path.join(tempDir.path, 'flutter', 'bin', 'cache', 'dart-sdk', 'bin', 'dart')}': null,
|
||||
@@ -286,6 +289,7 @@ void main() {
|
||||
'$flutter create --template=app ${createBase}app': null,
|
||||
'$flutter create --template=package ${createBase}package': null,
|
||||
'$flutter create --template=plugin ${createBase}plugin': null,
|
||||
'$flutter pub cache list': <ProcessResult>[ProcessResult(0,0,'{"packages":{}}','')],
|
||||
'git clean -f -x -- **/.packages': null,
|
||||
'git clean -f -x -- **/.dart_tool/': null,
|
||||
if (platform.isWindows) 'attrib -h .git': null,
|
||||
@@ -336,6 +340,7 @@ void main() {
|
||||
'$flutter create --template=app ${createBase}app': null,
|
||||
'$flutter create --template=package ${createBase}package': null,
|
||||
'$flutter create --template=plugin ${createBase}plugin': null,
|
||||
'$flutter pub cache list': <ProcessResult>[ProcessResult(0,0,'{"packages":{}}','')],
|
||||
'git clean -f -x -- **/.packages': null,
|
||||
'git clean -f -x -- **/.dart_tool/': null,
|
||||
if (platform.isMacOS) 'codesign -vvvv --check-notarization $binPath': <ProcessResult>[codesignFailure],
|
||||
|
||||
@@ -34,39 +34,29 @@ const String _kPubCacheEnvironmentKey = 'PUB_CACHE';
|
||||
|
||||
typedef MessageFilter = String? Function(String message);
|
||||
|
||||
/// globalCachePath is the directory in which the content of the localCachePath will be moved in
|
||||
void joinCaches({
|
||||
required FileSystem fileSystem,
|
||||
required Directory globalCacheDirectory,
|
||||
required Directory dependencyDirectory,
|
||||
/// Load any package-files stored in [preloadCacheDir] into the pub cache if it
|
||||
/// exists.
|
||||
///
|
||||
/// Deletes the [preloadCacheDir].
|
||||
@visibleForTesting
|
||||
void preloadPubCache({
|
||||
required Directory preloadCacheDir,
|
||||
required ProcessManager processManager,
|
||||
required Logger logger,
|
||||
required List<String> pubCommand,
|
||||
}) {
|
||||
for (final FileSystemEntity entity in dependencyDirectory.listSync()) {
|
||||
final String newPath = fileSystem.path.join(globalCacheDirectory.path, entity.basename);
|
||||
if (entity is File) {
|
||||
if (!fileSystem.file(newPath).existsSync()) {
|
||||
entity.copySync(newPath);
|
||||
}
|
||||
} else if (entity is Directory) {
|
||||
if (!globalCacheDirectory.childDirectory(entity.basename).existsSync()) {
|
||||
final Directory newDirectory = globalCacheDirectory.childDirectory(entity.basename);
|
||||
newDirectory.createSync();
|
||||
joinCaches(
|
||||
fileSystem: fileSystem,
|
||||
globalCacheDirectory: newDirectory,
|
||||
dependencyDirectory: entity,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (preloadCacheDir.existsSync()) {
|
||||
final Iterable<String> cacheFiles =
|
||||
preloadCacheDir
|
||||
.listSync()
|
||||
.map((FileSystemEntity f) => f.path)
|
||||
.where((String path) => path.endsWith('.tar.gz'));
|
||||
processManager.runSync(<String>[...pubCommand, 'cache', 'preload',...cacheFiles]);
|
||||
_tryDeleteDirectory(preloadCacheDir, logger);
|
||||
}
|
||||
}
|
||||
|
||||
Directory createDependencyDirectory(Directory pubGlobalDirectory, String dependencyName) {
|
||||
final Directory newDirectory = pubGlobalDirectory.childDirectory(dependencyName);
|
||||
newDirectory.createSync();
|
||||
return newDirectory;
|
||||
}
|
||||
|
||||
bool tryDelete(Directory directory, Logger logger) {
|
||||
bool _tryDeleteDirectory(Directory directory, Logger logger) {
|
||||
try {
|
||||
if (directory.existsSync()) {
|
||||
directory.deleteSync(recursive: true);
|
||||
@@ -78,24 +68,6 @@ bool tryDelete(Directory directory, Logger logger) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// When local cache (flutter_root/.pub-cache) and global cache (HOME/.pub-cache) are present a
|
||||
/// merge needs to be done leaving only the global
|
||||
///
|
||||
/// Valid pubCache should look like this ./localCachePath/.pub-cache/hosted/pub.dartlang.org
|
||||
bool needsToJoinCache({
|
||||
required FileSystem fileSystem,
|
||||
required String localCachePath,
|
||||
required Directory? globalDirectory,
|
||||
}) {
|
||||
if (globalDirectory == null) {
|
||||
return false;
|
||||
}
|
||||
final Directory localDirectory = fileSystem.directory(localCachePath);
|
||||
|
||||
return globalDirectory.childDirectory('hosted').childDirectory('pub.dartlang.org').existsSync() &&
|
||||
localDirectory.childDirectory('hosted').childDirectory('pub.dartlang.org').existsSync();
|
||||
}
|
||||
|
||||
/// Represents Flutter-specific data that is added to the `PUB_ENVIRONMENT`
|
||||
/// environment variable and allows understanding the type of requests made to
|
||||
/// the package site on Flutter's behalf.
|
||||
@@ -402,7 +374,7 @@ class _DefaultPub implements Pub {
|
||||
}) async {
|
||||
int exitCode;
|
||||
|
||||
final List<String> pubCommand = _pubCommand(arguments);
|
||||
final List<String> pubCommand = <String>[..._pubCommand, ...arguments];
|
||||
final Map<String, String> pubEnvironment = await _createPubEnvironment(context: context, flutterRootOverride: flutterRootOverride, summaryOnly: outputMode == PubOutputMode.summaryOnly);
|
||||
|
||||
try {
|
||||
@@ -536,7 +508,7 @@ class _DefaultPub implements Pub {
|
||||
arguments.insert(0, '--trace');
|
||||
}
|
||||
final Map<String, String> pubEnvironment = await _createPubEnvironment(context: context, flutterRootOverride: flutterRootOverride);
|
||||
final List<String> pubCommand = _pubCommand(arguments);
|
||||
final List<String> pubCommand = <String>[..._pubCommand, ...arguments];
|
||||
final int code = await _processUtils.stream(
|
||||
pubCommand,
|
||||
workingDirectory: directory,
|
||||
@@ -590,7 +562,9 @@ class _DefaultPub implements Pub {
|
||||
}
|
||||
|
||||
/// The command used for running pub.
|
||||
List<String> _pubCommand(List<String> arguments) {
|
||||
late final List<String> _pubCommand = _computePubCommand();
|
||||
|
||||
List<String> _computePubCommand() {
|
||||
// TODO(zanderso): refactor to use artifacts.
|
||||
final String sdkPath = _fileSystem.path.joinAll(<String>[
|
||||
Cache.flutterRoot!,
|
||||
@@ -607,7 +581,7 @@ class _DefaultPub implements Pub {
|
||||
'permissions for the current user.'
|
||||
);
|
||||
}
|
||||
return <String>[sdkPath, '--no-analytics', 'pub', ...arguments];
|
||||
return <String>[sdkPath, '--no-analytics', 'pub'];
|
||||
}
|
||||
|
||||
// Returns the environment value that should be used when running pub.
|
||||
@@ -629,88 +603,26 @@ class _DefaultPub implements Pub {
|
||||
return values.join(':');
|
||||
}
|
||||
|
||||
/// There are 3 ways to get the pub cache location
|
||||
/// There are 2 ways to get the pub cache location
|
||||
///
|
||||
/// 1) Provide the _kPubCacheEnvironmentKey.
|
||||
/// 2) There is a local cache (in the Flutter SDK) but not a global one (in the user's home directory).
|
||||
/// 3) If both local and global are available then merge the local into global and return the global.
|
||||
/// 2) The pub default user-level pub cache.
|
||||
///
|
||||
/// If we are using 2, check if there are pre-packaged packages in
|
||||
/// $FLUTTER_ROOT/.pub-preload-cache and install them in the user-level cache.
|
||||
String? _getPubCacheIfAvailable() {
|
||||
if (_platform.environment.containsKey(_kPubCacheEnvironmentKey)) {
|
||||
return _platform.environment[_kPubCacheEnvironmentKey];
|
||||
}
|
||||
|
||||
final String localCachePath = _fileSystem.path.join(Cache.flutterRoot!, '.pub-cache');
|
||||
final Directory? globalDirectory;
|
||||
if (_platform.isWindows) {
|
||||
globalDirectory = _getWindowsGlobalDirectory;
|
||||
}
|
||||
else {
|
||||
if (_platform.environment['HOME'] == null) {
|
||||
globalDirectory = null;
|
||||
} else {
|
||||
final String homeDirectoryPath = _platform.environment['HOME']!;
|
||||
globalDirectory = _fileSystem.directory(_fileSystem.path.join(homeDirectoryPath, '.pub-cache'));
|
||||
}
|
||||
}
|
||||
|
||||
if (needsToJoinCache(
|
||||
fileSystem: _fileSystem,
|
||||
localCachePath: localCachePath,
|
||||
globalDirectory: globalDirectory,
|
||||
)) {
|
||||
final Directory localDirectoryPub = _fileSystem.directory(
|
||||
_fileSystem.path.join(localCachePath, 'hosted', 'pub.dartlang.org')
|
||||
);
|
||||
final Directory globalDirectoryPub = _fileSystem.directory(
|
||||
_fileSystem.path.join(globalDirectory!.path, 'hosted', 'pub.dartlang.org')
|
||||
);
|
||||
for (final FileSystemEntity entity in localDirectoryPub.listSync()) {
|
||||
if (entity is Directory && !globalDirectoryPub.childDirectory(entity.basename).existsSync()){
|
||||
try {
|
||||
final Directory newDirectory = createDependencyDirectory(globalDirectoryPub, entity.basename);
|
||||
joinCaches(
|
||||
fileSystem: _fileSystem,
|
||||
globalCacheDirectory: newDirectory,
|
||||
dependencyDirectory: entity,
|
||||
);
|
||||
} on FileSystemException {
|
||||
if (!tryDelete(globalDirectoryPub.childDirectory(entity.basename), _logger)) {
|
||||
_logger.printWarning('The join of pub-caches failed');
|
||||
_logger.printStatus('Running "dart pub cache repair"');
|
||||
_processManager.runSync(<String>['dart', 'pub', 'cache', 'repair']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tryDelete(_fileSystem.directory(localCachePath), _logger);
|
||||
return globalDirectory.path;
|
||||
} else if (globalDirectory != null && globalDirectory.existsSync()) {
|
||||
return globalDirectory.path;
|
||||
} else if (_fileSystem.directory(localCachePath).existsSync()) {
|
||||
return localCachePath;
|
||||
}
|
||||
final String flutterRootPath = Cache.flutterRoot!;
|
||||
final Directory flutterRoot = _fileSystem.directory(flutterRootPath);
|
||||
final Directory preloadCacheDir = flutterRoot.childDirectory('.pub-preload-cache');
|
||||
preloadPubCache(preloadCacheDir: preloadCacheDir,logger: _logger,processManager: _processManager, pubCommand: _pubCommand);
|
||||
// Use pub's default location by returning null.
|
||||
return null;
|
||||
}
|
||||
|
||||
Directory? get _getWindowsGlobalDirectory {
|
||||
// %LOCALAPPDATA% is preferred as the cache location over %APPDATA%, because the latter is synchronised between
|
||||
// devices when the user roams between them, whereas the former is not.
|
||||
// The default cache dir used to be in %APPDATA%, so to avoid breaking old installs,
|
||||
// we use the old dir in %APPDATA% if it exists. Else, we use the new default location
|
||||
// in %LOCALAPPDATA%.
|
||||
for (final String envVariable in <String>['APPDATA', 'LOCALAPPDATA']) {
|
||||
if (_platform.environment[envVariable] != null) {
|
||||
final String homePath = _platform.environment[envVariable]!;
|
||||
final Directory globalDirectory = _fileSystem.directory(_fileSystem.path.join(homePath, 'Pub', 'Cache'));
|
||||
if (globalDirectory.existsSync()) {
|
||||
return globalDirectory;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// The full environment used when running pub.
|
||||
///
|
||||
/// [context] provides extra information to package server requests to
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/dart/pub.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
|
||||
void main() {
|
||||
testWithoutContext('join two folders', () async {
|
||||
final MemoryFileSystem fileSystem = MemoryFileSystem();
|
||||
final Directory target = fileSystem.currentDirectory.childDirectory('target');
|
||||
final Directory extra = fileSystem.currentDirectory.childDirectory('extra');
|
||||
target.createSync();
|
||||
target.childFile('first.file').createSync();
|
||||
target.childDirectory('dir').createSync();
|
||||
|
||||
extra.createSync();
|
||||
extra.childFile('second.file').writeAsBytesSync(<int>[0]);
|
||||
extra.childDirectory('dir').createSync();
|
||||
extra.childDirectory('dir').childFile('third.file').writeAsBytesSync(<int>[0]);
|
||||
extra.childDirectory('dir_2').createSync();
|
||||
extra.childDirectory('dir_2').childFile('fourth.file').writeAsBytesSync(<int>[0]);
|
||||
extra.childDirectory('dir_3').createSync();
|
||||
extra.childDirectory('dir_3').childFile('fifth.file').writeAsBytesSync(<int>[0]);
|
||||
joinCaches(
|
||||
fileSystem: fileSystem,
|
||||
globalCacheDirectory: target,
|
||||
dependencyDirectory: extra,
|
||||
);
|
||||
|
||||
expect(target.childFile('second.file').existsSync(), true);
|
||||
expect(target.childDirectory('dir').childFile('third.file').existsSync(), false);
|
||||
expect(target.childDirectory('dir_2').childFile('fourth.file').existsSync(), true);
|
||||
expect(target.childDirectory('dir_3').childFile('fifth.file').existsSync(), true);
|
||||
expect(extra.childDirectory('dir').childFile('third.file').existsSync(), true);
|
||||
});
|
||||
|
||||
group('needsToJoinCache()', (){
|
||||
testWithoutContext('make join', () async {
|
||||
final MemoryFileSystem fileSystem = MemoryFileSystem();
|
||||
final Directory local = fileSystem.currentDirectory.childDirectory('local');
|
||||
final Directory global = fileSystem.currentDirectory.childDirectory('global');
|
||||
|
||||
for (final Directory directory in <Directory>[local, global]) {
|
||||
directory.createSync();
|
||||
directory.childDirectory('hosted').createSync();
|
||||
directory.childDirectory('hosted').childDirectory('pub.dartlang.org').createSync();
|
||||
}
|
||||
final bool pass = needsToJoinCache(
|
||||
fileSystem: fileSystem,
|
||||
localCachePath: local.path,
|
||||
globalDirectory: global,
|
||||
);
|
||||
expect(pass, true);
|
||||
});
|
||||
|
||||
testWithoutContext('detects when global pub-cache does not have a pub.dartlang.org dir', () async {
|
||||
final MemoryFileSystem fileSystem = MemoryFileSystem();
|
||||
final Directory local = fileSystem.currentDirectory.childDirectory('local');
|
||||
final Directory global = fileSystem.currentDirectory.childDirectory('global');
|
||||
local.createSync();
|
||||
global.createSync();
|
||||
local.childDirectory('hosted').createSync();
|
||||
local.childDirectory('hosted').childDirectory('pub.dartlang.org').createSync();
|
||||
|
||||
expect(
|
||||
needsToJoinCache(
|
||||
fileSystem: fileSystem,
|
||||
localCachePath: local.path,
|
||||
globalDirectory: global
|
||||
),
|
||||
false
|
||||
);
|
||||
});
|
||||
testWithoutContext("don't join global directory null", () async {
|
||||
final MemoryFileSystem fileSystem = MemoryFileSystem();
|
||||
final Directory local = fileSystem.currentDirectory.childDirectory('local');
|
||||
const Directory? global = null;
|
||||
local.createSync();
|
||||
local.childDirectory('hosted').createSync();
|
||||
local.childDirectory('hosted').childDirectory('pub.dartlang.org').createSync();
|
||||
|
||||
expect(
|
||||
needsToJoinCache(
|
||||
fileSystem: fileSystem,
|
||||
localCachePath: local.path,
|
||||
globalDirectory: global
|
||||
),
|
||||
false
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -757,29 +757,24 @@ exit code: 66
|
||||
expect(processManager, hasNoRemainingExpectations);
|
||||
});
|
||||
|
||||
testWithoutContext('pub cache local is merge to global', () async {
|
||||
testWithoutContext('Preloaded packages are added to the pub cache', () async {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
final Directory local = fileSystem.currentDirectory.childDirectory('.pub-cache');
|
||||
final Directory global = fileSystem.currentDirectory.childDirectory('/global');
|
||||
global.createSync();
|
||||
for (final Directory dir in <Directory>[global.childDirectory('.pub-cache'), local]) {
|
||||
dir.createSync();
|
||||
dir.childDirectory('hosted').createSync();
|
||||
dir.childDirectory('hosted').childDirectory('pub.dartlang.org').createSync();
|
||||
}
|
||||
|
||||
final Directory globalHosted = global.childDirectory('.pub-cache').childDirectory('hosted').childDirectory('pub.dartlang.org');
|
||||
globalHosted.childFile('first.file').createSync();
|
||||
globalHosted.childDirectory('dir').createSync();
|
||||
|
||||
final Directory localHosted = local.childDirectory('hosted').childDirectory('pub.dartlang.org');
|
||||
localHosted.childFile('second.file').writeAsBytesSync(<int>[0]);
|
||||
localHosted.childDirectory('dir').createSync();
|
||||
localHosted.childDirectory('dir').childFile('third.file').writeAsBytesSync(<int>[0]);
|
||||
localHosted.childDirectory('dir_2').createSync();
|
||||
localHosted.childDirectory('dir_2').childFile('fourth.file').writeAsBytesSync(<int>[0]);
|
||||
final Directory preloadCache = fileSystem.currentDirectory.childDirectory('.pub-preload-cache');
|
||||
preloadCache.childFile('a.tar.gz').createSync(recursive: true);
|
||||
preloadCache.childFile('b.tar.gz').createSync();
|
||||
|
||||
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
const FakeCommand(
|
||||
command: <String>[
|
||||
'bin/cache/dart-sdk/bin/dart',
|
||||
'--no-analytics',
|
||||
'pub',
|
||||
'cache',
|
||||
'preload',
|
||||
'.pub-preload-cache/a.tar.gz',
|
||||
'.pub-preload-cache/b.tar.gz',
|
||||
],
|
||||
),
|
||||
const FakeCommand(
|
||||
command: <String>[
|
||||
'bin/cache/dart-sdk/bin/dart',
|
||||
@@ -793,7 +788,6 @@ exit code: 66
|
||||
exitCode: 69,
|
||||
environment: <String, String>{
|
||||
'FLUTTER_ROOT': '',
|
||||
'PUB_CACHE': '/global/.pub-cache',
|
||||
'PUB_ENVIRONMENT': 'flutter_cli:flutter_tests',
|
||||
},
|
||||
),
|
||||
@@ -822,12 +816,7 @@ exit code: 66
|
||||
}
|
||||
|
||||
expect(processManager, hasNoRemainingExpectations);
|
||||
expect(local.existsSync(), false);
|
||||
expect(globalHosted.childFile('second.file').existsSync(), false);
|
||||
expect(
|
||||
globalHosted.childDirectory('dir').childFile('third.file').existsSync(), false
|
||||
); // do not copy dependencies that are already downloaded
|
||||
expect(globalHosted.childDirectory('dir_2').childFile('fourth.file').existsSync(), true);
|
||||
expect(preloadCache.existsSync(), false);
|
||||
});
|
||||
|
||||
testWithoutContext('pub cache in environment is used', () async {
|
||||
|
||||
Reference in New Issue
Block a user