@@ -119,7 +119,7 @@ public HashSet<AssemblyLookupLocation> Restore()
119119 compilationInfoContainer . CompilationInfos . Add ( ( "NuGet feed responsiveness checked" , CheckNugetFeedResponsiveness ? "1" : "0" ) ) ;
120120
121121 HashSet < string > explicitFeeds = [ ] ;
122- string ? explicitNugetSources = null ;
122+ HashSet < string > reachableFeeds = [ ] ;
123123
124124 try
125125 {
@@ -137,9 +137,11 @@ public HashSet<AssemblyLookupLocation> Restore()
137137 compilationInfoContainer . CompilationInfos . Add ( ( "Inherited NuGet feed count" , inheritedFeeds . Count . ToString ( ) ) ) ;
138138 }
139139
140- var timeout = CheckSpecifiedFeeds ( explicitFeeds , out var reachableFeeds ) ;
141- var allReachable = explicitFeeds . Count == reachableFeeds . Count ;
142- EmitUnreachableFeedsDiagnostics ( allReachable ) ;
140+ var timeout = CheckSpecifiedFeeds ( explicitFeeds , out var reachableExplicitFeeds ) ;
141+ reachableFeeds . UnionWith ( reachableExplicitFeeds ) ;
142+
143+ var allExplicitReachable = explicitFeeds . Count == reachableExplicitFeeds . Count ;
144+ EmitUnreachableFeedsDiagnostics ( allExplicitReachable ) ;
143145
144146 if ( timeout )
145147 {
@@ -154,16 +156,6 @@ public HashSet<AssemblyLookupLocation> Restore()
154156 // Inherited feeds should only be used, if they are indeed reachable (as they may be environment specific).
155157 CheckSpecifiedFeeds ( inheritedFeeds , out var reachableInheritedFeeds ) ;
156158 reachableFeeds . UnionWith ( reachableInheritedFeeds ) ;
157-
158- // If feed responsiveness is being checked, we only want to use the feeds that are reachable (note this set includes private
159- // registry feeds if they are reachable).
160- explicitNugetSources = MakeRestoreSourcesArgument ( reachableFeeds ) ;
161- }
162- else if ( HasPrivateRegistryFeeds )
163- {
164- // If private registries are configured they need to be included as sources for the restore, which requires that
165- // they are provided as source arguments for the restore. The private registries are included in the `allFeeds` set.
166- explicitNugetSources = MakeRestoreSourcesArgument ( allFeeds ) ;
167159 }
168160
169161 using ( var nuget = new NugetExeWrapper ( fileProvider , legacyPackageDirectory , logger , IsDefaultFeedReachable ) )
@@ -206,9 +198,9 @@ public HashSet<AssemblyLookupLocation> Restore()
206198 }
207199
208200 // Restore project dependencies with `dotnet restore`.
209- var restoredProjects = RestoreSolutions ( explicitNugetSources , out var container ) ;
201+ var restoredProjects = RestoreSolutions ( reachableFeeds , out var container ) ;
210202 var projects = fileProvider . Projects . Except ( restoredProjects ) ;
211- RestoreProjects ( projects , explicitNugetSources , out var containers ) ;
203+ RestoreProjects ( projects , reachableFeeds , out var containers ) ;
212204
213205 var dependencies = containers . Flatten ( container ) ;
214206
@@ -313,7 +305,7 @@ private List<string> GetReachableFallbackNugetFeeds(HashSet<string>? feedsFromNu
313305 /// Populates dependencies with the relevant dependencies from the assets files generated by the restore.
314306 /// Returns a list of projects that are up to date with respect to restore.
315307 /// </summary>
316- private IEnumerable < string > RestoreSolutions ( string ? nugetSources , out DependencyContainer dependencies )
308+ private IEnumerable < string > RestoreSolutions ( HashSet < string > reachableFeeds , out DependencyContainer dependencies )
317309 {
318310 var successCount = 0 ;
319311 var nugetSourceFailures = 0 ;
@@ -326,6 +318,7 @@ private IEnumerable<string> RestoreSolutions(string? nugetSources, out Dependenc
326318 var projects = fileProvider . Solutions . SelectMany ( solution =>
327319 {
328320 logger . LogInfo ( $ "Restoring solution { solution } ...") ;
321+ var nugetSources = MakeRestoreSourcesArgument ( solution , reachableFeeds ) ;
329322 var res = dotnet . Restore ( new ( solution , PackageDirectory . DirInfo . FullName , ForceDotnetRefAssemblyFetching : true , NugetSources : nugetSources , TargetWindows : isWindows ) ) ;
330323 if ( res . Success )
331324 {
@@ -350,7 +343,7 @@ private IEnumerable<string> RestoreSolutions(string? nugetSources, out Dependenc
350343 return projects ;
351344 }
352345
353- private string ? MakeRestoreSourcesArgument ( IEnumerable < string > feeds )
346+ private string FeedsToRestoreArgument ( IEnumerable < string > feeds )
354347 {
355348 // If there are no feeds, we want to override any default feeds that `dotnet restore` would use by passing a dummy source argument.
356349 if ( ! feeds . Any ( ) )
@@ -369,14 +362,46 @@ private IEnumerable<string> RestoreSolutions(string? nugetSources, out Dependenc
369362 return feedArgs . ToString ( ) ;
370363 }
371364
365+ /// <summary>
366+ /// Constructs the list of NuGet sources to use for this restore.
367+ // (1) Use the feeds we get from `dotnet nuget list source`
368+ // (2) Use private registries, if they are configured
369+ /// </summary>
370+ /// <param name="path">Path to project/solution</param>
371+ /// <param name="reachableFeeds">The set of reachable NuGet feeds.</param>
372+ /// <returns>A string representing the NuGet sources argument for the restore command.</returns>
373+ private string ? MakeRestoreSourcesArgument ( string path , HashSet < string > reachableFeeds )
374+ {
375+ // Do not construct an set of explicit NuGet sources to use for restore.
376+ if ( ! CheckNugetFeedResponsiveness && ! HasPrivateRegistryFeeds )
377+ {
378+ return null ;
379+ }
380+
381+ // Find the path specific feeds.
382+ var folder = GetDirectoryName ( path ) ;
383+ var feedsToConsider = folder is not null ? GetFeeds ( ( ) => dotnet . GetNugetFeedsFromFolder ( folder ) ) . ToHashSet ( ) : [ ] ;
384+
385+ if ( HasPrivateRegistryFeeds )
386+ {
387+ feedsToConsider . UnionWith ( PrivateRegistryFeeds ) ;
388+ }
389+
390+ var feedsToUse = CheckNugetFeedResponsiveness
391+ ? feedsToConsider . Where ( reachableFeeds . Contains )
392+ : feedsToConsider ;
393+
394+ return FeedsToRestoreArgument ( feedsToUse ) ;
395+ }
396+
372397 /// <summary>
373398 /// Executes `dotnet restore` on all projects in projects.
374399 /// This is done in parallel for performance reasons.
375400 /// Populates dependencies with the relative paths to the assets files generated by the restore.
376401 /// </summary>
377402 /// <param name="projects">A list of paths to project files.</param>
378- /// <param name="explicitRestoreSources ">The explicit restore sources argument .</param>
379- private void RestoreProjects ( IEnumerable < string > projects , string ? explicitRestoreSources , out ConcurrentBag < DependencyContainer > dependencies )
403+ /// <param name="reachableFeeds ">The set of reachable NuGet feeds .</param>
404+ private void RestoreProjects ( IEnumerable < string > projects , HashSet < string > reachableFeeds , out ConcurrentBag < DependencyContainer > dependencies )
380405 {
381406 var successCount = 0 ;
382407 var nugetSourceFailures = 0 ;
@@ -393,7 +418,8 @@ private void RestoreProjects(IEnumerable<string> projects, string? explicitResto
393418 foreach ( var project in projectGroup )
394419 {
395420 logger . LogInfo ( $ "Restoring project { project } ...") ;
396- var res = dotnet . Restore ( new ( project , PackageDirectory . DirInfo . FullName , ForceDotnetRefAssemblyFetching : true , NugetSources : explicitRestoreSources , TargetWindows : isWindows ) ) ;
421+ var nugetSources = MakeRestoreSourcesArgument ( project , reachableFeeds ) ;
422+ var res = dotnet . Restore ( new ( project , PackageDirectory . DirInfo . FullName , ForceDotnetRefAssemblyFetching : true , NugetSources : nugetSources , TargetWindows : isWindows ) ) ;
397423 assets . AddDependenciesRange ( res . AssetsFilePaths ) ;
398424 lock ( sync )
399425 {
@@ -898,6 +924,19 @@ private IEnumerable<string> GetFeeds(Func<IList<string>> getNugetFeeds)
898924 }
899925 }
900926
927+ private string ? GetDirectoryName ( string path )
928+ {
929+ try
930+ {
931+ return new FileInfo ( path ) . Directory ? . FullName ;
932+ }
933+ catch ( Exception exc )
934+ {
935+ logger . LogWarning ( $ "Failed to get directory of '{ path } ': { exc } ") ;
936+ }
937+ return null ;
938+ }
939+
901940 private ( HashSet < string > explicitFeeds , HashSet < string > allFeeds ) GetAllFeeds ( )
902941 {
903942 var nugetConfigs = fileProvider . NugetConfigs ;
@@ -968,18 +1007,7 @@ private IEnumerable<string> GetFeeds(Func<IList<string>> getNugetFeeds)
9681007 {
9691008 // We don't have to get the feeds from each of the folders from below, it would be enought to check the folders that recursively contain the others.
9701009 var nugetConfigFeeds = nugetConfigs
971- . Select ( config =>
972- {
973- try
974- {
975- return new FileInfo ( config ) . Directory ? . FullName ;
976- }
977- catch ( Exception exc )
978- {
979- logger . LogWarning ( $ "Failed to get directory of '{ config } ': { exc } ") ;
980- }
981- return null ;
982- } )
1010+ . Select ( GetDirectoryName )
9831011 . Where ( folder => folder != null )
9841012 . SelectMany ( folder => GetFeeds ( ( ) => dotnet . GetNugetFeedsFromFolder ( folder ! ) ) )
9851013 . ToHashSet ( ) ;
0 commit comments