Skip to content

Commit 9335979

Browse files
authored
feat(#105): consolidate CLI helper functions for improved command handling (#132)
- Refactor CLI command routing to throw errors for unknown commands - Enhance invocation context handling to manage CLI confirmation state - Streamline command handler retrieval and error messaging
1 parent 12cdd34 commit 9335979

3 files changed

Lines changed: 63 additions & 64 deletions

File tree

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
1-
function Get-NovaCliBaseInvocationData {
1+
function Get-NovaCliResolvedInvocationContext {
22
[CmdletBinding()]
33
param(
4+
[Parameter(Mandatory)][string]$Command,
5+
[AllowEmptyCollection()][string[]]$Arguments = @(),
46
[Parameter(Mandatory)][hashtable]$CommonParameters,
57
[Parameter(Mandatory)][hashtable]$MutatingCommonParameters,
68
[Parameter(Mandatory)][string]$ModuleName,
7-
[Parameter(Mandatory)][bool]$WhatIfEnabled
9+
[Parameter(Mandatory)][bool]$WhatIfEnabled,
10+
[Parameter(Mandatory)][bool]$CliConfirmEnabled,
11+
[AllowNull()][pscustomobject]$HelpRequest = $null
812
)
913

1014
return [pscustomobject]@{
15+
Command = $Command
16+
Arguments = @($Arguments)
1117
CommonParameters = $CommonParameters
1218
MutatingCommonParameters = $MutatingCommonParameters
19+
IsHelpRequest = $null -ne $HelpRequest
20+
HelpRequest = $HelpRequest
1321
ModuleName = $ModuleName
1422
WhatIfEnabled = $WhatIfEnabled
23+
CliConfirmEnabled = $CliConfirmEnabled
1524
}
1625
}
1726

18-
function Get-NovaCliHelpInvocationContext {
27+
function Get-NovaCliInvocationWhatIfState {
1928
[CmdletBinding()]
2029
param(
21-
[Parameter(Mandatory)][pscustomobject]$HelpRequest,
22-
[Parameter(Mandatory)][pscustomobject]$BaseInvocationData
30+
[switch]$WhatIfEnabled,
31+
[Parameter(Mandatory)][hashtable]$MutatingCommonParameters,
32+
[switch]$RoutingWhatIfEnabled
2333
)
2434

25-
return [pscustomobject]@{
26-
Command = $HelpRequest.Command
27-
Arguments = @()
28-
CommonParameters = $BaseInvocationData.CommonParameters
29-
MutatingCommonParameters = $BaseInvocationData.MutatingCommonParameters
30-
IsHelpRequest = $true
31-
HelpRequest = $HelpRequest
32-
ModuleName = $BaseInvocationData.ModuleName
33-
WhatIfEnabled = $BaseInvocationData.WhatIfEnabled
34-
CliConfirmEnabled = $false
35-
}
35+
return $WhatIfEnabled.IsPresent -or $RoutingWhatIfEnabled.IsPresent -or $MutatingCommonParameters.ContainsKey('WhatIf')
3636
}
3737

38-
function Get-NovaCliConfirmState {
38+
function Get-NovaCliInvocationConfirmState {
3939
[CmdletBinding()]
4040
param(
4141
[Parameter(Mandatory)][hashtable]$MutatingCommonParameters
@@ -50,27 +50,6 @@ function Get-NovaCliConfirmState {
5050
return $cliConfirmEnabled
5151
}
5252

53-
function Get-NovaCliRoutedInvocationContext {
54-
[CmdletBinding()]
55-
param(
56-
[Parameter(Mandatory)][pscustomobject]$RoutingState,
57-
[Parameter(Mandatory)][pscustomobject]$BaseInvocationData,
58-
[Parameter(Mandatory)][bool]$CliConfirmEnabled
59-
)
60-
61-
return [pscustomobject]@{
62-
Command = $RoutingState.Command
63-
Arguments = $RoutingState.Arguments
64-
CommonParameters = $BaseInvocationData.CommonParameters
65-
MutatingCommonParameters = $BaseInvocationData.MutatingCommonParameters
66-
IsHelpRequest = $false
67-
HelpRequest = $null
68-
ModuleName = $BaseInvocationData.ModuleName
69-
WhatIfEnabled = $BaseInvocationData.WhatIfEnabled
70-
CliConfirmEnabled = $CliConfirmEnabled
71-
}
72-
}
73-
7453
function Get-NovaCliInvocationContext {
7554
[CmdletBinding()]
7655
param(
@@ -85,22 +64,22 @@ function Get-NovaCliInvocationContext {
8564
Assert-NovaCliArgumentSyntax -Arguments (@($InvocationRequest.Command) + $normalizedArguments)
8665
$helpRequest = Get-NovaCliHelpRequest -Command $InvocationRequest.Command -Arguments $normalizedArguments
8766
$moduleName = $ExecutionContext.SessionState.Module.Name
88-
$helpBaseInvocationData = Get-NovaCliBaseInvocationData -CommonParameters $commonParameters -MutatingCommonParameters $mutatingCommonParameters -ModuleName $moduleName -WhatIfEnabled:($WhatIfEnabled.IsPresent -or $mutatingCommonParameters.ContainsKey('WhatIf'))
67+
$whatIfState = Get-NovaCliInvocationWhatIfState -WhatIfEnabled:$WhatIfEnabled -MutatingCommonParameters $mutatingCommonParameters
8968

9069
if ($null -ne $helpRequest) {
91-
return Get-NovaCliHelpInvocationContext -HelpRequest $helpRequest -BaseInvocationData $helpBaseInvocationData
70+
return Get-NovaCliResolvedInvocationContext -Command $helpRequest.Command -Arguments @() -CommonParameters $commonParameters -MutatingCommonParameters $mutatingCommonParameters -ModuleName $moduleName -WhatIfEnabled:$whatIfState -CliConfirmEnabled:$false -HelpRequest $helpRequest
9271
}
9372

9473
$routingState = Get-NovaCliArgumentRoutingState -Command $InvocationRequest.Command -Arguments $normalizedArguments
95-
$cliConfirmEnabled = Get-NovaCliConfirmState -MutatingCommonParameters $mutatingCommonParameters
74+
$cliConfirmEnabled = Get-NovaCliInvocationConfirmState -MutatingCommonParameters $mutatingCommonParameters
9675

9776
if ( $routingState.ForwardedParameters.ContainsKey('Verbose')) {
9877
$commonParameters.Verbose = $true
9978
}
10079

10180
$mutatingCommonParameters = Merge-NovaCliParameterSet -BaseParameters $mutatingCommonParameters -AdditionalParameters $routingState.ForwardedParameters
10281
$cliConfirmEnabled = $cliConfirmEnabled -or $routingState.CliConfirmEnabled
103-
$routedBaseInvocationData = Get-NovaCliBaseInvocationData -CommonParameters $commonParameters -MutatingCommonParameters $mutatingCommonParameters -ModuleName $moduleName -WhatIfEnabled:($WhatIfEnabled.IsPresent -or $routingState.WhatIfEnabled -or $mutatingCommonParameters.ContainsKey('WhatIf'))
82+
$whatIfState = Get-NovaCliInvocationWhatIfState -WhatIfEnabled:$WhatIfEnabled -MutatingCommonParameters $mutatingCommonParameters -RoutingWhatIfEnabled:$routingState.WhatIfEnabled
10483

105-
return Get-NovaCliRoutedInvocationContext -RoutingState $routingState -BaseInvocationData $routedBaseInvocationData -CliConfirmEnabled:$cliConfirmEnabled
84+
return Get-NovaCliResolvedInvocationContext -Command $routingState.Command -Arguments $routingState.Arguments -CommonParameters $commonParameters -MutatingCommonParameters $mutatingCommonParameters -ModuleName $moduleName -WhatIfEnabled:$whatIfState -CliConfirmEnabled:$cliConfirmEnabled
10685
}

src/private/cli/InvokeNovaCliCommandRoute.ps1

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
1-
function Get-NovaCliCommandHandler {
2-
[CmdletBinding()]
3-
param(
4-
[Parameter(Mandatory)][hashtable]$CommandHandlerMap,
5-
[Parameter(Mandatory)][string]$Command
6-
)
7-
8-
$commandHandler = $CommandHandlerMap[$Command]
9-
if ($null -eq $commandHandler) {
10-
Stop-NovaOperation -Message "Unknown command: <$Command> | Use 'nova --help' to see available commands." -ErrorId 'Nova.Validation.UnknownCliCommand' -Category InvalidArgument -TargetObject $Command
11-
}
12-
13-
return $commandHandler
14-
}
15-
161
function Confirm-NovaCliRoutedCommand {
172
[CmdletBinding()]
183
param(
@@ -156,7 +141,7 @@ function Invoke-NovaCliCommandRoute {
156141
return Get-NovaCliHelp
157142
}
158143
default {
159-
return Get-NovaCliCommandHandler -CommandHandlerMap @{} -Command $command
144+
Stop-NovaOperation -Message "Unknown command: <$command> | Use 'nova --help' to see available commands." -ErrorId 'Nova.Validation.UnknownCliCommand' -Category InvalidArgument -TargetObject $command
160145
}
161146
}
162147
}

tests/CoverageGaps.Cli.Tests.ps1

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ Describe 'Coverage gaps for CLI and installed-version internals' {
115115
}
116116
ModuleName = 'NovaModuleTools'
117117
WhatIfEnabled = $false
118+
CliConfirmEnabled = $false
118119
}
119120
Mock Get-NovaCliCommandHelp {'package-help'}
120121

@@ -212,14 +213,33 @@ Describe 'Coverage gaps for CLI and installed-version internals' {
212213
}
213214
}
214215

215-
It 'Get-NovaCliCommandHandler returns the mapped handler for a known command' {
216+
It 'Invoke-NovaCliCommandRoute throws the stable unknown-command error for unmapped commands' {
216217
InModuleScope $script:moduleName {
217-
$expectedHandler = [pscustomobject]@{Name = 'publish-handler'}
218-
$handlerMap = @{publish = $expectedHandler}
218+
$invocationContext = [pscustomobject]@{
219+
Command = 'banana'
220+
Arguments = @()
221+
CommonParameters = @{}
222+
MutatingCommonParameters = @{}
223+
IsHelpRequest = $false
224+
HelpRequest = $null
225+
ModuleName = 'NovaModuleTools'
226+
WhatIfEnabled = $false
227+
CliConfirmEnabled = $false
228+
}
219229

220-
$result = Get-NovaCliCommandHandler -CommandHandlerMap $handlerMap -Command 'publish'
230+
$thrown = $null
231+
try {
232+
Invoke-NovaCliCommandRoute -InvocationContext $invocationContext
233+
}
234+
catch {
235+
$thrown = $_
236+
}
221237

222-
$result | Should -Be $expectedHandler
238+
$thrown | Should -Not -BeNullOrEmpty
239+
$thrown.Exception.Message | Should -Be "Unknown command: <banana> | Use 'nova --help' to see available commands."
240+
$thrown.FullyQualifiedErrorId | Should -Be 'Nova.Validation.UnknownCliCommand'
241+
$thrown.CategoryInfo.Category | Should -Be ([System.Management.Automation.ErrorCategory]::InvalidArgument)
242+
$thrown.TargetObject | Should -Be 'banana'
223243
}
224244
}
225245

@@ -293,6 +313,21 @@ Describe 'Coverage gaps for CLI and installed-version internals' {
293313
}
294314
}
295315

316+
It 'Get-NovaCliInvocationContext strips raw Confirm from mutating parameters while preserving CLI confirm intent' {
317+
InModuleScope $script:moduleName {
318+
$invocationRequest = [pscustomobject]@{
319+
Command = 'publish'
320+
BoundParameters = @{Command = 'publish'; Arguments = @('--confirm'); Confirm = $true}
321+
Arguments = @('--confirm')
322+
}
323+
$result = Get-NovaCliInvocationContext -InvocationRequest $invocationRequest
324+
325+
$result.Command | Should -Be 'publish'
326+
$result.CliConfirmEnabled | Should -BeTrue
327+
$result.MutatingCommonParameters.ContainsKey('Confirm') | Should -BeFalse
328+
}
329+
}
330+
296331
It 'Get-NovaCliArgumentRoutingState enables CLI confirmation only for supported mutating commands' {
297332
InModuleScope $script:moduleName {
298333
$supportedCommandList = @('build', 'test', 'package', 'deploy', 'bump', 'update', 'notification', 'publish', 'release')

0 commit comments

Comments
 (0)