Skip to content

Commit a74f031

Browse files
AndreaV-Lsiclaude
andcommitted
feat: Add Invoke-RepoHerd entry point for PowerShell Gallery users
- Add Invoke-RepoHerd function to RepoHerd.psm1 with full orchestration logic (defaults to dependencies.json in current working directory) - Refactor RepoHerd.ps1 to a thin wrapper delegating to Invoke-RepoHerd - Export Invoke-RepoHerd in module manifest - Bump version to 9.1.0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6c69c64 commit a74f031

6 files changed

Lines changed: 264 additions & 178 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ All notable changes to RepoHerd will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [9.1.0] - 2026-04-05
9+
10+
### Added
11+
12+
- `Invoke-RepoHerd` function as the module entry point for PowerShell Gallery users
13+
- After `Install-Module RepoHerd`, users can call `Invoke-RepoHerd` directly
14+
- Defaults to `dependencies.json` in the current working directory
15+
- Same parameters as `RepoHerd.ps1`
16+
17+
### Changed
18+
19+
- `RepoHerd.ps1` refactored to a thin wrapper that delegates to `Invoke-RepoHerd`
20+
821
## [9.0.0] - 2026-03-31
922

1023
### Changed

RepoHerd.ps1

Lines changed: 8 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
.\RepoHerd.ps1 -Verbose -DisablePostCheckoutScripts
4747
.\RepoHerd.ps1 -EnableDebug -EnableErrorContext
4848
.NOTES
49-
Version: 9.0.0
49+
Version: 9.1.0
5050
Last Modified: 2026-03-20
5151
5252
Requires PowerShell 7.6 LTS or later (installs side-by-side with Windows PowerShell 5.1).
@@ -94,175 +94,13 @@ param(
9494
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
9595
Import-Module (Join-Path $scriptDir 'RepoHerd.psm1') -Force
9696

97-
# Initialize module state from script parameters
98-
Initialize-RepoHerd `
99-
-ScriptPath $scriptDir `
100-
-DryRun:$DryRun `
101-
-EnableDebug:$EnableDebug `
102-
-DisableRecursion:$DisableRecursion `
103-
-MaxDepth $MaxDepth `
104-
-ApiCompatibility $ApiCompatibility `
105-
-DisablePostCheckoutScripts:$DisablePostCheckoutScripts `
106-
-EnableErrorContext:$EnableErrorContext `
107-
-OutputFile $OutputFile
108-
109-
# Main execution
110-
$exitCode = 0
111-
try {
112-
Write-Log "RepoHerd started - Version 9.0.0" -Level Info
113-
Write-Log "Script path: $scriptDir" -Level Debug
114-
Write-Log "PowerShell version: $($PSVersionTable.PSVersion)" -Level Debug
115-
Write-Log "Operating System: $([System.Environment]::OSVersion.VersionString)" -Level Debug
116-
Write-Log "Default API Compatibility: $ApiCompatibility" -Level Info
117-
118-
if (-not $DisableRecursion) {
119-
Write-Log "Recursive mode: ENABLED (default) with max depth: $MaxDepth" -Level Info
120-
} else {
121-
Write-Log "Recursive mode: DISABLED" -Level Info
122-
}
123-
124-
if (-not $DisablePostCheckoutScripts) {
125-
Write-Log "Post-checkout scripts: ENABLED (default)" -Level Info
126-
} else {
127-
Write-Log "Post-checkout scripts: DISABLED" -Level Info
128-
}
129-
130-
if ($EnableErrorContext) {
131-
Write-Log "Error context: ENABLED - Detailed error information will be shown" -Level Info
132-
} else {
133-
Write-Log "Error context: DISABLED - Use -EnableErrorContext for detailed error information" -Level Debug
134-
}
135-
136-
if ($OutputFile) {
137-
Write-Log "Structured output will be written to: $OutputFile" -Level Info
138-
}
139-
140-
# Calculate and log script hash in debug mode
141-
if ($EnableDebug) {
142-
$scriptContent = Get-Content -Path $MyInvocation.MyCommand.Path -Raw
143-
$scriptBytes = [System.Text.Encoding]::UTF8.GetBytes($scriptContent)
144-
$sha256 = [System.Security.Cryptography.SHA256]::Create()
145-
$hashBytes = $sha256.ComputeHash($scriptBytes)
146-
$scriptHash = [System.BitConverter]::ToString($hashBytes).Replace('-', '')
147-
Write-Log "Script SHA256 hash: $($scriptHash.Substring(0, 16))..." -Level Debug
148-
Write-Log "Full script hash: $scriptHash" -Level Debug
149-
}
150-
151-
if ($DryRun) {
152-
Write-Log "DRY RUN MODE - No actual changes will be made" -Level Warning
153-
}
154-
155-
if ($EnableDebug) {
156-
Write-Log "Debug logging enabled" -Level Info
157-
}
158-
159-
# Check Git installation
160-
if (-not (Test-GitInstalled)) {
161-
throw "Git is not installed or not accessible in PATH"
162-
}
163-
164-
# Determine input file path
165-
if ([string]::IsNullOrEmpty($InputFile)) {
166-
$InputFile = Join-Path $scriptDir "dependencies.json"
167-
Write-Log "Using default input file: $InputFile" -Level Verbose
168-
}
169-
170-
# Store the dependency file name for recursive processing
171-
# Access module internals for setting the default dependency file name
172-
& (Get-Module RepoHerd) { $script:DefaultDependencyFileName = $args[0] } (Split-Path -Leaf $InputFile)
173-
Write-Log "Default dependency file name for recursive processing: $(Split-Path -Leaf $InputFile)" -Level Debug
174-
175-
# Determine credentials file path
176-
if ([string]::IsNullOrEmpty($CredentialsFile)) {
177-
$CredentialsFile = Join-Path $scriptDir "git_credentials.json"
178-
Write-Log "Using default credentials file: $CredentialsFile" -Level Verbose
179-
}
180-
181-
# Read SSH credentials
182-
$sshCreds = Read-CredentialsFile -FilePath $CredentialsFile
183-
& (Get-Module RepoHerd) { $script:SshCredentials = $args[0] } $sshCreds
184-
185-
# Check if input file exists
186-
if (-not (Test-Path $InputFile)) {
187-
throw "Input file not found: $InputFile"
188-
}
189-
190-
# Process the initial dependency file with enhanced error handling
191-
Write-Log "Starting dependency processing at depth 0" -Level Info
192-
193-
$checkedOutRepos = Invoke-WithErrorContext -Context "Processing root dependency file" -ScriptBlock {
194-
Invoke-DependencyFile -DependencyFilePath $InputFile -Depth 0
195-
}
196-
197-
# Handle null return
198-
if ($null -eq $checkedOutRepos) {
199-
Write-Log "WARNING: Invoke-DependencyFile returned null, initializing as empty array" -Level Warning
200-
$checkedOutRepos = @()
201-
} else {
202-
Write-Log "Invoke-DependencyFile returned type: $($checkedOutRepos.GetType().FullName)" -Level Debug
203-
}
204-
if ($null -eq $checkedOutRepos) {
205-
Write-Log "WARNING: checkedOutRepos is null!" -Level Warning
206-
$checkedOutRepos = @()
207-
}
208-
209-
Write-Log "Completed depth 0 processing: 1 dependency file processed, $($checkedOutRepos.Count) repositories checked out" -Level Info
210-
211-
# Additional debug information
212-
if ($EnableDebug) {
213-
Write-Log "Detailed checkedOutRepos information:" -Level Debug
214-
Write-Log " Count: $($checkedOutRepos.Count)" -Level Debug
215-
Write-Log " IsArray: $($checkedOutRepos -is [Array])" -Level Debug
216-
if ($checkedOutRepos.Count -gt 0) {
217-
Write-Log " Repository details:" -Level Debug
218-
foreach ($repo in $checkedOutRepos) {
219-
Write-Log " - Repository: $($repo.Repository.'Repository URL'), Path: $($repo.AbsolutePath)" -Level Debug
220-
}
221-
}
222-
}
223-
224-
# If recursive mode is enabled, process nested dependencies
225-
$isRecursiveMode = -not $DisableRecursion
226-
Write-Log "Checking recursive processing conditions - RecursiveMode: $isRecursiveMode, CheckedOutRepos.Count: $($checkedOutRepos.Count)" -Level Debug
227-
228-
if ($isRecursiveMode -and $checkedOutRepos.Count -gt 0) {
229-
Write-Log "Entering recursive processing with $($checkedOutRepos.Count) repositories" -Level Info
230-
$defaultDepFileName = Split-Path -Leaf $InputFile
231-
Invoke-WithErrorContext -Context "Processing recursive dependencies" -ScriptBlock {
232-
Invoke-RecursiveDependencies -CheckedOutRepos $checkedOutRepos -DefaultDependencyFileName $defaultDepFileName -CurrentDepth 0
233-
}
234-
} else {
235-
if ($DisableRecursion) {
236-
Write-Log "Recursive processing skipped - recursive mode is disabled" -Level Info
237-
} elseif ($checkedOutRepos.Count -eq 0) {
238-
Write-Log "Recursive processing skipped - no new repositories were checked out at depth 0" -Level Info
239-
}
240-
}
241-
242-
# Show summary
243-
Show-Summary
244-
245-
# Determine exit code from failure count
246-
$failureCount = & (Get-Module RepoHerd) { $script:FailureCount }
247-
if ($failureCount -gt 0) {
248-
$exitCode = 1
249-
}
250-
}
251-
catch {
252-
Write-ErrorWithContext -ErrorRecord $_ -AdditionalMessage "Unexpected error in main execution"
253-
Show-ErrorDialog -Message $_.Exception.Message
254-
$exitCode = 1
97+
# When run from the script, default InputFile and CredentialsFile to the script directory
98+
if (-not $PSBoundParameters.ContainsKey('InputFile')) {
99+
$PSBoundParameters['InputFile'] = Join-Path $scriptDir "dependencies.json"
255100
}
256-
finally {
257-
# Write structured output if requested — guaranteed even on failure
258-
if (-not [string]::IsNullOrEmpty($OutputFile)) {
259-
try {
260-
Export-CheckoutResults -OutputFile $OutputFile
261-
}
262-
catch {
263-
Write-Host "Failed to write output file: $_" -ForegroundColor Red
264-
}
265-
}
101+
if (-not $PSBoundParameters.ContainsKey('CredentialsFile')) {
102+
$PSBoundParameters['CredentialsFile'] = Join-Path $scriptDir "git_credentials.json"
266103
}
267104

268-
exit $exitCode
105+
# Delegate to module function and exit with its return code
106+
exit (Invoke-RepoHerd @PSBoundParameters)

RepoHerd.psd1

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@{
22
# Module manifest for RepoHerd
33
RootModule = 'RepoHerd.psm1'
4-
ModuleVersion = '9.0.0'
4+
ModuleVersion = '9.1.0'
55
GUID = '55dbb622-24f8-4f70-b16e-5412d436f94f'
66
Author = 'LS Instruments AG'
77
CompanyName = 'LS Instruments AG'
@@ -47,7 +47,8 @@
4747
'Read-CredentialsFile',
4848
'Set-PostCheckoutScriptResult',
4949
'Export-CheckoutResults',
50-
'Show-Summary'
50+
'Show-Summary',
51+
'Invoke-RepoHerd'
5152
)
5253

5354
CmdletsToExport = @()
@@ -59,7 +60,7 @@
5960
Tags = @('Git', 'Dependency', 'SemVer', 'Checkout', 'MultiRepo', 'DevOps', 'Automation', 'SSH', 'CrossPlatform', 'DependencyManagement', 'VersionPinning', 'Repository', 'Submodules')
6061
LicenseUri = 'https://github.com/LS-Instruments/RepoHerd/blob/main/LICENSE'
6162
ProjectUri = 'https://github.com/LS-Instruments/RepoHerd'
62-
ReleaseNotes = 'v9.0.0: Project renamed from LsiGitCheckout to RepoHerd. Breaking: module, entry point, and initialization function renamed. Added GitHub Pages landing page with SEO.'
63+
ReleaseNotes = 'v9.1.0: Added Invoke-RepoHerd function for PowerShell Gallery users. Install-Module RepoHerd now provides a callable entry point.'
6364
}
6465
}
6566
}

0 commit comments

Comments
 (0)