@@ -18,19 +18,22 @@ internal sealed class AddCommand : BaseCommand
18
18
private readonly INuGetPackageCache _nuGetPackageCache ;
19
19
private readonly IInteractionService _interactionService ;
20
20
private readonly IProjectLocator _projectLocator ;
21
+ private readonly IAddCommandPrompter _prompter ;
21
22
22
- public AddCommand ( IDotNetCliRunner runner , INuGetPackageCache nuGetPackageCache , IInteractionService interactionService , IProjectLocator projectLocator )
23
+ public AddCommand ( IDotNetCliRunner runner , INuGetPackageCache nuGetPackageCache , IInteractionService interactionService , IProjectLocator projectLocator , IAddCommandPrompter prompter )
23
24
: base ( "add" , "Add an integration to the Aspire project." )
24
25
{
25
26
ArgumentNullException . ThrowIfNull ( runner ) ;
26
27
ArgumentNullException . ThrowIfNull ( nuGetPackageCache ) ;
27
28
ArgumentNullException . ThrowIfNull ( interactionService ) ;
28
29
ArgumentNullException . ThrowIfNull ( projectLocator ) ;
29
-
30
+ ArgumentNullException . ThrowIfNull ( prompter ) ;
31
+
30
32
_runner = runner ;
31
33
_nuGetPackageCache = nuGetPackageCache ;
32
34
_interactionService = interactionService ;
33
35
_projectLocator = projectLocator ;
36
+ _prompter = prompter ;
34
37
35
38
var integrationArgument = new Argument < string > ( "integration" ) ;
36
39
integrationArgument . Description = "The name of the integration to add (e.g. redis, postgres)." ;
@@ -170,23 +173,11 @@ protected override async Task<int> ExecuteAsync(ParseResult parseResult, Cancell
170
173
{
171
174
var distinctPackages = possiblePackages . DistinctBy ( p => p . Package . Id ) ;
172
175
173
- var packagePrompt = new SelectionPrompt < ( string FriendlyName , NuGetPackage Package ) > ( )
174
- . Title ( "Select an integration to add:" )
175
- . UseConverter ( PackageNameWithFriendlyNameIfAvailable )
176
- . PageSize ( 10 )
177
- . EnableSearch ( )
178
- . HighlightStyle ( Style . Parse ( "darkmagenta" ) )
179
- . AddChoices ( distinctPackages ) ;
180
-
181
176
// If there is only one package, we can skip the prompt and just use it.
182
177
var selectedPackage = distinctPackages . Count ( ) switch
183
178
{
184
179
1 => distinctPackages . First ( ) ,
185
- > 1 => await _interactionService . PromptForSelectionAsync (
186
- "Select an integration to add:" ,
187
- distinctPackages ,
188
- PackageNameWithFriendlyNameIfAvailable ,
189
- cancellationToken ) ,
180
+ > 1 => await _prompter . PromptForIntegrationAsync ( distinctPackages , cancellationToken ) ,
190
181
_ => throw new InvalidOperationException ( "Unexpected number of packages found." )
191
182
} ;
192
183
@@ -201,25 +192,9 @@ protected override async Task<int> ExecuteAsync(ParseResult parseResult, Cancell
201
192
}
202
193
203
194
// ... otherwise we had better prompt.
204
- var version = await _interactionService . PromptForSelectionAsync (
205
- $ "Select a version of the { selectedPackage . Package . Id } :",
206
- packageVersions ,
207
- p => p . Package . Version ,
208
- cancellationToken ) ;
195
+ var version = await _prompter . PromptForIntegrationVersionAsync ( packageVersions , cancellationToken ) ;
209
196
210
197
return version ;
211
-
212
- static string PackageNameWithFriendlyNameIfAvailable ( ( string FriendlyName , NuGetPackage Package ) packageWithFriendlyName )
213
- {
214
- if ( packageWithFriendlyName . FriendlyName is { } friendlyName )
215
- {
216
- return $ "[bold]{ friendlyName } [/] ({ packageWithFriendlyName . Package . Id } )";
217
- }
218
- else
219
- {
220
- return packageWithFriendlyName . Package . Id ;
221
- }
222
- }
223
198
}
224
199
225
200
private static ( string FriendlyName , NuGetPackage Package ) GenerateFriendlyName ( NuGetPackage package )
@@ -244,3 +219,45 @@ private static (string FriendlyName, NuGetPackage Package) GenerateFriendlyName(
244
219
return ( shortNameBuilder . ToString ( ) , package ) ;
245
220
}
246
221
}
222
+
223
+ internal interface IAddCommandPrompter
224
+ {
225
+ Task < ( string FriendlyName , NuGetPackage Package ) > PromptForIntegrationAsync ( IEnumerable < ( string FriendlyName , NuGetPackage Package ) > packages , CancellationToken cancellationToken ) ;
226
+ Task < ( string FriendlyName , NuGetPackage Package ) > PromptForIntegrationVersionAsync ( IEnumerable < ( string FriendlyName , NuGetPackage Package ) > packages , CancellationToken cancellationToken ) ;
227
+ }
228
+
229
+ internal class AddCommandPrompter ( IInteractionService interactionService ) : IAddCommandPrompter
230
+ {
231
+ public virtual async Task < ( string FriendlyName , NuGetPackage Package ) > PromptForIntegrationVersionAsync ( IEnumerable < ( string FriendlyName , NuGetPackage Package ) > packages , CancellationToken cancellationToken )
232
+ {
233
+ var selectedPackage = packages . First ( ) ;
234
+ var version = await interactionService . PromptForSelectionAsync (
235
+ $ "Select a version of the { selectedPackage . Package . Id } :",
236
+ packages ,
237
+ p => p . Package . Version ,
238
+ cancellationToken ) ;
239
+ return version ;
240
+ }
241
+
242
+ public virtual async Task < ( string FriendlyName , NuGetPackage Package ) > PromptForIntegrationAsync ( IEnumerable < ( string FriendlyName , NuGetPackage Package ) > packages , CancellationToken cancellationToken )
243
+ {
244
+ var selectedIntegration = await interactionService . PromptForSelectionAsync (
245
+ "Select an integration to add:" ,
246
+ packages ,
247
+ PackageNameWithFriendlyNameIfAvailable ,
248
+ cancellationToken ) ;
249
+ return selectedIntegration ;
250
+ }
251
+
252
+ private static string PackageNameWithFriendlyNameIfAvailable ( ( string FriendlyName , NuGetPackage Package ) packageWithFriendlyName )
253
+ {
254
+ if ( packageWithFriendlyName . FriendlyName is { } friendlyName )
255
+ {
256
+ return $ "[bold]{ friendlyName } [/] ({ packageWithFriendlyName . Package . Id } )";
257
+ }
258
+ else
259
+ {
260
+ return packageWithFriendlyName . Package . Id ;
261
+ }
262
+ }
263
+ }
0 commit comments