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

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

Issue 10340005: Add support for pub install. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix Chromium review errors? 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 * A named, versioned, unit of code and resource reuse. 6 * A named, versioned, unit of code and resource reuse.
7 */ 7 */
8 class Package implements Hashable { 8 class Package implements Hashable {
9 /** 9 /**
10 * Loads the package whose root directory is [packageDir]. 10 * Loads the package whose root directory is [packageDir].
(...skipping 10 matching lines...) Expand all
21 * The path to the directory containing the package. 21 * The path to the directory containing the package.
22 */ 22 */
23 final String dir; 23 final String dir;
24 24
25 /** 25 /**
26 * The name of the package. 26 * The name of the package.
27 */ 27 */
28 final String name; 28 final String name;
29 29
30 /** 30 /**
31 * The names of the packages that this package depends on. This is what is 31 * The ids of the packages that this package depends on. This is what is
32 * specified in the pubspec when this package depends on another. 32 * specified in the pubspec when this package depends on another.
33 */ 33 */
34 // TODO(rnystrom): When packages are versioned and sourced, this will likely 34 final Collection<PackageId> dependencies;
35 // be something more than just a string.
36 final Collection<String> dependencies;
37 35
38 /** 36 /**
39 * Constructs a package. This should not be called directly. Instead, acquire 37 * Constructs a package. This should not be called directly. Instead, acquire
40 * packages from [load()]. 38 * packages from [load()].
41 */ 39 */
42 Package._(String dir, this.dependencies) 40 Package._(String dir, this.dependencies)
43 : dir = dir, 41 : dir = dir,
44 name = basename(dir); 42 name = basename(dir);
45 43
46 /** 44 /**
47 * Reads and returns all of the packages this package immediately depends on.
48 */
49 Future<Collection<Package>> loadDependencies(PackageCache cache) {
50 return Futures.wait(dependencies.map((name) => cache.find(name)));
51 }
52
53 /**
54 * Walks the entire dependency graph starting at this package and returns a
55 * [Set] of all of the packages dependend on by this one, directly or
56 * indirectly. This package is included in the result set.
57 */
58 Future<Set<Package>> traverseDependencies(PackageCache cache) {
59 final completer = new Completer<Set<Package>>();
60 final packages = new Set<Package>();
61
62 var pendingAsyncCalls = 0;
63
64 walkPackage(Package package) {
65 // Skip packages we've already traversed.
66 if (packages.contains(package)) return;
67
68 // Add the package.
69 packages.add(package);
70
71 // Recurse into its dependencies.
72 pendingAsyncCalls++;
73 package.loadDependencies(cache).then((dependencies) {
74 dependencies.forEach(walkPackage);
75 pendingAsyncCalls--;
76 if (pendingAsyncCalls == 0) completer.complete(packages);
77 });
78 }
79
80 walkPackage(this);
81
82 return completer.future;
83 }
84
85 /**
86 * Generates a hashcode for the package. 45 * Generates a hashcode for the package.
87 */ 46 */
88 // TODO(rnystrom): Do something more sophisticated here once we care about 47 // TODO(rnystrom): Do something more sophisticated here once we care about
89 // versioning and different package sources. 48 // versioning and different package sources.
90 int hashCode() => name.hashCode(); 49 int hashCode() => name.hashCode();
91 50
92 /** 51 /**
93 * Returns a debug string for the package. 52 * Returns a debug string for the package.
94 */ 53 */
95 String toString() => '$name ($dir)'; 54 String toString() => '$name ($dir)';
96 55
97 /** 56 /**
98 * Parses the pubspec at the given path and returns the list of package 57 * Parses the pubspec at the given path and returns the list of package
99 * dependencies it exposes. 58 * dependencies it exposes.
100 */ 59 */
101 static Future<List<String>> _parsePubspec(String path) { 60 static Future<List<PackageId>> _parsePubspec(String path) {
102 final completer = new Completer<List<String>>(); 61 final completer = new Completer<List<PackageId>>();
103 62
104 // TODO(rnystrom): Handle the directory not existing. 63 // TODO(rnystrom): Handle the directory not existing.
105 // TODO(rnystrom): Error-handling. 64 // TODO(rnystrom): Error-handling.
106 final readFuture = readTextFile(path); 65 final readFuture = readTextFile(path);
107 readFuture.handleException((error) { 66 readFuture.handleException((error) {
108 // If there is no pubspec, we implicitly treat that as a package with no 67 // If there is no pubspec, we implicitly treat that as a package with no
109 // dependencies. 68 // dependencies.
110 // TODO(rnystrom): Distinguish file not found from other real errors. 69 // TODO(rnystrom): Distinguish file not found from other real errors.
111 completer.complete(<String>[]); 70 completer.complete(<PackageId>[]);
112 return true; 71 return true;
113 }); 72 });
114 73
115 readFuture.then((pubspec) { 74 readFuture.then((pubspec) {
116 if (pubspec.trim() == '') { 75 if (pubspec.trim() == '') {
117 completer.complete(<String>[]); 76 completer.complete(<String>[]);
118 return; 77 return;
119 } 78 }
120 79
121 var parsedPubspec = loadYaml(pubspec); 80 var parsedPubspec = loadYaml(pubspec);
122 if (parsedPubspec is! Map) { 81 if (parsedPubspec is! Map) {
123 completer.completeException('The pubspec must be a YAML mapping.'); 82 completer.completeException('The pubspec must be a YAML mapping.');
124 } 83 }
125 84
126 if (!parsedPubspec.containsKey('dependencies')) { 85 if (!parsedPubspec.containsKey('dependencies')) {
127 completer.complete(<String>[]); 86 completer.complete(<String>[]);
128 return; 87 return;
129 } 88 }
130 89
131 var dependencies = parsedPubspec['dependencies']; 90 var dependencies = parsedPubspec['dependencies'];
132 if (dependencies.some((e) => e is! String)) { 91 if (dependencies.some((e) => e is! String)) {
133 completer.completeException( 92 completer.completeException(
134 'The pubspec dependencies must be a list of package names.'); 93 'The pubspec dependencies must be a list of package names.');
135 } 94 }
136 95
137 completer.complete(dependencies); 96 var dependencyIds =
97 dependencies.map((name) => new PackageId(name, Source.defaultSource));
98 completer.complete(dependencyIds);
138 }); 99 });
139 100
140 return completer.future; 101 return completer.future;
141 } 102 }
142 } 103 }
104
105 /**
106 * A unique identifier for a package. A given package id specifies a single
107 * chunk of code and resources.
108 *
109 * Note that it's possible for multiple package ids to point to identical
110 * packages. For example, the same package may be available from multiple
111 * sources. As far as Pub is concerned, those packages are different.
112 */
113 // TODO(nweiz, rnystrom): this should include version eventually
114 class PackageId implements Hashable {
115 /**
116 * The name used by the [source] to look up the package.
117 *
118 * Note that this may be distinct from the name of the package itself. The
119 * [source] uses this name to locate the package and returns the true package
120 * name. For example, for a Git source [name] might be the URL
121 * "git://github.com/dart/uilib.git", while the package name would just be
122 * "uilib". It would be up to the source to take the URL and extract the
123 * package name.
124 */
125 final String name;
Bob Nystrom 2012/05/03 00:23:02 "fullName". You may also want to make a "name" ge
nweiz 2012/05/04 01:03:43 Done.
126
127 /**
128 * The [Source] used to look up the package given the [name].
129 */
130 final Source source;
131
132 PackageId(String this.name, Source this.source);
133
134 int hashCode() => name.hashCode() ^ source.name.hashCode();
135
136 bool operator ==(other) {
137 if (other is! PackageId) return false;
138 return other.name == name && other.source.name == source.name;
139 }
140
141 String toString() => "$name from ${source.name}";
142 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698