Skip to content

Commit 3be3412

Browse files
committed
Fetch entire pubspec for each valid version tag
Add "use_version_tags" boolean to git source descriptions
1 parent b29194d commit 3be3412

File tree

1 file changed

+61
-12
lines changed

1 file changed

+61
-12
lines changed

lib/src/source/git.dart

+61-12
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,40 @@ class GitSource extends CachedSource {
4545
/// Anything that Version.parse understands is considered a version,
4646
/// it will also attempt to strip off a preceding 'v' e.g. v1.0.0
4747
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);
5162
List<Pubspec> validVersions = [];
52-
results.forEach((String version) {
63+
for (String version in results) {
5364
// Strip preceding 'v' character so 'v1.0.0' can be parsed into a Version
5465
if (version.startsWith('v')) {
5566
version = version.substring(1);
5667
}
5768
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));
6074
} on FormatException {}
61-
});
75+
}
76+
6277
if (validVersions.length > 0) {
6378
return validVersions;
6479
}
80+
81+
// No valid version tags were found, defer to super
6582
return super.getVersions(name, description);
6683
}
6784

@@ -129,6 +146,7 @@ class GitSource extends CachedSource {
129146
var parsed = new Map.from(description);
130147
parsed.remove('url');
131148
parsed.remove('ref');
149+
parsed.remove('use_version_tags');
132150
if (fromLockFile) parsed.remove('resolved-ref');
133151

134152
if (!parsed.isEmpty) {
@@ -174,6 +192,10 @@ class GitSource extends CachedSource {
174192
Future<PackageId> resolveId(PackageId id) {
175193
return _ensureRevision(id).then((revision) {
176194
var description = {'url': _getUrl(id), 'ref': _getRef(id)};
195+
bool useVersionTags = _useVersionTags(id);
196+
if (useVersionTags) {
197+
description['use_version_tags'] = useVersionTags;
198+
}
177199
description['resolved-ref'] = revision;
178200
return new PackageId(id.name, name, id.version, description);
179201
});
@@ -279,8 +301,19 @@ class GitSource extends CachedSource {
279301
///
280302
/// This assumes that the canonical clone already exists.
281303
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+
});
284317
}
285318

286319
/// Clones the repo at the URI [from] to the path [to] on the local
@@ -310,8 +343,13 @@ class GitSource extends CachedSource {
310343

311344
/// Checks out the reference [ref] in [repoPath].
312345
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+
});
315353
}
316354

317355
/// Returns the path to the canonical clone of the repository referred to by
@@ -345,7 +383,8 @@ class GitSource extends CachedSource {
345383
}
346384

347385
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) {
349388
return id.version.toString();
350389
}
351390
return ref == null ? 'HEAD' : ref;
@@ -366,4 +405,14 @@ class GitSource extends CachedSource {
366405
if (description is PackageId) return description.description;
367406
return description;
368407
}
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+
}
369418
}

0 commit comments

Comments
 (0)