Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- CI bump now reuses the already activated built-module command when the current session is already running from
`dist/`, so publish-then-bump prerelease automation can continue in the same session without losing private helper
bindings.
- Keep standalone `nova bump` output stable by formatting version-update results in the CLI layer instead of relying on
PowerShell's default object rendering.
- `nova bump --what-if` and `% run.ps1` now surface a predictable summary for previous version, new version, label,
and commit count.

### Changed

Expand Down
53 changes: 47 additions & 6 deletions src/private/cli/FormatNovaCliCommandResult.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,61 @@ function Test-NovaCliNoUpdateResult {
return ($propertyNames -contains 'UpdateAvailable') -and ($propertyNames -contains 'CurrentVersion') -and -not $Result.UpdateAvailable
}

function Format-NovaCliCommandResult {
function Test-NovaCliVersionUpdateResult {
[CmdletBinding()]
param(
[string]$Command,
[object]$Result
)

if (-not (Test-NovaCliNoUpdateResult -Command $Command -Result $Result)) {
return $Result
if ($Command -ne 'bump' -or $null -eq $Result) {
return $false
}

$propertyNames = @($Result.PSObject.Properties.Name)
foreach ($requiredPropertyName in @('PreviousVersion', 'NewVersion', 'Label', 'CommitCount', 'Applied')) {
if ($propertyNames -notcontains $requiredPropertyName) {
return $false
}
}

return $true
}

function Format-NovaCliVersionUpdateResult {
[CmdletBinding()]
param(
[Parameter(Mandatory)][object]$Result
)

$summaryPrefix = if ($Result.Applied) {
'Version bump completed:'
}
else {
'Version plan:'
}

return "$summaryPrefix $( $Result.PreviousVersion ) -> $( $Result.NewVersion ) | Label: $( $Result.Label ) | Commits: $( $Result.CommitCount )"
}

return @(
"You're up to date!"
"$( $Result.ModuleName ) $( $Result.CurrentVersion ) is currently the newest version available."
function Format-NovaCliCommandResult {
[CmdletBinding()]
param(
[string]$Command,
[object]$Result
)

if (Test-NovaCliNoUpdateResult -Command $Command -Result $Result) {
return @(
"You're up to date!"
"$( $Result.ModuleName ) $( $Result.CurrentVersion ) is currently the newest version available."
)
}

if (Test-NovaCliVersionUpdateResult -Command $Command -Result $Result) {
return Format-NovaCliVersionUpdateResult -Result $Result
}

return $Result
}

12 changes: 11 additions & 1 deletion src/private/cli/InvokeNovaCliCommandRoute.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ function Invoke-NovaCliUpdateRouteCommand {
Format-NovaCliCommandResult -Command $InvocationContext.Command -Result $result
}

function Invoke-NovaCliBumpRouteCommand {
[CmdletBinding()]
param(
[Parameter(Mandatory)][pscustomobject]$InvocationContext
)

$result = Invoke-NovaCliParsedCommand -InvocationContext $InvocationContext -ParserCommand 'ConvertFrom-NovaBumpCliArgument' -ActionCommand 'Update-NovaModuleVersion'
return Format-NovaCliCommandResult -Command $InvocationContext.Command -Result $result
}

function Invoke-NovaCliNotificationRouteCommand {
[CmdletBinding()]
param(
Expand Down Expand Up @@ -125,7 +135,7 @@ function Invoke-NovaCliCommandRoute {
return Invoke-NovaCliInitCommand -Arguments $InvocationContext.Arguments -ForwardedParameters $mutatingCommonParameters -WhatIfEnabled:$InvocationContext.WhatIfEnabled
}
'bump' {
return Invoke-NovaCliParsedCommand -InvocationContext $InvocationContext -ParserCommand 'ConvertFrom-NovaBumpCliArgument' -ActionCommand 'Update-NovaModuleVersion'
return Invoke-NovaCliBumpRouteCommand -InvocationContext $InvocationContext
}
'update' {
return Invoke-NovaCliUpdateRouteCommand -InvocationContext $InvocationContext
Expand Down
3 changes: 2 additions & 1 deletion src/private/cli/InvokeNovaCliInstallWorkflow.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ function Invoke-NovaCliInstallWorkflow {
Write-Warning "Installed nova to $( $WorkflowContext.TargetDirectory ), but that directory is not currently in PATH. Add it to your shell profile before using nova directly from zsh/bash."
}

Write-NovaModuleReleaseNotesLink
$releaseNotesUri = Get-NovaModuleReleaseNotesUri

return [pscustomobject]@{
CommandName = 'nova'
InstalledPath = $installedPath
DestinationDirectory = $WorkflowContext.TargetDirectory
DirectoryOnPath = $directoryOnPath
ReleaseNotesUri = $releaseNotesUri
}
}
9 changes: 6 additions & 3 deletions src/private/release/InvokeNovaVersionUpdateWorkflow.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ function Invoke-NovaVersionUpdateWorkflow {
[switch]$WhatIfEnabled
)

$versionWriteResult = $null
if ($ShouldRun) {
Set-NovaModuleVersion -ProjectInfo $WorkflowContext.ProjectInfo -Label $WorkflowContext.Label -PreviewRelease:$WorkflowContext.PreviewRelease -Confirm:$false
$versionWriteResult = Set-NovaModuleVersion -ProjectInfo $WorkflowContext.ProjectInfo -Label $WorkflowContext.Label -PreviewRelease:$WorkflowContext.PreviewRelease -Confirm:$false
}

if (-not (Test-NovaVersionUpdateResultRequired -ShouldRun:$ShouldRun -WhatIfEnabled:$WhatIfEnabled)) {
return
}

return Get-NovaVersionUpdateResult -WorkflowContext $WorkflowContext
return Get-NovaVersionUpdateResult -WorkflowContext $WorkflowContext -Applied:($null -ne $versionWriteResult -and $versionWriteResult.Applied)
}

function Test-NovaVersionUpdateResultRequired {
Expand All @@ -30,13 +31,15 @@ function Test-NovaVersionUpdateResultRequired {
function Get-NovaVersionUpdateResult {
[CmdletBinding()]
param(
[Parameter(Mandatory)][pscustomobject]$WorkflowContext
[Parameter(Mandatory)][pscustomobject]$WorkflowContext,
[switch]$Applied
)

return [pscustomobject]@{
PreviousVersion = $WorkflowContext.PreviousVersion
NewVersion = $WorkflowContext.NewVersion
Label = $WorkflowContext.Label
CommitCount = $WorkflowContext.CommitCount
Applied = [bool]$Applied
}
}
29 changes: 25 additions & 4 deletions src/private/release/SetNovaModuleVersion.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
function Get-NovaModuleVersionWriteResult {
[CmdletBinding()]
param(
[Parameter(Mandatory)][string]$ProjectFile,
[Parameter(Mandatory)][string]$PreviousVersion,
[Parameter(Mandatory)][string]$NewVersion,
[switch]$Applied
)

return [pscustomobject]@{
ProjectFile = $ProjectFile
Target = [System.IO.Path]::GetFileName($ProjectFile)
PreviousVersion = $PreviousVersion
NewVersion = $NewVersion
Applied = [bool]$Applied
}
}

function Set-NovaModuleVersion {
[CmdletBinding(SupportsShouldProcess = $true)]
param(
Expand All @@ -11,13 +29,16 @@ function Set-NovaModuleVersion {

$versionUpdatePlan = Get-NovaVersionUpdatePlan -ProjectInfo $ProjectInfo -Label $Label -PreviewRelease:$PreviewRelease -StableRelease:$StableRelease
$jsonContent = Read-ProjectJsonData -ProjectJsonPath $versionUpdatePlan.ProjectFile
$previousVersion = [string]$jsonContent.Version
$newVersion = $versionUpdatePlan.NewVersion.ToString()
$target = [System.IO.Path]::GetFileName($versionUpdatePlan.ProjectFile)
$action = "Set module version to $newVersion"

if ( $PSCmdlet.ShouldProcess($target, $action)) {
$jsonContent.Version = $newVersion
Write-Host "Version bumped to : $newVersion"
Write-ProjectJsonData -ProjectJsonPath $versionUpdatePlan.ProjectFile -Data $jsonContent
if (-not $PSCmdlet.ShouldProcess($target, $action)) {
return Get-NovaModuleVersionWriteResult -ProjectFile $versionUpdatePlan.ProjectFile -PreviousVersion $previousVersion -NewVersion $newVersion
}

$jsonContent.Version = $newVersion
Write-ProjectJsonData -ProjectJsonPath $versionUpdatePlan.ProjectFile -Data $jsonContent
return Get-NovaModuleVersionWriteResult -ProjectFile $versionUpdatePlan.ProjectFile -PreviousVersion $previousVersion -NewVersion $newVersion -Applied
}
33 changes: 28 additions & 5 deletions src/private/shared/WriteNovaModuleReleaseNotesLink.ps1
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
function Get-NovaModuleReleaseNotesMessage {
[CmdletBinding(DefaultParameterSetName = 'Module')]
param(
[Parameter(ParameterSetName = 'Module')]
[object]$Module = $ExecutionContext.SessionState.Module,
[Parameter(ParameterSetName = 'Uri')]
[AllowNull()][string]$ReleaseNotesUri
)

if ($PSCmdlet.ParameterSetName -eq 'Module') {
$ReleaseNotesUri = Get-NovaModuleReleaseNotesUri -Module $Module
}

if ( [string]::IsNullOrWhiteSpace($ReleaseNotesUri)) {
return $null
}

return "Release notes: $($ReleaseNotesUri.Trim() )"
}

function Write-NovaModuleReleaseNotesLink {
[CmdletBinding()]
[CmdletBinding(DefaultParameterSetName = 'Module')]
param(
[object]$Module = $ExecutionContext.SessionState.Module
[Parameter(ParameterSetName = 'Module')]
[object]$Module = $ExecutionContext.SessionState.Module,
[Parameter(ParameterSetName = 'Uri')]
[AllowNull()][string]$ReleaseNotesUri
)

$releaseNotesUri = Get-NovaModuleReleaseNotesUri -Module $Module
if ($null -eq $releaseNotesUri) {
$message = Get-NovaModuleReleaseNotesMessage @PSBoundParameters
if ($null -eq $message) {
return
}

Write-Host "Release notes: $releaseNotesUri"
Write-Host $message
}
22 changes: 19 additions & 3 deletions src/private/update/InvokeNovaModuleSelfUpdateWorkflow.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@ function Invoke-NovaModuleSelfUpdateOrStop {
}
}

function Complete-NovaModuleSelfUpdateResult {
[CmdletBinding()]
param(
[Parameter(Mandatory)][pscustomobject]$Plan,
[AllowNull()][string]$ReleaseNotesUri
)

if ($Plan.PSObject.Properties.Name -contains 'ReleaseNotesUri') {
$Plan.ReleaseNotesUri = $ReleaseNotesUri
return $Plan
}

$Plan | Add-Member -NotePropertyName 'ReleaseNotesUri' -NotePropertyValue $ReleaseNotesUri
return $Plan
}

function Invoke-NovaModuleSelfUpdateWorkflow {
[CmdletBinding()]
param(
Expand All @@ -20,11 +36,11 @@ function Invoke-NovaModuleSelfUpdateWorkflow {

$plan = $WorkflowContext.Plan
if (-not $plan.UpdateAvailable) {
return $plan
return Complete-NovaModuleSelfUpdateResult -Plan $plan -ReleaseNotesUri $null
}

Invoke-NovaModuleSelfUpdateOrStop -Plan $plan
$plan.Updated = $true
Write-NovaModuleReleaseNotesLink
return $plan
$releaseNotesUri = Get-NovaModuleReleaseNotesUri
return Complete-NovaModuleSelfUpdateResult -Plan $plan -ReleaseNotesUri $releaseNotesUri
}
4 changes: 3 additions & 1 deletion src/public/InstallNovaCli.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ function Install-NovaCli {
return
}

return Invoke-NovaCliInstallWorkflow -WorkflowContext $workflowContext
$result = Invoke-NovaCliInstallWorkflow -WorkflowContext $workflowContext
Write-NovaModuleReleaseNotesLink -ReleaseNotesUri $result.ReleaseNotesUri
return $result
}
10 changes: 6 additions & 4 deletions src/public/UpdateNovaModuleTools.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ function Update-NovaModuleTool {
$workflowContext = Get-NovaModuleSelfUpdateWorkflowContext
$plan = $workflowContext.Plan
if (-not $plan.UpdateAvailable) {
return $plan
return Complete-NovaModuleSelfUpdateResult -Plan $plan -ReleaseNotesUri $null
}

if ($plan.IsPrereleaseTarget -and -not (Confirm-NovaPrereleaseModuleUpdate -Cmdlet $PSCmdlet -CurrentVersion $plan.CurrentVersion -TargetVersion $plan.TargetVersion)) {
$plan.Cancelled = $true
return $plan
return Complete-NovaModuleSelfUpdateResult -Plan $plan -ReleaseNotesUri $null
}

if (-not $PSCmdlet.ShouldProcess($plan.ModuleName, $workflowContext.Action)) {
return $plan
return Complete-NovaModuleSelfUpdateResult -Plan $plan -ReleaseNotesUri $null
}

return Invoke-NovaModuleSelfUpdateWorkflow -WorkflowContext $workflowContext
$result = Invoke-NovaModuleSelfUpdateWorkflow -WorkflowContext $workflowContext
Write-NovaModuleReleaseNotesLink -ReleaseNotesUri $result.ReleaseNotesUri
return $result
}
11 changes: 10 additions & 1 deletion src/public/UpdateNovaModuleVersion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,14 @@ function Update-NovaModuleVersion {

$shouldRun = $PSCmdlet.ShouldProcess($workflowContext.Target, $workflowContext.Action)

return Invoke-NovaVersionUpdateWorkflow -WorkflowContext $workflowContext -ShouldRun:$shouldRun -WhatIfEnabled:$WhatIfPreference
$result = Invoke-NovaVersionUpdateWorkflow -WorkflowContext $workflowContext -ShouldRun:$shouldRun -WhatIfEnabled:$WhatIfPreference
if ($null -eq $result) {
return
}

if ($result.Applied) {
Write-Host "Version bumped to : $( $result.NewVersion )"
}

return $result
}
63 changes: 63 additions & 0 deletions tests/CoverageGaps.Cli.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,69 @@ Describe 'Coverage gaps for CLI and installed-version internals' {
}
}

It 'Format-NovaCliCommandResult renders structured bump results as a stable CLI summary' {
InModuleScope $script:moduleName {
$versionUpdateResult = [pscustomobject]@{
PreviousVersion = '1.0.0'
NewVersion = '1.1.0-preview'
Label = 'Minor'
CommitCount = 2
Applied = $false
}
$result = Format-NovaCliCommandResult -Command 'bump' -Result $versionUpdateResult

$result | Should -Be 'Version plan: 1.0.0 -> 1.1.0-preview | Label: Minor | Commits: 2'
}
}

It 'Format-NovaCliCommandResult renders applied bump results as a completed CLI summary' {
InModuleScope $script:moduleName {
$versionUpdateResult = [pscustomobject]@{
PreviousVersion = '1.0.0'
NewVersion = '1.1.0'
Label = 'Minor'
CommitCount = 2
Applied = $true
}

$result = Format-NovaCliCommandResult -Command 'bump' -Result $versionUpdateResult

$result | Should -Be 'Version bump completed: 1.0.0 -> 1.1.0 | Label: Minor | Commits: 2'
}
}

It 'Invoke-NovaCliCommandRoute formats bump results through the shared CLI formatter' {
InModuleScope $script:moduleName {
$invocationContext = [pscustomobject]@{
Command = 'bump'
Arguments = @('--preview')
CommonParameters = @{}
MutatingCommonParameters = @{WhatIf = $true}
IsHelpRequest = $false
HelpRequest = $null
ModuleName = 'NovaModuleTools'
WhatIfEnabled = $true
CliConfirmEnabled = $false
}
Mock ConvertFrom-NovaBumpCliArgument {@{Preview = $true}}
Mock Update-NovaModuleVersion {
[pscustomobject]@{
PreviousVersion = '1.0.0'
NewVersion = '1.1.0-preview'
Label = 'Minor'
CommitCount = 2
Applied = $false
}
}

$result = Invoke-NovaCliCommandRoute -InvocationContext $invocationContext

$result | Should -Be 'Version plan: 1.0.0 -> 1.1.0-preview | Label: Minor | Commits: 2'
Assert-MockCalled ConvertFrom-NovaBumpCliArgument -Times 1 -ParameterFilter {$Arguments -eq @('--preview')}
Assert-MockCalled Update-NovaModuleVersion -Times 1 -ParameterFilter {$Preview -and $WhatIf}
}
}

It 'Invoke-NovaCliCommandRoute handles the direct root --help command route when help was not pre-normalized' {
InModuleScope $script:moduleName {
$invocationContext = [pscustomobject]@{
Expand Down
Loading
Loading