Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * The application-specific cache of installed packages. | |
| 7 * | |
| 8 * This cache contains symlinks to all packages used by an app. These links | |
| 9 * point either to the [SystemCache] or to some other location on the local | |
| 10 * filesystem. | |
| 11 * | |
| 12 * This corresponds to the application's packages directory. | |
|
Bob Nystrom
2012/05/03 00:15:49
Put "packages" in quotes for clarity?
nweiz
2012/05/04 01:03:43
Done.
| |
| 13 */ | |
| 14 class AppCache { | |
| 15 /** | |
| 16 * The root directory of the application containing this cache. | |
|
Bob Nystrom
2012/05/03 00:15:49
Instead of root directory, can this just be the pa
nweiz
2012/05/04 01:03:43
Done.
| |
| 17 */ | |
| 18 final String appDir; | |
| 19 | |
| 20 /** | |
| 21 * The system-wide cache which caches packages that need to be fetched over | |
| 22 * the network. | |
| 23 */ | |
| 24 final SystemCache systemCache; | |
| 25 | |
| 26 /** | |
| 27 * Packages which have already been loaded into memory. | |
| 28 */ | |
| 29 final Map<PackageId, Package> _loadedPackages; | |
| 30 | |
| 31 /** | |
| 32 * Packages which are currently being asynchronously installed to the cache. | |
| 33 */ | |
| 34 final Map<PackageId, Future<Package>> _pendingInstalls; | |
| 35 | |
| 36 /** | |
| 37 * Creates a new package cache for the given application directory. It's | |
| 38 * backed by the packages subdirectory of [appDir]. | |
| 39 */ | |
| 40 AppCache(this.appDir, this.systemCache) | |
| 41 : _loadedPackages = new Map<PackageId, Package>(), | |
| 42 _pendingInstalls = new Map<PackageId, Future<Package>>(); | |
| 43 | |
| 44 /** | |
| 45 * Returns the directory containing the packages. | |
| 46 */ | |
| 47 // TODO(rnystrom): Make this path configurable. | |
|
Bob Nystrom
2012/05/03 00:15:49
TODO(nweiz)
I believe the goog convention is to n
nweiz
2012/05/04 01:03:43
This was a pre-existing comment on code I moved fr
| |
| 48 String get packagesDir() => join(this.appDir, 'packages'); | |
| 49 | |
| 50 /** | |
| 51 * Ensures that the package identified by [id] is installed to the cache, | |
| 52 * loads it, and returns it. | |
| 53 * | |
| 54 * If this completes successfully, the package is guaranteed to be importable | |
| 55 * using the `package:` scheme. | |
| 56 * | |
| 57 * This will automatically install the package to the system-wide cache as | |
| 58 * well if it requires network access to retrieve (specifically, if | |
| 59 * `id.source.shouldCache` is true). | |
| 60 * | |
| 61 * See also [installTransitively]. | |
| 62 */ | |
| 63 Future<Package> install(PackageId id) { | |
| 64 var package = _loadedPackages[id]; | |
| 65 if (package != null) return package; | |
|
Bob Nystrom
2012/05/03 00:15:49
new Future.immediate(package);
nweiz
2012/05/04 01:03:43
Done.
| |
| 66 | |
| 67 var pending = _pendingInstalls[id]; | |
| 68 if (pending != null) return pending; | |
| 69 | |
| 70 var packageDir = join(packagesDir, id.name); | |
| 71 var future = ensureNestedDir(dirname(packageDir)).chain((_) { | |
| 72 return exists(packageDir); | |
| 73 }).chain((exists) { | |
| 74 // If the package already exists in the cache, no need to re-install. | |
| 75 if (exists) return new Future.immediate(null); | |
| 76 | |
| 77 if (id.source.shouldCache) { | |
| 78 return systemCache.install(id). | |
| 79 chain((pkg) => createSymlink(pkg.dir, packageDir)); | |
|
Bob Nystrom
2012/05/03 00:15:49
Style nit, consider moving chain( to the previous
nweiz
2012/05/04 01:03:43
Done.
| |
| 80 } else { | |
| 81 return id.source.install(id, packageDir).transform((found) { | |
| 82 if (found) return null; | |
| 83 throw 'Package ${id.name} not found in source "${id.source.name}".'; | |
|
Bob Nystrom
2012/05/03 00:15:49
We should eventually have a more robust error-hand
nweiz
2012/05/04 01:03:43
Done.
| |
| 84 }); | |
| 85 } | |
| 86 }).chain((_) => Package.load(packageDir)); | |
| 87 | |
| 88 future.then((pkg) => _loadedPackages[id] = pkg); | |
| 89 always(future, () => _pendingInstalls.remove(id)); | |
| 90 _pendingInstalls[id] = future; | |
| 91 | |
| 92 return future; | |
| 93 } | |
| 94 | |
| 95 /** | |
| 96 * Installs the package identified by [id] and all its transitive | |
| 97 * dependencies. | |
| 98 */ | |
| 99 Future<Package> installTransitively(PackageId id) { | |
| 100 var seen = new Set<PackageId>(); | |
| 101 Future<Package> helper(id) { | |
| 102 if (seen.contains(id)) return new Future.immediate(null); | |
| 103 seen.add(id); | |
| 104 | |
| 105 return install(id).chain((package) { | |
| 106 return Futures.wait(package.dependencies.map(helper)). | |
| 107 transform((_) => package); | |
| 108 }); | |
| 109 } | |
| 110 | |
| 111 return helper(id); | |
| 112 } | |
| 113 } | |
| OLD | NEW |