@@ -253,160 +253,67 @@ private static async Task<int> RunRecommendAsync(string[] args)
253253
254254 private static async Task < int > RunInstallAsync ( string [ ] args )
255255 {
256- var requestedSkills = new List < string > ( ) ;
257- string ? targetPath = null ;
258- string ? cachePath = null ;
259- string ? catalogVersion = null ;
260- string ? projectDirectory = null ;
261- var installAll = false ;
262- var autoInstall = false ;
263- var pruneAutoManaged = false ;
264- var force = false ;
265- var bundledOnly = false ;
266- var refreshCatalog = false ;
267- var agent = AgentPlatform . Auto ;
268- var scope = InstallScope . Project ;
269-
270- for ( var index = 0 ; index < args . Length ; index ++ )
271- {
272- switch ( args [ index ] )
273- {
274- case "--all" :
275- installAll = true ;
276- break ;
277- case "--auto" :
278- autoInstall = true ;
279- break ;
280- case "--prune" :
281- pruneAutoManaged = true ;
282- break ;
283- case "--force" :
284- force = true ;
285- break ;
286- case "--target" :
287- targetPath = ReadValue ( args , ++ index , "--target" ) ;
288- break ;
289- case "--cache-dir" :
290- cachePath = ReadValue ( args , ++ index , "--cache-dir" ) ;
291- break ;
292- case "--catalog-version" :
293- catalogVersion = ReadValue ( args , ++ index , "--catalog-version" ) ;
294- break ;
295- case "--agent" :
296- agent = SkillInstallTarget . ParseAgent ( ReadValue ( args , ++ index , "--agent" ) ) ;
297- break ;
298- case "--scope" :
299- scope = SkillInstallTarget . ParseScope ( ReadValue ( args , ++ index , "--scope" ) ) ;
300- break ;
301- case "--project-dir" :
302- projectDirectory = ReadValue ( args , ++ index , "--project-dir" ) ;
303- break ;
304- case "--bundled" :
305- bundledOnly = true ;
306- break ;
307- case "--refresh" :
308- refreshCatalog = true ;
309- break ;
310- default :
311- requestedSkills . Add ( args [ index ] ) ;
312- break ;
313- }
314- }
315-
316- var packageMode = requestedSkills . Count > 0
317- && string . Equals ( requestedSkills [ 0 ] , "package" , StringComparison . OrdinalIgnoreCase ) ;
256+ var options = ParseInstallOptions ( args ) ;
318257
319- if ( packageMode )
320- {
321- requestedSkills . RemoveAt ( 0 ) ;
322-
323- if ( installAll )
324- {
325- throw new InvalidOperationException ( "`dotnet skills install package` requires explicit package names and does not support --all." ) ;
326- }
327-
328- if ( requestedSkills . Count == 0 )
329- {
330- throw new InvalidOperationException ( "Specify one or more package names after `dotnet skills install package`." ) ;
331- }
332- }
333-
334- if ( autoInstall )
335- {
336- if ( installAll )
337- {
338- throw new InvalidOperationException ( "`dotnet skills install --auto` scans the project and does not support --all." ) ;
339- }
340-
341- if ( packageMode || requestedSkills . Count > 0 )
342- {
343- throw new InvalidOperationException ( "`dotnet skills install --auto` does not accept explicit skill or package names." ) ;
344- }
345- }
346- else if ( pruneAutoManaged )
347- {
348- throw new InvalidOperationException ( "`--prune` is only available together with `dotnet skills install --auto`." ) ;
349- }
350-
351- if ( pruneAutoManaged && scope != InstallScope . Project )
258+ if ( options . PruneAutoManaged && options . Scope != InstallScope . Project )
352259 {
353260 throw new InvalidOperationException ( "`dotnet skills install --auto --prune` requires --scope project because global skill roots are shared across repositories." ) ;
354261 }
355262
356- await MaybeShowToolUpdateAsync ( cachePath ) ;
263+ await MaybeShowToolUpdateAsync ( options . CachePath ) ;
357264
358- var catalog = await ResolveCatalogForInstallAsync ( bundledOnly , cachePath , catalogVersion , refreshCatalog ) ;
265+ var catalog = await ResolveCatalogForInstallAsync ( options . BundledOnly , options . CachePath , options . CatalogVersion , options . RefreshCatalog ) ;
359266 var installer = new SkillInstaller ( catalog ) ;
360- if ( autoInstall )
267+ if ( options . AutoInstall )
361268 {
362269 var autoSyncService = new ProjectSkillAutoSyncService ( catalog ) ;
363270
364- if ( ShouldUseAutoDetectedLayouts ( targetPath , agent ) )
271+ if ( ShouldUseAutoDetectedLayouts ( options . TargetPath , options . Agent ) )
365272 {
366- var layouts = SkillInstallTarget . ResolveAllDetected ( projectDirectory , scope ) ;
273+ var layouts = SkillInstallTarget . ResolveAllDetected ( options . ProjectDirectory , options . Scope ) ;
367274 for ( var index = 0 ; index < layouts . Count ; index ++ )
368275 {
369276 if ( index > 0 )
370277 {
371278 Console . WriteLine ( ) ;
372279 }
373280
374- ExecuteAutoInstallIntoLayout ( catalog , installer , autoSyncService , layouts [ index ] , projectDirectory , force , pruneAutoManaged ) ;
281+ ExecuteAutoInstallIntoLayout ( catalog , installer , autoSyncService , layouts [ index ] , options . ProjectDirectory , options . Force , options . PruneAutoManaged ) ;
375282 }
376283
377284 return 0 ;
378285 }
379286
380- var autoLayout = SkillInstallTarget . Resolve ( targetPath , agent , scope , projectDirectory ) ;
381- ExecuteAutoInstallIntoLayout ( catalog , installer , autoSyncService , autoLayout , projectDirectory , force , pruneAutoManaged ) ;
287+ var autoLayout = SkillInstallTarget . Resolve ( options . TargetPath , options . Agent , options . Scope , options . ProjectDirectory ) ;
288+ ExecuteAutoInstallIntoLayout ( catalog , installer , autoSyncService , autoLayout , options . ProjectDirectory , options . Force , options . PruneAutoManaged ) ;
382289 return 0 ;
383290 }
384291
385- var selectedSkills = packageMode
386- ? installer . SelectSkillsFromPackages ( requestedSkills )
387- : installer . SelectSkills ( requestedSkills , installAll ) ;
388- if ( ShouldUseAutoDetectedLayouts ( targetPath , agent ) )
292+ var selectedSkills = options . PackageMode
293+ ? installer . SelectSkillsFromPackages ( options . RequestedSkills )
294+ : installer . SelectSkills ( options . RequestedSkills , options . InstallAll ) ;
295+ if ( ShouldUseAutoDetectedLayouts ( options . TargetPath , options . Agent ) )
389296 {
390297 var batchResults = new List < SkillInstallBatchResult > ( ) ;
391298
392- foreach ( var layout in SkillInstallTarget . ResolveAllDetected ( projectDirectory , scope ) )
299+ foreach ( var layout in SkillInstallTarget . ResolveAllDetected ( options . ProjectDirectory , options . Scope ) )
393300 {
394301 var installedBefore = installer . GetInstalledSkills ( layout )
395302 . ToDictionary ( record => record . Skill . Name , StringComparer . OrdinalIgnoreCase ) ;
396- var summary = installer . Install ( selectedSkills , layout , force ) ;
397- var rows = BuildInstallRows ( selectedSkills , installedBefore , force , summary ) ;
303+ var summary = installer . Install ( selectedSkills , layout , options . Force ) ;
304+ var rows = BuildInstallRows ( selectedSkills , installedBefore , options . Force , summary ) ;
398305 batchResults . Add ( new SkillInstallBatchResult ( layout , rows , summary ) ) ;
399306 }
400307
401308 ConsoleUi . RenderInstallSummaryMultiple ( catalog , batchResults ) ;
402309 return 0 ;
403310 }
404311
405- var singleLayout = SkillInstallTarget . Resolve ( targetPath , agent , scope , projectDirectory ) ;
312+ var singleLayout = SkillInstallTarget . Resolve ( options . TargetPath , options . Agent , options . Scope , options . ProjectDirectory ) ;
406313 var installedInSingleLayout = installer . GetInstalledSkills ( singleLayout )
407314 . ToDictionary ( record => record . Skill . Name , StringComparer . OrdinalIgnoreCase ) ;
408- var singleSummary = installer . Install ( selectedSkills , singleLayout , force ) ;
409- var singleRows = BuildInstallRows ( selectedSkills , installedInSingleLayout , force , singleSummary ) ;
315+ var singleSummary = installer . Install ( selectedSkills , singleLayout , options . Force ) ;
316+ var singleRows = BuildInstallRows ( selectedSkills , installedInSingleLayout , options . Force , singleSummary ) ;
410317
411318 ConsoleUi . RenderInstallSummary ( catalog , singleLayout , singleRows , singleSummary ) ;
412319 return 0 ;
@@ -832,6 +739,120 @@ internal static bool IsUsageStartup(string[] args) =>
832739
833740 internal static bool IsInteractiveStartup ( string [ ] args ) => args . Length == 0 ;
834741
742+ internal static InstallCommandOptions ParseInstallOptions ( string [ ] args )
743+ {
744+ var requestedSkills = new List < string > ( ) ;
745+ string ? targetPath = null ;
746+ string ? cachePath = null ;
747+ string ? catalogVersion = null ;
748+ string ? projectDirectory = null ;
749+ var installAll = false ;
750+ var autoInstall = false ;
751+ var pruneAutoManaged = false ;
752+ var force = false ;
753+ var bundledOnly = false ;
754+ var refreshCatalog = false ;
755+ var agent = AgentPlatform . Auto ;
756+ var scope = InstallScope . Project ;
757+
758+ for ( var index = 0 ; index < args . Length ; index ++ )
759+ {
760+ switch ( args [ index ] )
761+ {
762+ case "--all" :
763+ installAll = true ;
764+ break ;
765+ case "--auto" :
766+ autoInstall = true ;
767+ break ;
768+ case "--prune" :
769+ pruneAutoManaged = true ;
770+ break ;
771+ case "--force" :
772+ force = true ;
773+ break ;
774+ case "--target" :
775+ targetPath = ReadValue ( args , ++ index , "--target" ) ;
776+ break ;
777+ case "--cache-dir" :
778+ cachePath = ReadValue ( args , ++ index , "--cache-dir" ) ;
779+ break ;
780+ case "--catalog-version" :
781+ catalogVersion = ReadValue ( args , ++ index , "--catalog-version" ) ;
782+ break ;
783+ case "--agent" :
784+ agent = SkillInstallTarget . ParseAgent ( ReadValue ( args , ++ index , "--agent" ) ) ;
785+ break ;
786+ case "--scope" :
787+ scope = SkillInstallTarget . ParseScope ( ReadValue ( args , ++ index , "--scope" ) ) ;
788+ break ;
789+ case "--project-dir" :
790+ projectDirectory = ReadValue ( args , ++ index , "--project-dir" ) ;
791+ break ;
792+ case "--bundled" :
793+ bundledOnly = true ;
794+ break ;
795+ case "--refresh" :
796+ refreshCatalog = true ;
797+ break ;
798+ default :
799+ requestedSkills . Add ( args [ index ] ) ;
800+ break ;
801+ }
802+ }
803+
804+ var packageMode = requestedSkills . Count > 0
805+ && string . Equals ( requestedSkills [ 0 ] , "package" , StringComparison . OrdinalIgnoreCase ) ;
806+
807+ if ( packageMode )
808+ {
809+ requestedSkills . RemoveAt ( 0 ) ;
810+
811+ if ( installAll )
812+ {
813+ throw new InvalidOperationException ( "`dotnet skills install package` requires explicit package names and does not support --all." ) ;
814+ }
815+
816+ if ( requestedSkills . Count == 0 )
817+ {
818+ throw new InvalidOperationException ( "Specify one or more package names after `dotnet skills install package`." ) ;
819+ }
820+ }
821+
822+ if ( autoInstall )
823+ {
824+ if ( installAll )
825+ {
826+ throw new InvalidOperationException ( "`dotnet skills install --auto` scans the project and does not support --all." ) ;
827+ }
828+
829+ if ( packageMode || requestedSkills . Count > 0 )
830+ {
831+ throw new InvalidOperationException ( "`dotnet skills install --auto` does not accept explicit skill or package names." ) ;
832+ }
833+ }
834+ else if ( pruneAutoManaged )
835+ {
836+ throw new InvalidOperationException ( "`--prune` is only available together with `dotnet skills install --auto`." ) ;
837+ }
838+
839+ return new InstallCommandOptions (
840+ requestedSkills . ToArray ( ) ,
841+ targetPath ,
842+ cachePath ,
843+ catalogVersion ,
844+ projectDirectory ,
845+ installAll ,
846+ autoInstall ,
847+ pruneAutoManaged ,
848+ force ,
849+ bundledOnly ,
850+ refreshCatalog ,
851+ agent ,
852+ scope ,
853+ packageMode ) ;
854+ }
855+
835856 private static bool IsVersionCommand ( string command ) =>
836857 string . Equals ( command , "version" , StringComparison . OrdinalIgnoreCase )
837858 || string . Equals ( command , "--version" , StringComparison . OrdinalIgnoreCase ) ;
@@ -1213,3 +1234,19 @@ private static async Task<int> RunAgentWhereAsync(string[] args)
12131234 return 0 ;
12141235 }
12151236}
1237+
1238+ internal sealed record InstallCommandOptions (
1239+ IReadOnlyList < string > RequestedSkills ,
1240+ string ? TargetPath ,
1241+ string ? CachePath ,
1242+ string ? CatalogVersion ,
1243+ string ? ProjectDirectory ,
1244+ bool InstallAll ,
1245+ bool AutoInstall ,
1246+ bool PruneAutoManaged ,
1247+ bool Force ,
1248+ bool BundledOnly ,
1249+ bool RefreshCatalog ,
1250+ AgentPlatform Agent ,
1251+ InstallScope Scope ,
1252+ bool PackageMode ) ;
0 commit comments