1- using System . Collections . Generic ;
1+ using System ;
2+ using System . Collections . Generic ;
23using System . IO ;
34using System . Linq ;
45using System . Threading . Tasks ;
@@ -66,13 +67,13 @@ public async Task SwitchToNightlyPreview(CommandLineArgs commandLineArgs)
6667
6768 if ( solutionPaths . Any ( ) )
6869 {
69- await SwitchSolutionsToNightlyPreview ( solutionPaths ) ;
70+ await SwitchSolutionsToNightlyPreview ( solutionPaths , commandLineArgs ) ;
7071 }
7172 else
7273 {
7374 var projectPaths = GetProjectPaths ( commandLineArgs ) ;
74-
75- await SwitchProjectsToNightlyPreview ( projectPaths ) ;
75+
76+ await SwitchProjectsToNightlyPreview ( projectPaths , commandLineArgs ) ;
7677 }
7778 }
7879
@@ -185,13 +186,16 @@ await _npmPackagesUpdater.Update(
185186 }
186187 }
187188
188- private async Task SwitchProjectsToNightlyPreview ( List < string > projects )
189+ private async Task SwitchProjectsToNightlyPreview ( List < string > projects , CommandLineArgs commandLineArgs )
189190 {
191+ var ( includeFiles , excludedPackages , latestVersionFromMyGet ) = await ResolveNightlyIncludeContextAsync ( commandLineArgs ) ;
192+
190193 foreach ( var project in projects )
191194 {
192195 var folder = Path . GetDirectoryName ( project ) ;
196+ var projectFolder = FindSolutionFolder ( project ) ?? folder ;
193197
194- _packageSourceManager . Add ( FindSolutionFolder ( project ) ?? folder , "ABP Nightly" ,
198+ _packageSourceManager . Add ( projectFolder , "ABP Nightly" ,
195199 "https://www.myget.org/F/abp-nightly/api/v3/index.json" , "Volo.*" ) ;
196200
197201 await _nugetPackagesVersionUpdater . UpdateSolutionAsync (
@@ -201,11 +205,17 @@ await _nugetPackagesVersionUpdater.UpdateSolutionAsync(
201205 await _npmPackagesUpdater . Update (
202206 folder ,
203207 true ) ;
208+
209+ // See SwitchSolutionsToNightlyPreview for the race-avoidance rationale: this
210+ // sequential pass always runs after the per-project UpdateSolutionAsync above.
211+ await UpdateIncludedCentralPackageFilesAsync ( includeFiles , excludedPackages , latestVersionFromMyGet , projectFolder ) ;
204212 }
205213 }
206214
207- private async Task SwitchSolutionsToNightlyPreview ( List < string > solutionPaths )
215+ private async Task SwitchSolutionsToNightlyPreview ( List < string > solutionPaths , CommandLineArgs commandLineArgs )
208216 {
217+ var ( includeFiles , excludedPackages , latestVersionFromMyGet ) = await ResolveNightlyIncludeContextAsync ( commandLineArgs ) ;
218+
209219 foreach ( var solutionPath in solutionPaths )
210220 {
211221 var solutionFolder = Path . GetDirectoryName ( solutionPath ) ;
@@ -232,6 +242,67 @@ await _npmPackagesUpdater.Update(
232242 solutionAngularFolder ,
233243 true ) ;
234244 }
245+
246+ // Optional Central Package Management support: only runs when --include is
247+ // explicitly passed, and only after UpdateSolutionAsync's internal parallel
248+ // (Task.WaitAll) per-project update has fully completed, so no --include file
249+ // is ever touched concurrently with anything else.
250+ await UpdateIncludedCentralPackageFilesAsync ( includeFiles , excludedPackages , latestVersionFromMyGet , solutionFolder ) ;
251+ }
252+ }
253+
254+ private async Task < ( List < string > IncludeFiles , List < string > ExcludedPackages , string LatestVersionFromMyGet ) > ResolveNightlyIncludeContextAsync (
255+ CommandLineArgs commandLineArgs )
256+ {
257+ var includeFiles = GetCommaSeparatedOption ( commandLineArgs , Options . Include . Short , Options . Include . Long ) ;
258+ var excludedPackages = GetCommaSeparatedOption ( commandLineArgs , Options . Exclude . Short , Options . Exclude . Long ) ;
259+
260+ if ( ! includeFiles . Any ( ) )
261+ {
262+ return ( includeFiles , excludedPackages , null ) ;
263+ }
264+
265+ string latestVersionFromMyGet ;
266+ try
267+ {
268+ latestVersionFromMyGet = await _nugetPackagesVersionUpdater . GetLatestVersionFromMyGet ( "Volo.Abp.Core" ) ;
269+ }
270+ catch ( Exception ex )
271+ {
272+ // Don't let a transient MyGet failure abort the whole switch-to-nightly run
273+ // (source registration / regular PackageReference updates below must still
274+ // proceed for every solution/project) - just skip the --include pass.
275+ Logger . LogWarning ( ex , "Could not resolve the latest Volo.Abp.Core nightly version; --include files will be skipped for this run." ) ;
276+ return ( includeFiles , excludedPackages , null ) ;
277+ }
278+
279+ if ( latestVersionFromMyGet . IsNullOrWhiteSpace ( ) )
280+ {
281+ // No exception was thrown, but MyGet simply has no version for this package yet
282+ // (e.g. not indexed there) - warn so users aren't left wondering why --include did nothing.
283+ Logger . LogWarning ( "Could not resolve the latest Volo.Abp.Core nightly version; --include files will be skipped for this run." ) ;
284+ return ( includeFiles , excludedPackages , null ) ;
285+ }
286+
287+ return ( includeFiles , excludedPackages , latestVersionFromMyGet ) ;
288+ }
289+
290+ private async Task UpdateIncludedCentralPackageFilesAsync (
291+ List < string > includeFiles ,
292+ List < string > excludedPackages ,
293+ string latestVersionFromMyGet ,
294+ string baseFolder )
295+ {
296+ foreach ( var includeFile in includeFiles )
297+ {
298+ var resolvedPath = Path . IsPathRooted ( includeFile )
299+ ? includeFile
300+ : Path . Combine ( baseFolder , includeFile ) ;
301+
302+ await _nugetPackagesVersionUpdater . UpdateCentralPackageVersionsAsync (
303+ resolvedPath ,
304+ latestVersionFromMyGet ,
305+ excludedPackages ) ;
235306 }
236307 }
237308
@@ -285,6 +356,14 @@ private string GetDirectory(CommandLineArgs commandLineArgs)
285356 ?? Directory . GetCurrentDirectory ( ) ;
286357 }
287358
359+ private List < string > GetCommaSeparatedOption ( CommandLineArgs commandLineArgs , string shortName , string longName )
360+ {
361+ var raw = commandLineArgs . Options . GetOrNull ( shortName , longName ) ;
362+ return raw . IsNullOrWhiteSpace ( )
363+ ? new List < string > ( )
364+ : raw . Split ( ',' ) . Select ( s => s . Trim ( ) ) . Where ( s => ! s . IsNullOrWhiteSpace ( ) ) . ToList ( ) ;
365+ }
366+
288367 private string GetSolutionAngularFolder ( string solutionFolder )
289368 {
290369 var upperAngularPath = Path . Combine ( Directory . GetParent ( solutionFolder ) ? . FullName ?? "" , "angular" ) ;
@@ -340,5 +419,15 @@ public static class Directory
340419 public const string Short = "d" ;
341420 public const string Long = "directory" ;
342421 }
422+ public static class Include
423+ {
424+ public const string Short = "i" ;
425+ public const string Long = "include" ;
426+ }
427+ public static class Exclude
428+ {
429+ public const string Short = "ep" ;
430+ public const string Long = "exclude-packages" ;
431+ }
343432 }
344433}
0 commit comments