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

Unified Diff: utils/pub/package.dart

Issue 10207018: First pass at "pub update" implementation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor cleanup. 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 side-by-side diff with in-line comments
Download patch
Index: utils/pub/package.dart
diff --git a/utils/pub/package.dart b/utils/pub/package.dart
index 2942a92c67c1c4ec2af1a8a65d3b9b276d722f72..e1b19654c7b2791e69a6c0a1834dffa759ce5a98 100644
--- a/utils/pub/package.dart
+++ b/utils/pub/package.dart
@@ -5,7 +5,23 @@
/**
* A named, versioned, unit of code and resource reuse.
*/
-class Package {
+class Package implements Hashable {
+ /**
+ * Loads the package whose root directory is [packageDir].
+ */
+ static Future<Package> load(String packageDir) {
+ final pubspecPath = join(packageDir, 'pubspec');
+
+ return _parsePubspec(pubspecPath).transform((dependencies) {
+ return new Package._(packageDir, dependencies);
+ });
+ }
+
+ /**
+ * The path to the directory containing the package.
+ */
+ final String dir;
+
/**
* The name of the package.
*/
@@ -20,20 +36,93 @@ class Package {
final Collection<String> dependencies;
/**
- * The cache where this package is contained.
+ * Constructs a package. This should not be called directly. Instead, acquire
+ * packages from [load()].
*/
- final PackageCache _cache;
+ Package._(String dir, this.dependencies)
+ : dir = dir,
+ name = basename(dir);
/**
- * Constructs a package. This should not be called directly. Instead, acquire
- * packages from [PackageCache].
+ * Reads and returns all of the packages this package immediately depends on.
+ */
+ Future<Collection<Package>> loadDependencies() {
nweiz 2012/04/25 17:50:47 I don't think the distinction between loadDependen
Bob Nystrom 2012/04/25 22:20:29 "local" doesn't have the right connotation to me.
nweiz 2012/04/25 22:30:09 I like "loadImmediateDependencies". It is verbose,
+ return Futures.wait(dependencies.map((name) => cache.find(name)));
+ }
+
+ /**
+ * Walks the entire dependency graph starting at this package and returns a
+ * [Set] of all of the packages dependend on by this one, directly or
+ * indirectly. This package is included in the result set.
+ */
+ Future<Set<Package>> traverseDependencies() {
+ final completer = new Completer<Set<Package>>();
+ final packages = new Set<Package>();
+
+ var pendingAsyncCalls = 0;
+
+ walkPackage(Package package) {
+ // Skip packages we've already traversed.
+ if (packages.contains(package)) return;
+
+ // Add the package.
+ packages.add(package);
+
+ // Recurse into its dependencies.
+ pendingAsyncCalls++;
+ package.loadDependencies().then((dependencies) {
+ for (final dependency in dependencies) {
nweiz 2012/04/25 17:50:47 I would write dependencies.forEach(walkPackage), b
Bob Nystrom 2012/04/25 22:20:29 Done.
+ walkPackage(dependency);
+ }
+
+ pendingAsyncCalls--;
+ if (pendingAsyncCalls == 0) completer.complete(packages);
+ });
+ }
+
+ walkPackage(this);
+
+ return completer.future;
+ }
+
+ /**
+ * Generates a hashcode for the package.
+ */
+ int hashCode() => name.hashCode();
nweiz 2012/04/25 17:50:47 If you define hashCode, you should also define ==.
Bob Nystrom 2012/04/25 22:20:29 Leaving a TODO for now. I definitely want somethin
+
+ /**
+ * Returns a debug string for the package.
*/
- Package._(this._cache, this.name, this.dependencies);
+ String toString() => '$name ($dir)';
/**
- * Reads and returns all of the packages this package depends on.
+ * Parses the pubspec at the given path and returns the list of package
+ * dependencies it exposes.
*/
- Future<Collection<Package>> readDependencies() {
- return Futures.wait(dependencies.map((name) => _cache.find(name)));
+ static Future<List<String>> _parsePubspec(String path) {
+ final completer = new Completer<List<String>>();
+
+ // TODO(rnystrom): Handle the directory not existing.
+ // TODO(rnystrom): Error-handling.
+ final readFuture = readTextFile(path);
+ readFuture.handleException((error) {
+ // If there is no pubspec, we implicitly treat that as a package with no
+ // dependencies.
+ // TODO(rnystrom): Distinguish file not found from other real errors.
+ completer.complete(<String>[]);
+ return true;
+ });
+
+ readFuture.then((pubspec) {
+ // TODO(rnystrom): Use YAML parser when ready. For now, it's just a flat
+ // list of newline-separated strings.
+ final dependencyNames = pubspec.split('\n').
+ map((name) => name.trim()).
+ filter((name) => (name != null) && (name != ''));
+
+ completer.complete(dependencyNames);
+ });
+
+ return completer.future;
}
}
« utils/pub/io.dart ('K') | « utils/pub/io.dart ('k') | utils/pub/pub.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698