Private/Resolve-ConfigPath.ps1
|
function Resolve-ConfigPath { <# .SYNOPSIS Locates the Envoke config.json file using a three-location search order. .DESCRIPTION Searches for config.json in the following priority order, returning the first match found: 1. ExplicitPath parameter — if provided, this path must exist (throws if not) 2. $HOME\.envoke\config.json — user data folder, survives module updates 3. Module directory config.json — beside the module files, works for git-clone users If no config file is found at any location, throws an actionable error message naming the expected locations and directing the user to copy config.example.jsonc. Guards against .jsonc files being passed as the config path — ConvertFrom-Json does not support JSONC comment syntax and will fail to parse such files. .PARAMETER ExplicitPath Optional. Explicit path to a config.json file. When provided, this path takes priority over all search locations. Throws a terminating error if the path does not exist or points to a .jsonc file. .NOTES Author: Aaron AlAnsari Created: 2026-02-24 The module directory search (location 3) uses $PSScriptRoot which resolves to the Private/ directory at dot-source time. One level up (..) reaches the module root where config.json would be placed by git-clone users. #> [CmdletBinding()] [OutputType([string])] param ( [Parameter()] [string]$ExplicitPath ) # Guard: reject .jsonc files — ConvertFrom-Json cannot parse JSONC comment syntax. if (-not [string]::IsNullOrWhiteSpace($ExplicitPath) -and $ExplicitPath.EndsWith('.jsonc')) { throw "Config file must be plain JSON (.json). Copy config.example.jsonc and save as config.json, then remove the // comment lines." } # Location 1: explicit parameter always wins when provided. if (-not [string]::IsNullOrWhiteSpace($ExplicitPath)) { if (-not (Test-Path -Path $ExplicitPath -PathType Leaf)) { throw "Config file not found at specified path: '$ExplicitPath'. Verify the path exists and is accessible." } Write-EnvkLog -Level 'DEBUG' -Message "Resolved config path (explicit parameter): $ExplicitPath" return $ExplicitPath } # Location 2: user data folder — survives PSGallery/module updates. $userConfig = Join-Path $HOME '.envoke\config.json' if (Test-Path -Path $userConfig -PathType Leaf) { Write-EnvkLog -Level 'DEBUG' -Message "Resolved config path (user data folder): $userConfig" return $userConfig } # Location 3: module directory — beside the module files for git-clone users. # $PSScriptRoot is the Private/ directory; '..' reaches the module root. $moduleConfig = Join-Path $PSScriptRoot '..\config.json' if (Test-Path -Path $moduleConfig -PathType Leaf) { Write-EnvkLog -Level 'DEBUG' -Message "Resolved config path (module directory): $moduleConfig" return $moduleConfig } # No config found at any location — provide an actionable error message. $userLocation = Join-Path $HOME '.envoke\config.json' $moduleLocation = Join-Path $PSScriptRoot '..\config.json' throw ( "No config.json found. Copy config.example.jsonc from the module directory, " + "save it as config.json (removing the // comment lines), and place it at one of these locations:`n" + " $userLocation`n" + " $moduleLocation" ) } |