1
1
using System ;
2
+ using System . Collections . Concurrent ;
2
3
using System . Collections . Generic ;
3
4
using System . IO ;
4
5
using System . Linq ;
@@ -144,11 +145,11 @@ public HashSet<AssemblyLookupLocation> Restore()
144
145
logger . LogError ( $ "Failed to restore Nuget packages with nuget.exe: { exc . Message } ") ;
145
146
}
146
147
147
- var restoredProjects = RestoreSolutions ( out var assets1 ) ;
148
+ var restoredProjects = RestoreSolutions ( out var container ) ;
148
149
var projects = fileProvider . Projects . Except ( restoredProjects ) ;
149
- RestoreProjects ( projects , out var assets2 ) ;
150
+ RestoreProjects ( projects , out var containers ) ;
150
151
151
- var dependencies = Assets . GetCompilationDependencies ( logger , assets1 . Union ( assets2 ) ) ;
152
+ var dependencies = containers . Flatten ( container ) ;
152
153
153
154
var paths = dependencies
154
155
. Paths
@@ -198,14 +199,14 @@ private List<string> GetReachableFallbackNugetFeeds()
198
199
/// As opposed to RestoreProjects this is not run in parallel using PLINQ
199
200
/// as `dotnet restore` on a solution already uses multiple threads for restoring
200
201
/// 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.
202
203
/// Returns a list of projects that are up to date with respect to restore.
203
204
/// </summary>
204
- private IEnumerable < string > RestoreSolutions ( out IEnumerable < string > assets )
205
+ private IEnumerable < string > RestoreSolutions ( out DependencyContainer dependencies )
205
206
{
206
207
var successCount = 0 ;
207
208
var nugetSourceFailures = 0 ;
208
- var assetFiles = new List < string > ( ) ;
209
+ var assets = new Assets ( logger ) ;
209
210
var projects = fileProvider . Solutions . SelectMany ( solution =>
210
211
{
211
212
logger . LogInfo ( $ "Restoring solution { solution } ...") ;
@@ -218,10 +219,10 @@ private IEnumerable<string> RestoreSolutions(out IEnumerable<string> assets)
218
219
{
219
220
nugetSourceFailures ++ ;
220
221
}
221
- assetFiles . AddRange ( res . AssetsFilePaths ) ;
222
+ assets . AddDependenciesRange ( res . AssetsFilePaths ) ;
222
223
return res . RestoredProjects ;
223
224
} ) . ToList ( ) ;
224
- assets = assetFiles ;
225
+ dependencies = assets . Dependencies ;
225
226
compilationInfoContainer . CompilationInfos . Add ( ( "Successfully restored solution files" , successCount . ToString ( ) ) ) ;
226
227
compilationInfoContainer . CompilationInfos . Add ( ( "Failed solution restore with package source error" , nugetSourceFailures . ToString ( ) ) ) ;
227
228
compilationInfoContainer . CompilationInfos . Add ( ( "Restored projects through solution files" , projects . Count . ToString ( ) ) ) ;
@@ -231,33 +232,39 @@ private IEnumerable<string> RestoreSolutions(out IEnumerable<string> assets)
231
232
/// <summary>
232
233
/// Executes `dotnet restore` on all projects in projects.
233
234
/// 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.
235
236
/// </summary>
236
237
/// <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 )
238
239
{
239
240
var successCount = 0 ;
240
241
var nugetSourceFailures = 0 ;
241
- var assetFiles = new List < string > ( ) ;
242
+ ConcurrentBag < DependencyContainer > collectedDependencies = [ ] ;
242
243
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 =>
244
246
{
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 )
248
249
{
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 )
250
254
{
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
+ }
256
263
}
257
- assetFiles . AddRange ( res . AssetsFilePaths ) ;
258
264
}
265
+ collectedDependencies . Add ( assets . Dependencies ) ;
259
266
} ) ;
260
- assets = assetFiles ;
267
+ dependencies = collectedDependencies ;
261
268
compilationInfoContainer . CompilationInfos . Add ( ( "Successfully restored project files" , successCount . ToString ( ) ) ) ;
262
269
compilationInfoContainer . CompilationInfos . Add ( ( "Failed project restore with package source error" , nugetSourceFailures . ToString ( ) ) ) ;
263
270
}
0 commit comments