@@ -266,21 +266,6 @@ class GitSource extends CachedSource {
266266 return p.url.normalize (parsed.toString ());
267267 }
268268
269- /// Limit the number of concurrent git operations to 1.
270- // TODO(sigurdm): Use RateLimitedScheduler.
271- final Pool _pool = Pool (1 );
272-
273- /// A map from revision cache locations to futures that will complete once
274- /// they're finished being cloned.
275- ///
276- /// This lets us avoid race conditions when getting multiple different
277- /// packages from the same repository.
278- final _revisionCacheClones = < String , Future <void >> {};
279-
280- /// The paths to the canonical clones of repositories for which "git fetch"
281- /// has already been run during this run of pub.
282- final _updatedRepos = < String > {};
283-
284269 /// Given a Git repo that contains a pub package, gets the name of the pub
285270 /// package.
286271 ///
@@ -305,7 +290,7 @@ class GitSource extends CachedSource {
305290 containingDir: relativeTo,
306291 tagPattern: tagPattern,
307292 );
308- return await _pool .withResource (() async {
293+ return await cache.gitCache.pool .withResource (() async {
309294 await _ensureRepoCache (description, cache);
310295 final path = _repoCachePath (description, cache);
311296
@@ -370,7 +355,7 @@ class GitSource extends CachedSource {
370355 if (description is ! GitDescription ) {
371356 throw StateError ('Called with wrong ref' );
372357 }
373- return await _pool .withResource (() async {
358+ return await cache.gitCache.pool .withResource (() async {
374359 await _ensureRepoCache (description, cache);
375360 final path = _repoCachePath (description, cache);
376361 final result = < PackageId > [];
@@ -417,7 +402,7 @@ class GitSource extends CachedSource {
417402 if (description is ! ResolvedGitDescription ) {
418403 throw StateError ('Called with wrong ref' );
419404 }
420- final pubspec = await _pool .withResource (
405+ final pubspec = await cache.gitCache.pool .withResource (
421406 () => _describeUncached (id.toRef (), description.resolvedRef, cache),
422407 );
423408 if (pubspec.version != id.version) {
@@ -430,8 +415,6 @@ class GitSource extends CachedSource {
430415 return pubspec;
431416 }
432417
433- final Map <(PackageRef , String ), Pubspec > _pubspecAtRevisionCache = {};
434-
435418 /// Like [describeUncached] , but takes a separate [ref] and Git [revision]
436419 /// rather than a single ID.
437420 Future <Pubspec > _describeUncached (
@@ -443,7 +426,10 @@ class GitSource extends CachedSource {
443426 if (description is ! GitDescription ) {
444427 throw ArgumentError ('Wrong source' );
445428 }
446- return _pubspecAtRevisionCache[(ref, revision)] ?? = await () async {
429+ return cache.gitCache.pubspecAtRevisionCache[(
430+ ref,
431+ revision,
432+ )] ?? = await () async {
447433 await _ensureRevision (description, revision, cache);
448434 final resolvedDescription = ResolvedGitDescription (description, revision);
449435 return Pubspec .parse (
@@ -473,7 +459,7 @@ class GitSource extends CachedSource {
473459 PackageId id,
474460 SystemCache cache,
475461 ) async {
476- return await _pool .withResource (() async {
462+ return await cache.gitCache.pool .withResource (() async {
477463 var didUpdate = false ;
478464 final ref = id.toRef ();
479465 final description = ref.description;
@@ -495,25 +481,28 @@ class GitSource extends CachedSource {
495481
496482 final revisionCachePath = _revisionCachePath (id, cache);
497483 final path = description.path;
498- await _revisionCacheClones.putIfAbsent (revisionCachePath, () async {
499- if (! entryExists (revisionCachePath)) {
500- await _cloneViaTemp (
501- _repoCachePath (description, cache),
502- revisionCachePath,
503- cache,
504- );
505- await git.run ([
506- 'config' ,
507- 'remote.origin.lfsurl' ,
508- description.url,
509- ], workingDir: revisionCachePath);
510- await _checkOut (revisionCachePath, resolvedRef);
511- _writePackageList (revisionCachePath, [path]);
512- didUpdate = true ;
513- } else {
514- didUpdate | = _updatePackageList (revisionCachePath, path);
515- }
516- });
484+ await cache.gitCache.revisionCacheClones.putIfAbsent (
485+ revisionCachePath,
486+ () async {
487+ if (! entryExists (revisionCachePath)) {
488+ await _cloneViaTemp (
489+ _repoCachePath (description, cache),
490+ revisionCachePath,
491+ cache,
492+ );
493+ await git.run ([
494+ 'config' ,
495+ 'remote.origin.lfsurl' ,
496+ description.url,
497+ ], workingDir: revisionCachePath);
498+ await _checkOut (revisionCachePath, resolvedRef);
499+ _writePackageList (revisionCachePath, [path]);
500+ didUpdate = true ;
501+ } else {
502+ didUpdate | = _updatePackageList (revisionCachePath, path);
503+ }
504+ },
505+ );
517506 return DownloadPackageResult (id, didUpdate: didUpdate);
518507 });
519508 }
@@ -646,7 +635,7 @@ class GitSource extends CachedSource {
646635 SystemCache cache,
647636 ) async {
648637 final path = _repoCachePath (description, cache);
649- if (_updatedRepos .contains (path)) return false ;
638+ if (cache.gitCache.updatedRepos .contains (path)) return false ;
650639
651640 await _deleteGitRepoIfInvalid (path);
652641
@@ -672,7 +661,7 @@ class GitSource extends CachedSource {
672661 SystemCache cache,
673662 ) async {
674663 final path = _repoCachePath (description, cache);
675- if (_updatedRepos .contains (path)) return false ;
664+ if (cache.gitCache.updatedRepos .contains (path)) return false ;
676665
677666 await _deleteGitRepoIfInvalid (path);
678667
@@ -693,14 +682,14 @@ class GitSource extends CachedSource {
693682 SystemCache cache,
694683 ) async {
695684 final path = _repoCachePath (description, cache);
696- assert (! _updatedRepos .contains (path));
685+ assert (! cache.gitCache.updatedRepos .contains (path));
697686 try {
698687 await _cloneViaTemp (description.url, path, cache, mirror: true );
699688 } catch (_) {
700689 await _deleteGitRepoIfInvalid (path);
701690 rethrow ;
702691 }
703- _updatedRepos .add (path);
692+ cache.gitCache.updatedRepos .add (path);
704693 }
705694
706695 /// Runs "git fetch" in the canonical clone of the repository referred to by
@@ -714,9 +703,9 @@ class GitSource extends CachedSource {
714703 SystemCache cache,
715704 ) async {
716705 final path = _repoCachePath (description, cache);
717- if (_updatedRepos .contains (path)) return false ;
706+ if (cache.gitCache.updatedRepos .contains (path)) return false ;
718707 await git.run ([_gitDirArg (path), 'fetch' ], workingDir: path);
719- _updatedRepos .add (path);
708+ cache.gitCache.updatedRepos .add (path);
720709 return true ;
721710 }
722711
@@ -1226,3 +1215,22 @@ RegExp compileTagPattern(String tagPattern) {
12261215 r'$' ,
12271216 );
12281217}
1218+
1219+ /// State that is cached for the GitSource.
1220+ final class GitSourceCache {
1221+ /// Limit the number of concurrent git operations to 1.
1222+ final pool = Pool (1 );
1223+
1224+ /// A map from revision cache locations to futures that will complete once
1225+ /// they're finished being cloned.
1226+ ///
1227+ /// This lets us avoid race conditions when getting multiple different
1228+ /// packages from the same repository.
1229+ final revisionCacheClones = < String , Future <void >> {};
1230+
1231+ /// The paths to the canonical clones of repositories for which "git fetch"
1232+ /// has already been run during this run of pub.
1233+ final updatedRepos = < String > {};
1234+
1235+ final pubspecAtRevisionCache = < (PackageRef , String ), Pubspec > {};
1236+ }
0 commit comments