@@ -45,23 +45,40 @@ class GitSource extends CachedSource {
45
45
/// Anything that Version.parse understands is considered a version,
46
46
/// it will also attempt to strip off a preceding 'v' e.g. v1.0.0
47
47
Future <List <Pubspec >> getVersions (String name, description) async {
48
- PackageId id = new PackageId (name, null , null , _getDescription (description));
49
- await describeUncached (id);
50
- List results = await git.run (["tag" , "-l" ], workingDir: _repoCachePath (id));
48
+ if (! _useVersionTags (description)) {
49
+ // No need to get versions if the useVersionTags option is false
50
+ return super .getVersions (name, description);
51
+ }
52
+
53
+ PackageId id =
54
+ new PackageId (name, this .name, null , _getDescription (description));
55
+ String cachePath = _repoCachePath (id);
56
+ if (! entryExists (cachePath)) {
57
+ // Must have the repo cloned in order to list its tags
58
+ await _clone (_getUrl (id), cachePath);
59
+ }
60
+
61
+ List results = await git.run (["tag" , "-l" ], workingDir: cachePath);
51
62
List <Pubspec > validVersions = [];
52
- results. forEach (( String version) {
63
+ for ( String version in results ) {
53
64
// Strip preceding 'v' character so 'v1.0.0' can be parsed into a Version
54
65
if (version.startsWith ('v' )) {
55
66
version = version.substring (1 );
56
67
}
57
68
try {
58
- Pubspec pubspec = new Pubspec (name, version: new Version .parse (version));
59
- validVersions.add (pubspec);
69
+ // Use Version.parse to determine valid version tags
70
+ PackageId packageAtVersion = new PackageId (
71
+ name, this .name, new Version .parse (version), description);
72
+ // Fetch the pubspec for this version
73
+ validVersions.add (await describeUncached (packageAtVersion));
60
74
} on FormatException {}
61
- });
75
+ }
76
+
62
77
if (validVersions.length > 0 ) {
63
78
return validVersions;
64
79
}
80
+
81
+ // No valid version tags were found, defer to super
65
82
return super .getVersions (name, description);
66
83
}
67
84
@@ -129,6 +146,7 @@ class GitSource extends CachedSource {
129
146
var parsed = new Map .from (description);
130
147
parsed.remove ('url' );
131
148
parsed.remove ('ref' );
149
+ parsed.remove ('use_version_tags' );
132
150
if (fromLockFile) parsed.remove ('resolved-ref' );
133
151
134
152
if (! parsed.isEmpty) {
@@ -174,6 +192,10 @@ class GitSource extends CachedSource {
174
192
Future <PackageId > resolveId (PackageId id) {
175
193
return _ensureRevision (id).then ((revision) {
176
194
var description = {'url' : _getUrl (id), 'ref' : _getRef (id)};
195
+ bool useVersionTags = _useVersionTags (id);
196
+ if (useVersionTags) {
197
+ description['use_version_tags' ] = useVersionTags;
198
+ }
177
199
description['resolved-ref' ] = revision;
178
200
return new PackageId (id.name, name, id.version, description);
179
201
});
@@ -279,8 +301,19 @@ class GitSource extends CachedSource {
279
301
///
280
302
/// This assumes that the canonical clone already exists.
281
303
Future <String > _getRev (PackageId id) {
282
- return git.run (["rev-list" , "--max-count=1" , _getEffectiveRef (id)],
283
- workingDir: _repoCachePath (id)).then ((result) => result.first);
304
+ var ref = _getEffectiveRef (id);
305
+ return git
306
+ .run (["rev-list" , "--max-count=1" , ref], workingDir: _repoCachePath (id))
307
+ .then ((result) => result.first)
308
+ .catchError ((e) {
309
+ if (ref == id.version.toString ()) {
310
+ // Try again with a "v" before the ref in case this was a version tag
311
+ ref = 'v$ref ' ;
312
+ return git.run (["rev-list" , "--max-count=1" , ref],
313
+ workingDir: _repoCachePath (id)).then ((result) => result.first);
314
+ }
315
+ throw e;
316
+ });
284
317
}
285
318
286
319
/// Clones the repo at the URI [from] to the path [to] on the local
@@ -310,8 +343,13 @@ class GitSource extends CachedSource {
310
343
311
344
/// Checks out the reference [ref] in [repoPath] .
312
345
Future _checkOut (String repoPath, String ref) {
313
- return git.run (["checkout" , ref], workingDir: repoPath).then (
314
- (result) => null );
346
+ return git.run (["checkout" , ref], workingDir: repoPath)
347
+ .then ((result) => null )
348
+ .catchError ((_) {
349
+ // Try again with a "v" before the ref in case this was a version tag
350
+ return git.run (["checkout" , 'v$ref ' ], workingDir: repoPath)
351
+ .then ((result) => null );
352
+ });
315
353
}
316
354
317
355
/// Returns the path to the canonical clone of the repository referred to by
@@ -345,7 +383,8 @@ class GitSource extends CachedSource {
345
383
}
346
384
347
385
var ref = _getRef (description);
348
- if (ref == null && id.version != null && id.version != Version .none) {
386
+ if (_useVersionTags (description) && id.version != null &&
387
+ id.version != Version .none) {
349
388
return id.version.toString ();
350
389
}
351
390
return ref == null ? 'HEAD' : ref;
@@ -366,4 +405,14 @@ class GitSource extends CachedSource {
366
405
if (description is PackageId ) return description.description;
367
406
return description;
368
407
}
408
+
409
+ /// Returns value of "use_version_tags" in the description
410
+ ///
411
+ /// [description] may be a description or a [PackageId] .
412
+ bool _useVersionTags (description) {
413
+ description = _getDescription (description);
414
+ if (description is String ) return false ;
415
+ return description.containsKey ('use_version_tags' )
416
+ ? description['use_version_tags' ] : false ;
417
+ }
369
418
}
0 commit comments