Chromium Code Reviews| Index: utils/pub/git_source.dart |
| diff --git a/utils/pub/git_source.dart b/utils/pub/git_source.dart |
| index 7c5fb8c5c994c8301c6f2214b83f56ea5479606a..28d04c3ca3a631d2e0092c5a6a4d95dcca828f6b 100644 |
| --- a/utils/pub/git_source.dart |
| +++ b/utils/pub/git_source.dart |
| @@ -54,8 +54,8 @@ class GitSource extends Source { |
| if (exists) return new Future.immediate(null); |
| return _clone(_repoCachePath(id), revisionCachePath); |
| }).chain((_) { |
| - var ref = _getRef(id); |
| - if (ref == null) return new Future.immediate(null); |
| + var ref = _getEffectiveRef(id); |
| + if (ref == 'HEAD') return new Future.immediate(null); |
| return _checkOut(revisionCachePath, ref); |
| }).chain((_) => Package.load(revisionCachePath, systemCache.sources)); |
| } |
| @@ -70,7 +70,7 @@ class GitSource extends Source { |
| /** |
| * Ensures [description] is a Git URL. |
| */ |
| - void validateDescription(description) { |
| + void validateDescription(description, [bool fromLockFile=false]) { |
|
Jennifer Messerly
2012/07/19 18:45:34
nit: spaces around equals http://www.dartlang.org/
nweiz
2012/07/19 18:56:54
Done.
|
| // A single string is assumed to be a Git URL. |
| if (description is String) return; |
| if (description is! Map || !description.containsKey('url')) { |
| @@ -80,10 +80,11 @@ class GitSource extends Source { |
| description = new Map.from(description); |
| description.remove('url'); |
| description.remove('ref'); |
| + if (fromLockFile) description.remove('resolved-ref'); |
| if (!description.isEmpty()) { |
| var plural = description.length > 1; |
| - var keys = Strings.join(description.keys, ', '); |
| + var keys = Strings.join(description.getKeys(), ', '); |
| throw new FormatException("Invalid key${plural ? 's' : ''}: $keys."); |
| } |
| } |
| @@ -100,6 +101,17 @@ class GitSource extends Source { |
| } |
| /** |
| + * Attaches a specific commit to [id] to disambiguate it. |
| + */ |
| + Future<PackageId> resolveId(PackageId id) { |
| + return _revisionAt(id).transform((revision) { |
| + var description = {'url': _getUrl(id), 'ref': _getRef(id)}; |
| + description['resolved-ref'] = revision; |
| + return new PackageId(this, id.version, description); |
| + }); |
| + } |
| + |
| + /** |
| * Ensure that the canonical clone of the repository referred to by [id] (the |
| * one in `<system cache>/git/cache`) exists and is up-to-date. Returns a |
| * future that completes once this is finished and throws an exception if it |
| @@ -119,11 +131,10 @@ class GitSource extends Source { |
| } |
| /** |
| - * Returns a future that completes to the revision hash of the repository for |
| - * [id] at [ref], which can be any Git ref. |
| + * Returns a future that completes to the revision hash of [id]. |
| */ |
| - Future<String> _revisionAt(PackageId id, String ref) { |
| - return runProcess("git", ["rev-parse", ref], |
| + Future<String> _revisionAt(PackageId id) { |
| + return runProcess("git", ["rev-parse", _getEffectiveRef(id)], |
| workingDir: _repoCachePath(id), pipeStderr: true).transform((result) { |
| if (!result.success) throw 'Git failed.'; |
| return result.stdout[0]; |
| @@ -131,13 +142,10 @@ class GitSource extends Source { |
| } |
| /** |
| - * Returns the path to the revision-specific cache of [id] at [ref], which can |
| - * be any Git ref. |
| + * Returns the path to the revision-specific cache of [id]. |
| */ |
| Future<String> _revisionCachePath(PackageId id) { |
| - var ref = _getRef(id); |
| - if (ref == null) ref = 'HEAD'; |
| - return _revisionAt(id, ref).transform((rev) { |
| + return _revisionAt(id).transform((rev) { |
| var revisionCacheName = '${id.name}-$rev'; |
| return join(systemCacheRoot, revisionCacheName); |
| }); |
| @@ -186,7 +194,26 @@ class GitSource extends Source { |
| } |
| /** |
| - * Returns the commit ref for [id], or null if none is given. |
| + * Returns the commit ref that should be checked out for [description]. |
| + * |
| + * This differs from [_getRef] in that it doesn't just return the ref in |
| + * [description]. It will return a sensible default if that ref doesn't exist, |
| + * and it will respect the "resolved-ref" parameter set by [resolveId]. |
| + * |
| + * [description] may be a description or a [PackageId]. |
| + */ |
| + String _getEffectiveRef(description) { |
| + description = _getDescription(description); |
| + if (description is Map && description.containsKey('resolved-ref')) { |
| + return description['resolved-ref']; |
| + } |
| + |
| + var ref = _getRef(description); |
| + return ref == null ? 'HEAD' : ref; |
| + } |
| + |
| + /** |
| + * Returns the commit ref for [description], or null if none is given. |
| * |
| * [description] may be a description or a [PackageId]. |
| */ |