11using System ;
2+ using System . Collections . Concurrent ;
23using System . Collections . Generic ;
34using System . IO ;
45using System . Linq ;
@@ -144,11 +145,11 @@ public HashSet<AssemblyLookupLocation> Restore()
144145 logger . LogError ( $ "Failed to restore Nuget packages with nuget.exe: { exc . Message } ") ;
145146 }
146147
147- var restoredProjects = RestoreSolutions ( out var assets1 ) ;
148+ var restoredProjects = RestoreSolutions ( out var container ) ;
148149 var projects = fileProvider . Projects . Except ( restoredProjects ) ;
149- RestoreProjects ( projects , out var assets2 ) ;
150+ RestoreProjects ( projects , out var containers ) ;
150151
151- var dependencies = Assets . GetCompilationDependencies ( logger , assets1 . Union ( assets2 ) ) ;
152+ var dependencies = containers . Flatten ( container ) ;
152153
153154 var paths = dependencies
154155 . Paths
@@ -198,14 +199,14 @@ private List<string> GetReachableFallbackNugetFeeds()
198199 /// As opposed to RestoreProjects this is not run in parallel using PLINQ
199200 /// as `dotnet restore` on a solution already uses multiple threads for restoring
200201 /// the projects (this can be disabled with the `--disable-parallel` flag).
201- /// Populates assets with the relative paths to the assets files generated by the restore.
202+ /// Populates dependencies with the relevant dependencies from the assets files generated by the restore.
202203 /// Returns a list of projects that are up to date with respect to restore.
203204 /// </summary>
204- private IEnumerable < string > RestoreSolutions ( out IEnumerable < string > assets )
205+ private IEnumerable < string > RestoreSolutions ( out DependencyContainer dependencies )
205206 {
206207 var successCount = 0 ;
207208 var nugetSourceFailures = 0 ;
208- var assetFiles = new List < string > ( ) ;
209+ var assets = new Assets ( logger ) ;
209210 var projects = fileProvider . Solutions . SelectMany ( solution =>
210211 {
211212 logger . LogInfo ( $ "Restoring solution { solution } ...") ;
@@ -218,10 +219,10 @@ private IEnumerable<string> RestoreSolutions(out IEnumerable<string> assets)
218219 {
219220 nugetSourceFailures ++ ;
220221 }
221- assetFiles . AddRange ( res . AssetsFilePaths ) ;
222+ assets . AddDependenciesRange ( res . AssetsFilePaths ) ;
222223 return res . RestoredProjects ;
223224 } ) . ToList ( ) ;
224- assets = assetFiles ;
225+ dependencies = assets . Dependencies ;
225226 compilationInfoContainer . CompilationInfos . Add ( ( "Successfully restored solution files" , successCount . ToString ( ) ) ) ;
226227 compilationInfoContainer . CompilationInfos . Add ( ( "Failed solution restore with package source error" , nugetSourceFailures . ToString ( ) ) ) ;
227228 compilationInfoContainer . CompilationInfos . Add ( ( "Restored projects through solution files" , projects . Count . ToString ( ) ) ) ;
@@ -231,33 +232,39 @@ private IEnumerable<string> RestoreSolutions(out IEnumerable<string> assets)
231232 /// <summary>
232233 /// Executes `dotnet restore` on all projects in projects.
233234 /// This is done in parallel for performance reasons.
234- /// Populates assets with the relative paths to the assets files generated by the restore.
235+ /// Populates dependencies with the relative paths to the assets files generated by the restore.
235236 /// </summary>
236237 /// <param name="projects">A list of paths to project files.</param>
237- private void RestoreProjects ( IEnumerable < string > projects , out IEnumerable < string > assets )
238+ private void RestoreProjects ( IEnumerable < string > projects , out ConcurrentBag < DependencyContainer > dependencies )
238239 {
239240 var successCount = 0 ;
240241 var nugetSourceFailures = 0 ;
241- var assetFiles = new List < string > ( ) ;
242+ ConcurrentBag < DependencyContainer > collectedDependencies = [ ] ;
242243 var sync = new object ( ) ;
243- Parallel . ForEach ( projects , new ParallelOptions { MaxDegreeOfParallelism = DependencyManager . Threads } , project =>
244+ var projectGroups = projects . GroupBy ( Path . GetDirectoryName ) ;
245+ Parallel . ForEach ( projectGroups , new ParallelOptions { MaxDegreeOfParallelism = DependencyManager . Threads } , projectGroup =>
244246 {
245- logger . LogInfo ( $ "Restoring project { project } ...") ;
246- var res = dotnet . Restore ( new ( project , PackageDirectory . DirInfo . FullName , ForceDotnetRefAssemblyFetching : true ) ) ;
247- lock ( sync )
247+ var assets = new Assets ( logger ) ;
248+ foreach ( var project in projectGroup )
248249 {
249- if ( res . Success )
250+ logger . LogInfo ( $ "Restoring project { project } ...") ;
251+ var res = dotnet . Restore ( new ( project , PackageDirectory . DirInfo . FullName , ForceDotnetRefAssemblyFetching : true ) ) ;
252+ assets . AddDependenciesRange ( res . AssetsFilePaths ) ;
253+ lock ( sync )
250254 {
251- successCount ++ ;
252- }
253- if ( res . HasNugetPackageSourceError )
254- {
255- nugetSourceFailures ++ ;
255+ if ( res . Success )
256+ {
257+ successCount ++ ;
258+ }
259+ if ( res . HasNugetPackageSourceError )
260+ {
261+ nugetSourceFailures ++ ;
262+ }
256263 }
257- assetFiles . AddRange ( res . AssetsFilePaths ) ;
258264 }
265+ collectedDependencies . Add ( assets . Dependencies ) ;
259266 } ) ;
260- assets = assetFiles ;
267+ dependencies = collectedDependencies ;
261268 compilationInfoContainer . CompilationInfos . Add ( ( "Successfully restored project files" , successCount . ToString ( ) ) ) ;
262269 compilationInfoContainer . CompilationInfos . Add ( ( "Failed project restore with package source error" , nugetSourceFailures . ToString ( ) ) ) ;
263270 }
0 commit comments