Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: utils/pub/entrypoint.dart

Issue 10399076: Get codebase ready for actually supporting versioning. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Validate descriptions and move stuff into Entrypoint. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * The "packages" directory for an application or library. 6 * Pub operates over a directed graph of dependencies that starts at a root
7 * "entrypoint" package. This is typically the package where the current
nweiz 2012/05/18 21:16:01 I'd make it more explicit that an entrypoint could
Bob Nystrom 2012/05/18 22:13:04 Done.
8 * working directory is located. An entrypoint knows the [root] package it is
9 * associated with and is responsible for building the "packages" directory
nweiz 2012/05/18 21:16:01 s/building/managing/
Bob Nystrom 2012/05/18 22:13:04 Done.
10 * for it.
7 * 11 *
8 * This directory contains symlinks to all packages used by an app. These links 12 * That directory 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 13 * point either to the [SystemCache] or to some other location on the local
10 * filesystem. 14 * filesystem.
11 */ 15 */
12 class PackagesDir { 16 class Entrypoint {
13 /** 17 /**
14 * The package containing this directory. 18 * The root package this entrypoint is associated with.
15 */ 19 */
16 final Package owner; 20 final Package root;
17 21
18 /** 22 /**
19 * The system-wide cache which caches packages that need to be fetched over 23 * The system-wide cache which caches packages that need to be fetched over
20 * the network. 24 * the network.
21 */ 25 */
22 final SystemCache cache; 26 final SystemCache cache;
23 27
24 /** 28 /**
25 * Packages which have already been loaded into memory. 29 * Packages which have already been loaded into memory.
26 */ 30 */
27 final Map<PackageId, Package> _loadedPackages; 31 final Map<PackageId, Package> _loadedPackages;
28 32
29 /** 33 /**
30 * Packages which are currently being asynchronously installed to the 34 * Packages which are currently being asynchronously installed to the
31 * directory. 35 * directory.
32 */ 36 */
33 final Map<PackageId, Future<Package>> _pendingInstalls; 37 final Map<PackageId, Future<Package>> _pendingInstalls;
34 38
35 PackagesDir(this.owner, this.cache) 39 Entrypoint(this.root, this.cache)
36 : _loadedPackages = new Map<PackageId, Package>(), 40 : _loadedPackages = new Map<PackageId, Package>(),
37 _pendingInstalls = new Map<PackageId, Future<Package>>(); 41 _pendingInstalls = new Map<PackageId, Future<Package>>();
38 42
39 /** 43 /**
40 * Returns the path to the "packages" directory. 44 * The path to this "packages" directory.
41 */ 45 */
42 // TODO(rnystrom): Make this path configurable. 46 String get path() => join(root.dir, 'packages');
nweiz 2012/05/18 21:16:01 This TODO should probably come back now, right?
Bob Nystrom 2012/05/18 22:13:04 Done.
43 String get path() => join(owner.dir, 'packages');
44 47
45 /** 48 /**
46 * Ensures that the package identified by [id] is installed to the directory, 49 * Ensures that the package identified by [id] is installed to the directory,
47 * loads it, and returns it. 50 * loads it, and returns it.
48 * 51 *
49 * If this completes successfully, the package is guaranteed to be importable 52 * If this completes successfully, the package is guaranteed to be importable
50 * using the `package:` scheme. 53 * using the `package:` scheme.
51 * 54 *
52 * This will automatically install the package to the system-wide cache as 55 * This will automatically install the package to the system-wide cache as
53 * well if it requires network access to retrieve (specifically, if 56 * well if it requires network access to retrieve (specifically, if
(...skipping 15 matching lines...) Expand all
69 // If the package already exists in the directory, no need to re-install. 72 // If the package already exists in the directory, no need to re-install.
70 if (exists) return new Future.immediate(null); 73 if (exists) return new Future.immediate(null);
71 74
72 if (id.source.shouldCache) { 75 if (id.source.shouldCache) {
73 return cache.install(id).chain( 76 return cache.install(id).chain(
74 (pkg) => createSymlink(pkg.dir, packageDir)); 77 (pkg) => createSymlink(pkg.dir, packageDir));
75 } else { 78 } else {
76 return id.source.install(id, packageDir).transform((found) { 79 return id.source.install(id, packageDir).transform((found) {
77 if (found) return null; 80 if (found) return null;
78 // TODO(nweiz): More robust error-handling. 81 // TODO(nweiz): More robust error-handling.
79 throw 'Package ${id.fullName} not found in source ' 82 throw 'Package ${id.name} not found in source "${id.source.name}".';
80 '"${id.source.name}".';
81 }); 83 });
82 } 84 }
83 }).chain((_) => Package.load(packageDir, cache.sources)); 85 }).chain((_) => Package.load(packageDir, cache.sources));
84 86
85 future.then((pkg) => _loadedPackages[id] = pkg); 87 future.then((pkg) => _loadedPackages[id] = pkg);
86 always(future, () => _pendingInstalls.remove(id)); 88 always(future, () => _pendingInstalls.remove(id));
87 _pendingInstalls[id] = future; 89 _pendingInstalls[id] = future;
88 90
89 return future; 91 return future;
90 } 92 }
91 93
92 /** 94 /**
93 * Installs the package identified by [id] and all its transitive 95 * Installs all of the packages referred to by [packages] and their transitive
94 * dependencies. 96 * dependencies. References are resolved using [entrypoint].
95 */ 97 */
96 Future<Package> installTransitively(PackageId id) { 98 Future installTransitively(Package entrypoint,
nweiz 2012/05/18 21:16:01 Taking "Package entrypoint" here seems weird for a
Bob Nystrom 2012/05/18 22:13:04 Yeah, that's just stale code from before this refa
99 List<PackageRef> packages) {
97 var seen = new Set<PackageId>(); 100 var seen = new Set<PackageId>();
98 Future<Package> helper(id) {
99 if (seen.contains(id)) return new Future.immediate(null);
100 seen.add(id);
101 101
102 return install(id).chain((package) { 102 Future helper(List<PackageRef> packages) {
103 return Futures.wait(package.dependencies.map(helper)). 103 return Futures.wait(packages.map((ref) {
104 transform((_) => package); 104 return entrypoint.resolve(ref).chain((id) {
105 }); 105 if (seen.contains(id)) return new Future.immediate(null);
106 seen.add(id);
107
108 return install(id).chain((package) {
109 return helper(package.dependencies);
110 });
111 });
112 }));
106 } 113 }
107 114
108 return helper(id); 115 return helper(packages);
109 } 116 }
110 117
111 /** 118 /**
112 * Installs all dependencies of [owner] to the "packages" directory. Returns a 119 * Installs all dependencies of the [root] package to its "packages"
113 * [Future] that completes when all dependencies are installed. 120 * directory. Returns a [Future] that completes when all dependencies are
121 * installed.
114 */ 122 */
115 Future installDependencies() { 123 Future installDependencies() {
116 return Futures.wait(owner.dependencies.map(installTransitively)). 124 return installTransitively(root, root.dependencies);
117 transform((_) => null);
118 } 125 }
119 } 126 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698