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

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: Respond to review. 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
« no previous file with comments | « utils/pub/command_install.dart ('k') | utils/pub/git_source.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
8 * working directory is located. An entrypoint knows the [root] package it is
9 * associated with and is responsible for managing the "packages" directory
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.
15 *
16 * While entrypoints are typically applications, a pure library package may end
17 * up being used as an entrypoint. Also, a single package may be used as an
18 * entrypoint in one context but not in another. For example, a package that
19 * contains a reusable library may not be the entrypoint when used by an app,
20 * but may be the entrypoint when you're running its tests.
11 */ 21 */
12 class PackagesDir { 22 class Entrypoint {
13 /** 23 /**
14 * The package containing this directory. 24 * The root package this entrypoint is associated with.
15 */ 25 */
16 final Package owner; 26 final Package root;
17 27
18 /** 28 /**
19 * The system-wide cache which caches packages that need to be fetched over 29 * The system-wide cache which caches packages that need to be fetched over
20 * the network. 30 * the network.
21 */ 31 */
22 final SystemCache cache; 32 final SystemCache cache;
23 33
24 /** 34 /**
25 * Packages which have already been loaded into memory. 35 * Packages which have already been loaded into memory.
26 */ 36 */
27 final Map<PackageId, Package> _loadedPackages; 37 final Map<PackageId, Package> _loadedPackages;
28 38
29 /** 39 /**
30 * Packages which are currently being asynchronously installed to the 40 * Packages which are currently being asynchronously installed to the
31 * directory. 41 * directory.
32 */ 42 */
33 final Map<PackageId, Future<Package>> _pendingInstalls; 43 final Map<PackageId, Future<Package>> _pendingInstalls;
34 44
35 PackagesDir(this.owner, this.cache) 45 Entrypoint(this.root, this.cache)
36 : _loadedPackages = new Map<PackageId, Package>(), 46 : _loadedPackages = new Map<PackageId, Package>(),
37 _pendingInstalls = new Map<PackageId, Future<Package>>(); 47 _pendingInstalls = new Map<PackageId, Future<Package>>();
38 48
39 /** 49 /**
40 * Returns the path to the "packages" directory. 50 * The path to this "packages" directory.
41 */ 51 */
42 // TODO(rnystrom): Make this path configurable. 52 // TODO(rnystrom): Make this path configurable.
43 String get path() => join(owner.dir, 'packages'); 53 String get path() => join(root.dir, 'packages');
44 54
45 /** 55 /**
46 * Ensures that the package identified by [id] is installed to the directory, 56 * Ensures that the package identified by [id] is installed to the directory,
47 * loads it, and returns it. 57 * loads it, and returns it.
48 * 58 *
49 * If this completes successfully, the package is guaranteed to be importable 59 * If this completes successfully, the package is guaranteed to be importable
50 * using the `package:` scheme. 60 * using the `package:` scheme.
51 * 61 *
52 * This will automatically install the package to the system-wide cache as 62 * This will automatically install the package to the system-wide cache as
53 * well if it requires network access to retrieve (specifically, if 63 * 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. 79 // If the package already exists in the directory, no need to re-install.
70 if (exists) return new Future.immediate(null); 80 if (exists) return new Future.immediate(null);
71 81
72 if (id.source.shouldCache) { 82 if (id.source.shouldCache) {
73 return cache.install(id).chain( 83 return cache.install(id).chain(
74 (pkg) => createSymlink(pkg.dir, packageDir)); 84 (pkg) => createSymlink(pkg.dir, packageDir));
75 } else { 85 } else {
76 return id.source.install(id, packageDir).transform((found) { 86 return id.source.install(id, packageDir).transform((found) {
77 if (found) return null; 87 if (found) return null;
78 // TODO(nweiz): More robust error-handling. 88 // TODO(nweiz): More robust error-handling.
79 throw 'Package ${id.fullName} not found in source ' 89 throw 'Package ${id.name} not found in source "${id.source.name}".';
80 '"${id.source.name}".';
81 }); 90 });
82 } 91 }
83 }).chain((_) => Package.load(packageDir, cache.sources)); 92 }).chain((_) => Package.load(packageDir, cache.sources));
84 93
85 future.then((pkg) => _loadedPackages[id] = pkg); 94 future.then((pkg) => _loadedPackages[id] = pkg);
86 always(future, () => _pendingInstalls.remove(id)); 95 always(future, () => _pendingInstalls.remove(id));
87 _pendingInstalls[id] = future; 96 _pendingInstalls[id] = future;
88 97
89 return future; 98 return future;
90 } 99 }
91 100
92 /** 101 /**
93 * Installs the package identified by [id] and all its transitive 102 * Installs all dependencies of the [root] package to its "packages"
94 * dependencies. 103 * directory. Returns a [Future] that completes when all dependencies are
104 * installed.
95 */ 105 */
96 Future<Package> installTransitively(PackageId id) { 106 Future installDependencies() {
97 var seen = new Set<PackageId>(); 107 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 108
102 return install(id).chain((package) { 109 Future helper(List<PackageRef> packages) {
103 return Futures.wait(package.dependencies.map(helper)). 110 return Futures.wait(packages.map((ref) {
104 transform((_) => package); 111 return resolve(ref).chain((id) {
105 }); 112 if (seen.contains(id)) return new Future.immediate(null);
113 seen.add(id);
114
115 return install(id).chain((package) {
116 return helper(package.dependencies);
117 });
118 });
119 }));
106 } 120 }
107 121
108 return helper(id); 122 return helper(root.dependencies);
109 } 123 }
110 124
111 /** 125 /**
112 * Installs all dependencies of [owner] to the "packages" directory. Returns a 126 * Given [ref], which ambiguously identifies a dependent package, selects an
113 * [Future] that completes when all dependencies are installed. 127 * appropriate precise package to use when this is the entrypoint. In other
128 * words, given a loose refence like "foo >= 2.0", figures out what concrete
129 * package we should use starting from this entrypoint.
114 */ 130 */
115 Future installDependencies() { 131 Future<PackageId> resolve(PackageRef ref) {
116 return Futures.wait(owner.dependencies.map(installTransitively)). 132 // TODO(rnystrom): This should use the lockfile to select the right version
117 transform((_) => null); 133 // once that's implemented. If the lockfile doesn't exist, it should
134 // generate it. In the meantime, here's a dumb implementation:
135 return new Future.immediate(
136 new PackageId(ref.source, Version.none, ref.description));
118 } 137 }
119 } 138 }
OLDNEW
« no previous file with comments | « utils/pub/command_install.dart ('k') | utils/pub/git_source.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698