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

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

Issue 10214006: Refactor command code and add support for --help and --version. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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 { 8 class Package implements Hashable {
9 /**
10 * Loads the package whose root directory is [packageDir].
11 */
12 static Future<Package> load(String packageDir) {
13 final pubspecPath = join(packageDir, 'pubspec');
14
15 return _parsePubspec(pubspecPath).transform((dependencies) {
16 return new Package._(packageDir, dependencies);
17 });
18 }
19
20 /**
21 * The path to the directory containing the package.
22 */
23 final String dir;
24
9 /** 25 /**
10 * The name of the package. 26 * The name of the package.
11 */ 27 */
12 final String name; 28 final String name;
13 29
14 /** 30 /**
15 * The names of the packages that this package depends on. This is what is 31 * The names of the packages that this package depends on. This is what is
16 * specified in the pubspec when this package depends on another. 32 * specified in the pubspec when this package depends on another.
17 */ 33 */
18 // TODO(rnystrom): When packages are versioned and sourced, this will likely 34 // TODO(rnystrom): When packages are versioned and sourced, this will likely
19 // be something more than just a string. 35 // be something more than just a string.
20 final Collection<String> dependencies; 36 final Collection<String> dependencies;
21 37
22 /** 38 /**
23 * The cache where this package is contained. 39 * Constructs a package. This should not be called directly. Instead, acquire
40 * packages from [load()].
24 */ 41 */
25 final PackageCache _cache; 42 Package._(String dir, this.dependencies)
43 : dir = dir,
44 name = basename(dir);
26 45
27 /** 46 /**
28 * Constructs a package. This should not be called directly. Instead, acquire 47 * Reads and returns all of the packages this package immediately depends on.
29 * packages from [PackageCache].
30 */ 48 */
31 Package._(this._cache, this.name, this.dependencies); 49 Future<Collection<Package>> loadDependencies(PackageCache cache) {
50 return Futures.wait(dependencies.map((name) => cache.find(name)));
51 }
32 52
33 /** 53 /**
34 * Reads and returns all of the packages this package depends on. 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.
35 */ 57 */
36 Future<Collection<Package>> readDependencies() { 58 Future<Set<Package>> traverseDependencies(PackageCache cache) {
37 return Futures.wait(dependencies.map((name) => _cache.find(name))); 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 for (final dependency in dependencies) {
75 walkPackage(dependency);
76 }
77
78 pendingAsyncCalls--;
79 if (pendingAsyncCalls == 0) completer.complete(packages);
80 });
81 }
82
83 walkPackage(this);
84
85 return completer.future;
86 }
87
88 /**
89 * Generates a hashcode for the package.
90 */
91 int hashCode() => name.hashCode();
92
93 /**
94 * Returns a debug string for the package.
95 */
96 String toString() => '$name ($dir)';
97
98 /**
99 * Parses the pubspec at the given path and returns the list of package
100 * dependencies it exposes.
101 */
102 static Future<List<String>> _parsePubspec(String path) {
103 final completer = new Completer<List<String>>();
104
105 // TODO(rnystrom): Handle the directory not existing.
106 // TODO(rnystrom): Error-handling.
107 final readFuture = readTextFile(path);
108 readFuture.handleException((error) {
109 // If there is no pubspec, we implicitly treat that as a package with no
110 // dependencies.
111 // TODO(rnystrom): Distinguish file not found from other real errors.
112 completer.complete(<String>[]);
113 return true;
114 });
115
116 readFuture.then((pubspec) {
117 // TODO(rnystrom): Use YAML parser when ready. For now, it's just a flat
118 // list of newline-separated strings.
119 final dependencyNames = pubspec.split('\n').
120 map((name) => name.trim()).
121 filter((name) => (name != null) && (name != ''));
122
123 completer.complete(dependencyNames);
124 });
125
126 return completer.future;
38 } 127 }
39 } 128 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698