Skip to content

Commit 51d6147

Browse files
authored
feat(#99): enhance adapter architecture for external dependencies (#129)
* feat(#99): enhance adapter architecture for external dependencies - Isolate external workflow execution behind smaller internal adapters for clearer change points. - Refactor CLI environment access and Git command interactions for improved maintainability. - Introduce shared JSON file handling functions for better configuration management. * feat(#99): enhance adapter architecture for external dependencies - Isolate external workflow execution behind smaller internal adapters for clearer change points. - Refactor CLI environment access and Git command interactions for improved maintainability. - Introduce shared JSON file handling functions for better configuration management. * feat(#99): add test for Get-NovaCliConsoleReadKeyReader functionality - verify default console read delegate returns correct type - ensure delegate output matches expected format
1 parent eed582c commit 51d6147

24 files changed

Lines changed: 564 additions & 107 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
118118
entry point for all
119119
operations.
120120
- Change `nova` help to a dedicated CLI-native help system with both short and long command help forms.
121+
- Isolate external workflow execution behind smaller internal adapters so git, raw package upload, repository publish,
122+
self-update, settings-file I/O, and CLI environment access have clearer change points and smaller test seams.
121123
- `% nova <command> --help` and `% nova <command> -h` now show short CLI help.
122124
- `% nova --help <command>` and `% nova -h <command>` now show long CLI help.
123125
- Long command help now includes the matching public GitHub Pages guide URL for the selected command, while short help

src/private/cli/ConfirmNovaCliAction.ps1

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,15 @@ function Invoke-NovaCliConsoleReadKey {
3737
[CmdletBinding()]
3838
param()
3939

40-
return [Console]::ReadKey($true)
40+
$consoleReader = Get-NovaCliConsoleReadKeyReader
41+
return & $consoleReader
42+
}
43+
44+
function Get-NovaCliConsoleReadKeyReader {
45+
[CmdletBinding()]
46+
param()
47+
48+
return {[Console]::ReadKey($true)}
4149
}
4250

4351
function Read-NovaCliPromptKey {
@@ -52,14 +60,27 @@ function Read-NovaCliPromptKey {
5260
}
5361
}
5462

63+
function Get-NovaCliConfirmResponseKey {
64+
[CmdletBinding()]
65+
param()
66+
67+
$response = Get-NovaEnvironmentVariableValue -Name 'NOVA_CLI_CONFIRM_RESPONSE'
68+
if ( [string]::IsNullOrWhiteSpace($response)) {
69+
return $null
70+
}
71+
72+
return [char]$response[0]
73+
}
74+
5575
function Get-NovaCliCommandPromptKey {
5676
[CmdletBinding()]
5777
param(
5878
[Parameter(Mandatory)][string]$Message
5979
)
6080

61-
if (-not [string]::IsNullOrWhiteSpace($env:NOVA_CLI_CONFIRM_RESPONSE)) {
62-
return [char]$env:NOVA_CLI_CONFIRM_RESPONSE[0]
81+
$configuredResponse = Get-NovaCliConfirmResponseKey
82+
if ($null -ne $configuredResponse) {
83+
return $configuredResponse
6384
}
6485

6586
Write-Host 'Confirm'
@@ -127,4 +148,3 @@ function Confirm-NovaCliCommandAction {
127148
return
128149
} while ($true)
129150
}
130-

src/private/cli/GetNovaCliInstallDirectory.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ function Get-NovaCliInstallDirectory {
88
return [System.IO.Path]::GetFullPath($DestinationDirectory)
99
}
1010

11-
$homeDirectory = $env:HOME
11+
$homeDirectory = Get-NovaEnvironmentVariableValue -Name 'HOME'
1212

1313
if ( [string]::IsNullOrWhiteSpace($homeDirectory)) {
1414
Stop-NovaOperation -Message 'HOME environment variable is not set. Provide -DestinationDirectory explicitly.' -ErrorId 'Nova.Environment.HomeDirectoryMissing' -Category ResourceUnavailable -TargetObject 'HOME'

src/private/cli/TestNovaCliDirectoryOnPath.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ function Test-NovaCliDirectoryOnPath {
55
)
66

77
$resolvedDirectory = [System.IO.Path]::GetFullPath($Directory)
8-
foreach ($entry in @($env:PATH -split [regex]::Escape([string][System.IO.Path]::PathSeparator))) {
8+
$pathValue = Get-NovaEnvironmentVariableValue -Name 'PATH'
9+
foreach ($entry in @($pathValue -split [regex]::Escape([string][System.IO.Path]::PathSeparator))) {
910
if ( [string]::IsNullOrWhiteSpace($entry)) {
1011
continue
1112
}

src/private/package/InvokeNovaPackageArtifactUpload.ps1

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,8 @@ function Invoke-NovaPackageArtifactUpload {
99
Stop-NovaOperation -Message "Package file not found: $( $UploadArtifact.PackagePath )" -ErrorId 'Nova.Environment.PackageUploadFileNotFound' -Category ObjectNotFound -TargetObject $UploadArtifact.PackagePath
1010
}
1111

12-
$webRequestParameters = @{
13-
Uri = $UploadArtifact.UploadUrl
14-
Method = 'Put'
15-
InFile = $UploadArtifact.PackagePath
16-
}
17-
if (@($UploadArtifact.Headers.Keys).Count -gt 0) {
18-
$webRequestParameters.Headers = $UploadArtifact.Headers
19-
}
20-
21-
$webRequestCommand = Get-Command -Name Invoke-WebRequest -CommandType Cmdlet -ErrorAction Stop
22-
if ( $webRequestCommand.Parameters.ContainsKey('UseBasicParsing')) {
23-
$webRequestParameters.UseBasicParsing = $true
24-
}
25-
2612
try {
27-
$response = Invoke-WebRequest @webRequestParameters
13+
$response = Invoke-NovaPackageUploadRequest -UploadArtifact $UploadArtifact
2814
}
2915
catch {
3016
Stop-NovaOperation -Message "Package upload failed for $( $UploadArtifact.PackagePath ) -> $( $UploadArtifact.UploadUrl ). $( $_.Exception.Message )" -ErrorId 'Nova.Dependency.PackageUploadRequestFailed' -Category ConnectionError -TargetObject $UploadArtifact.UploadUrl
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
function Get-NovaPackageUploadRequestParameterMap {
2+
[CmdletBinding()]
3+
param(
4+
[Parameter(Mandatory)][pscustomobject]$UploadArtifact
5+
)
6+
7+
$parameters = @{
8+
Uri = $UploadArtifact.UploadUrl
9+
Method = 'Put'
10+
InFile = $UploadArtifact.PackagePath
11+
}
12+
if (@($UploadArtifact.Headers.Keys).Count -gt 0) {
13+
$parameters.Headers = $UploadArtifact.Headers
14+
}
15+
16+
return $parameters
17+
}
18+
19+
function Add-NovaLegacyWebRequestOption {
20+
[CmdletBinding()]
21+
param(
22+
[Parameter(Mandatory)][hashtable]$Parameters
23+
)
24+
25+
$webRequestCommand = Get-Command -Name Invoke-WebRequest -CommandType Cmdlet -ErrorAction Stop
26+
if ( $webRequestCommand.Parameters.ContainsKey('UseBasicParsing')) {
27+
$Parameters.UseBasicParsing = $true
28+
}
29+
30+
return $Parameters
31+
}
32+
33+
function Invoke-NovaPackageUploadRequest {
34+
[CmdletBinding()]
35+
param(
36+
[Parameter(Mandatory)][pscustomobject]$UploadArtifact
37+
)
38+
39+
$parameters = Get-NovaPackageUploadRequestParameterMap -UploadArtifact $UploadArtifact
40+
$parameters = Add-NovaLegacyWebRequestOption -Parameters $parameters
41+
return Invoke-WebRequest @parameters
42+
}

src/private/release/GetGitCommitMessagesForVersionBump.ps1

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,38 @@ function Get-GitCommitMessageForVersionBump {
99
}
1010

1111
$format = '%s%n%b%n--END-COMMIT--'
12-
$lastTag = & git -C $ProjectRoot describe --tags --abbrev=0 2> $null
12+
$lastTagResult = Invoke-NovaGitCommand -ProjectRoot $ProjectRoot -Arguments @('describe', '--tags', '--abbrev=0')
13+
$logResult = Get-NovaVersionBumpCommitLogResult -ProjectRoot $ProjectRoot -Format $format -LastTagResult $lastTagResult
14+
return @(ConvertFrom-NovaVersionBumpCommitLogResult -Result $logResult)
15+
}
1316

14-
if ($LASTEXITCODE -eq 0 -and -not [string]::IsNullOrWhiteSpace($lastTag)) {
15-
$raw = & git -C $ProjectRoot log "$lastTag..HEAD" --format=$format 2> $null
16-
}
17-
else {
18-
$raw = & git -C $ProjectRoot log --format=$format 2> $null
17+
function Get-NovaVersionBumpCommitLogResult {
18+
[CmdletBinding()]
19+
param(
20+
[Parameter(Mandatory)][string]$ProjectRoot,
21+
[Parameter(Mandatory)][string]$Format,
22+
[Parameter(Mandatory)][pscustomobject]$LastTagResult
23+
)
24+
25+
$lastTag = Get-NovaGitCommandOutputText -Result $LastTagResult
26+
if ($LastTagResult.ExitCode -eq 0 -and -not [string]::IsNullOrWhiteSpace($lastTag)) {
27+
return Invoke-NovaGitCommand -ProjectRoot $ProjectRoot -Arguments @('log', "$lastTag..HEAD", "--format=$format")
1928
}
2029

21-
if ($LASTEXITCODE -ne 0 -or -not $raw) {
30+
return Invoke-NovaGitCommand -ProjectRoot $ProjectRoot -Arguments @('log', "--format=$format")
31+
}
32+
33+
function ConvertFrom-NovaVersionBumpCommitLogResult {
34+
[CmdletBinding()]
35+
param(
36+
[Parameter(Mandatory)][pscustomobject]$Result
37+
)
38+
39+
if ($Result.ExitCode -ne 0 -or @($Result.Output).Count -eq 0) {
2240
return @()
2341
}
2442

25-
$text = ($raw -join [Environment]::NewLine)
43+
$text = (@($Result.Output) -join [Environment]::NewLine)
2644
$commits = $text -split '(?m)^--END-COMMIT--\r?$'
2745
return @($commits | ForEach-Object {$_.Trim()} | Where-Object {-not [string]::IsNullOrWhiteSpace($_)})
2846
}

src/private/release/GetNovaVersionLabelForBump.ps1

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ function Test-GitRepositoryIsAvailable {
3434
return $false
3535
}
3636

37-
$null = & git -C $ProjectRoot rev-parse --git-dir 2> $null
38-
return $LASTEXITCODE -eq 0
37+
$result = Invoke-NovaGitCommand -ProjectRoot $ProjectRoot -Arguments @('rev-parse', '--git-dir')
38+
return $result.ExitCode -eq 0
3939
}
4040

4141
function Test-GitRepositoryHasCommittedHead {
@@ -44,8 +44,8 @@ function Test-GitRepositoryHasCommittedHead {
4444
[Parameter(Mandatory)][string]$ProjectRoot
4545
)
4646

47-
$null = & git -C $ProjectRoot rev-parse --verify HEAD 2> $null
48-
return $LASTEXITCODE -eq 0
47+
$result = Invoke-NovaGitCommand -ProjectRoot $ProjectRoot -Arguments @('rev-parse', '--verify', 'HEAD')
48+
return $result.ExitCode -eq 0
4949
}
5050

5151
function Test-GitRepositoryHasCommitsSinceLatestTag {
@@ -54,11 +54,13 @@ function Test-GitRepositoryHasCommitsSinceLatestTag {
5454
[Parameter(Mandatory)][string]$ProjectRoot
5555
)
5656

57-
$lastTag = & git -C $ProjectRoot describe --tags --abbrev=0 2> $null
58-
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($lastTag)) {
57+
$lastTagResult = Invoke-NovaGitCommand -ProjectRoot $ProjectRoot -Arguments @('describe', '--tags', '--abbrev=0')
58+
$lastTag = Get-NovaGitCommandOutputText -Result $lastTagResult
59+
if ($lastTagResult.ExitCode -ne 0 -or [string]::IsNullOrWhiteSpace($lastTag)) {
5960
return $true
6061
}
6162

62-
$commitCount = & git -C $ProjectRoot rev-list --count "$lastTag..HEAD" 2> $null
63-
return $LASTEXITCODE -ne 0 -or $commitCount -ne '0'
63+
$commitCountResult = Invoke-NovaGitCommand -ProjectRoot $ProjectRoot -Arguments @('rev-list', '--count', "$lastTag..HEAD")
64+
$commitCount = Get-NovaGitCommandOutputText -Result $commitCountResult
65+
return $commitCountResult.ExitCode -ne 0 -or $commitCount -ne '0'
6466
}

src/private/release/InitiateGitRepo.ps1

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,44 @@ function New-InitiateGitRepo {
55
[string]$DirectoryPath
66
)
77

8-
# Check if Git is installed
9-
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
10-
Write-Warning 'Git is not installed. Please install Git and initialize repo manually'
8+
if (-not (Test-NovaGitCommandAvailable)) {
9+
Write-Warning 'Git is not installed. Please install Git and initialize repo manually'
1110
return
1211
}
13-
Push-Location -StackName 'GitInit'
12+
13+
if (Test-Path -LiteralPath (Join-Path $DirectoryPath '.git')) {
14+
Write-Warning 'A Git repository already exists in this directory.'
15+
return
16+
}
17+
18+
if (-not $PSCmdlet.ShouldProcess($DirectoryPath, "Initiating git on $DirectoryPath")) {
19+
return
20+
}
21+
1422
try {
15-
# Navigate to the specified directory
16-
Set-Location $DirectoryPath
17-
18-
# Check if a Git repository already exists
19-
if (Test-Path -Path '.git') {
20-
Write-Warning 'A Git repository already exists in this directory.'
21-
return
22-
}
23-
24-
if ( $PSCmdlet.ShouldProcess($DirectoryPath, ("Initiating git on $DirectoryPath"))) {
25-
try {
26-
git init | Out-Null
27-
} catch {
28-
Stop-NovaOperation -Message "Failed to initialize Git repo: $( $_.Exception.Message )" -ErrorId 'Nova.Dependency.GitRepositoryInitializationFailed' -Category OpenError -TargetObject $DirectoryPath
29-
}
30-
}
31-
Write-Verbose 'Git repository initialized successfully'
23+
$result = Invoke-NovaGitCommand -ProjectRoot $DirectoryPath -Arguments @('init')
3224
}
33-
finally {
34-
Pop-Location -StackName 'GitInit'
25+
catch {
26+
Stop-NovaOperation -Message "Failed to initialize Git repo: $( $_.Exception.Message )" -ErrorId 'Nova.Dependency.GitRepositoryInitializationFailed' -Category OpenError -TargetObject $DirectoryPath
27+
}
28+
29+
if ($result.ExitCode -ne 0) {
30+
Stop-NovaOperation -Message (Get-NovaGitInitializationFailureMessage -Result $result) -ErrorId 'Nova.Dependency.GitRepositoryInitializationFailed' -Category OpenError -TargetObject $DirectoryPath
3531
}
32+
33+
Write-Verbose 'Git repository initialized successfully'
34+
}
35+
36+
function Get-NovaGitInitializationFailureMessage {
37+
[CmdletBinding()]
38+
param(
39+
[Parameter(Mandatory)][pscustomobject]$Result
40+
)
41+
42+
$details = Get-NovaGitCommandOutputText -Result $Result
43+
if ( [string]::IsNullOrWhiteSpace($details)) {
44+
return 'Failed to initialize Git repo.'
45+
}
46+
47+
return "Failed to initialize Git repo: $details"
3648
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function Invoke-NovaRepositoryPublishCommand {
2+
[CmdletBinding()]
3+
param(
4+
[Parameter(Mandatory)][hashtable]$PublishParameters
5+
)
6+
7+
Publish-PSResource @PublishParameters
8+
}

0 commit comments

Comments
 (0)