@@ -84,18 +84,27 @@ function Show-Usage {
8484 Write-Host
8585}
8686
87- # Write helpers respect numeric verbosity:0 = silent,1 = errors/warnings only,2 = errors+warnings+ok+info,3+ = debug
88- function Write-Info { if ( $VerboseMode -ge 2 ) { Write-Host " [INFO] " - ForegroundColor Cyan - NoNewline; Write-Host " $args " } }
89- function Write-Ok { if ( $VerboseMode -ge 2 ) { Write-Host " [OK] " - ForegroundColor Green - NoNewline; Write-Host " $args " } }
90- function Write-Err { if ( $VerboseMode -ge 1 ) { Write-Host " [ERR] " - ForegroundColor Red - NoNewline; Write-Host " $args " } }
91- function Write-Warn { if ( $VerboseMode -ge 1 ) { Write-Host " [WARN] " - ForegroundColor Magenta - NoNewline; Write-Host " $args " } }
92- function Write-Debug { if ( $VerboseMode -ge 3 ) { Write-Host " [DEBUG] " - ForegroundColor Yellow - NoNewline; Write-Host " $args " } }
87+ # ###############################################################################
88+ # Variables and initial setup
89+ # ###############################################################################
90+
91+ # Get the directory of the current script
92+ $ScriptDirectory = Split-Path - Path $MyInvocation .MyCommand.Definition - Parent
9393
9494# Name of the script we install/copy; use a single variable instead of hardcoded strings
9595$ScriptFileName = ' Create-VSSolution.ps1'
9696$ScriptBaseName = [System.IO.Path ]::GetFileNameWithoutExtension($ScriptFileName )
9797
98+ # ###############################################################################
99+ # Include sourced libraries
100+ # ###############################################################################
101+ . " $ScriptDirectory \inc\Logging.ps1"
102+
103+ # ###############################################################################
98104# Main Script Logic
105+ # ###############################################################################
106+ Write-Header " Create-VSSolution Installer"
107+ Write-Info " Using install path: $InstallPath "
99108
100109# Show-Help
101110# If user asked for help, show usage AND then exit
@@ -104,8 +113,6 @@ if ($Help) {
104113 exit 0
105114}
106115
107- if ($VerboseMode -ge 2 ) { Write-Host " Starting installation script for $ScriptBaseName ..." - ForegroundColor Green }
108-
109116# Determine whether any action switches were provided. Discover switch parameters from the script's parameter metadata instead of hardcoding.
110117# Exclude non-action switches such as Help, Force and VerboseMode.
111118$nonActionSwitches = @ (' Help' , ' Force' , ' VerboseMode' )
@@ -141,71 +148,62 @@ foreach ($name in $actionSwitches) {
141148if (-not $actionProvided ) {
142149 $AddToPath = $true
143150 $CreateProfileFunction = $true
144- Write-Ok " No action flags provided - defaulting to -AddToPath"
151+ Write-Debug " No action flags provided - defaulting to -AddToPath"
145152}
146153
147154# Ensure install folder exists (safe to create even if deleting wrapper)
148155if (-not (Test-Path - Path $InstallPath )) {
156+ Write-Run " Creating install folder: $InstallPath "
149157 try {
150158 New-Item - ItemType Directory - Path $InstallPath - Force - ErrorAction Stop | Out-Null
151159 if (Test-Path - Path $InstallPath ) {
152- Write-Ok " Created install folder: $InstallPath "
160+ Write-RunDone $true
153161 }
154162 else {
155- Write-Warn " Failed to create install folder: $InstallPath "
163+ Write-RunDone $false
164+ Write-Err " Install folder creation reported success but path does not exist: $InstallPath "
165+ exit 1
156166 }
157167 }
158168 catch {
159- Write-Warn " Failed to create install folder: $InstallPath . Error: $_ "
169+ Write-Err " Failed to create install folder: $InstallPath . Error: $_ "
160170 }
161171}
162172
173+ # ###############################################################################
174+ # Path to source and destination
175+ # ###############################################################################
163176$dest = Join-Path $InstallPath $ScriptFileName
177+ $source = (Join-Path $PSScriptRoot $ScriptFileName )
178+ $sourceInc = Join-Path $PSScriptRoot ' inc'
164179
165- if (-not $DeleteProfileFunction ) {
166- $source = $null
167- # Determine source script path (assume repo root where this installer lives)
168- $possibleSources = @ (
169- (Join-Path $PSScriptRoot (Join-Path ' src' $ScriptFileName )),
170- (Join-Path $PSScriptRoot $ScriptFileName ),
171- (Join-Path (Get-Location ).Path (Join-Path ' src' $ScriptFileName )),
172- (Join-Path (Get-Location ).Path $ScriptFileName )
173- )
174-
175- # Select the first existing path (use a simple loop to avoid Select-Object parsing issues)
176- foreach ($p in $possibleSources ) {
177- if (Test-Path $p ) { $source = $p ; break }
178- }
179-
180- if (-not $source ) {
181- # When source not found, exit with code1
182- Write-Err " Source '$ScriptFileName ' not found in repo - skipping copy/module installation. You can still use -AddToPath to add the scripts folder to PATH."
183- exit1
184- }
185- }
186-
187- # If -Delete specified, perform cleanup and exit
180+ # ###############################################################################
181+ # Perform cleanup and exit
182+ # Optionally: -Delete
183+ # ###############################################################################
188184if ($Delete ) {
189- Write-Info " Running -Delete: will remove script, shim, module, profile wrapper and user PATH entry if present."
185+ Write-Run " Starting cleanup of installed artifacts..."
186+ [array ]$errors = @ ()
187+ [array ]$warnings = @ ()
190188
191189 # Remove script and shim
192190 $scriptPath = $dest
193191 $shimPath = Join-Path $InstallPath ' Create-VSSolution.cmd'
194192 if (Test-Path $scriptPath ) {
195- try { Remove-Item - Path $scriptPath - Force - ErrorAction Stop; Write-Ok " Removed script: $scriptPath " } catch { Write-Err " Failed to remove script: $_ " }
193+ try { Remove-Item - Path $scriptPath - Force - ErrorAction Stop; Write-Debug " Removed script: $scriptPath " } catch { $errors += " Failed to remove script: $_ " }
196194 }
197- else { Write-Ok " Script not found: $scriptPath " }
195+ else { Write-Debug " Script not found: $scriptPath " }
198196 if (Test-Path $shimPath ) {
199- try { Remove-Item - Path $shimPath - Force - ErrorAction Stop; Write-Ok " Removed shim: $shimPath " } catch { Write-Err " Failed to remove shim: $_ " }
197+ try { Remove-Item - Path $shimPath - Force - ErrorAction Stop; Write-Debug " Removed shim: $shimPath " } catch { $errors += " Failed to remove shim: $_ " }
200198 }
201- else { Write-Warn " Shim not found: $shimPath " }
199+ else { $warnings += " Shim not found: $shimPath " }
202200
203201 # Remove module folder
204202 $moduleDir = Join-Path $env: USERPROFILE ' Documents\PowerShell\Modules\Create-VSSolution'
205203 if (Test-Path $moduleDir ) {
206- try { Remove-Item - Path $moduleDir - Recurse - Force - ErrorAction Stop; Write-Ok " Removed module folder: $moduleDir " } catch { Write-Err " Failed to remove module folder: $_ " }
204+ try { Remove-Item - Path $moduleDir - Recurse - Force - ErrorAction Stop; Write-Debug " Removed module folder: $moduleDir " } catch { $errors += " Failed to remove module folder: $_ " }
207205 }
208- else { Write-Warn " Module folder not found: $moduleDir " }
206+ else { $warnings += " Module folder not found: $moduleDir " }
209207
210208 # Remove install path from user PATH
211209 try {
@@ -215,13 +213,13 @@ if ($Delete) {
215213 $newParts = $parts | Where-Object { -not ([string ]::Equals($_ , $InstallPath , [System.StringComparison ]::InvariantCultureIgnoreCase)) }
216214 $new = [string ]::Join(' ;' , $newParts )
217215 [Environment ]::SetEnvironmentVariable(' Path' , $new , ' User' )
218- Write-Ok " Removed $InstallPath from user PATH. Restart terminals to pick up change."
216+ Write-Debug " Removed $InstallPath from user PATH. Restart terminals to pick up change."
219217 }
220218 else {
221- Write-Ok " User PATH did not contain $InstallPath "
219+ Write-Debug " User PATH did not contain $InstallPath "
222220 }
223221 }
224- catch { Write-Err " Failed to update user PATH: $_ " }
222+ catch { $errors += " Failed to update user PATH: $_ " }
225223
226224 # Remove wrapper from profile (reuse existing removal logic)
227225 if (Test-Path - Path $PROFILE ) {
@@ -234,82 +232,127 @@ if ($Delete) {
234232 $out += $line
235233 }
236234 Set-Content - Path $PROFILE - Value $out
237- Write-Ok " Removed Create-VSSolution wrapper from profile ($PROFILE )."
235+ Write-Debug " Removed Create-VSSolution wrapper from profile ($PROFILE )."
238236 }
239- catch { Write-Err " Failed to remove wrapper from profile: $_ " }
237+ catch { $errors += " Failed to remove wrapper from profile: $_ " }
240238 }
241239 else {
242- Write-Ok " Profile $PROFILE does not exist. Nothing to remove."
240+ Write-Debug " Profile $PROFILE does not exist. Nothing to remove."
241+ }
242+
243+ if ($errors.Count -eq 0 ) {
244+ Write-RunDone $true
245+ }
246+ else {
247+ Write-RunDone $false
248+ }
249+
250+ if ($warnings.Count -gt 0 ) {
251+ Write-Host " Cleanup completed with warnings:"
252+ foreach ($warn in $warnings ) {
253+ Write-Warn " - $warn "
254+ }
243255 }
244256
245- Write-Host " Delete complete." - ForegroundColor Cyan
257+ if ($errors.Count -gt 0 ) {
258+ Write-Host " Cleanup completed with errors:"
259+ foreach ($err in $errors ) {
260+ Write-Err " - $err "
261+ }
262+ exit 1
263+ }
246264 exit 0
247265}
248266
249- # Optionally add to user PATH
267+ # ###############################################################################
268+ # Add script path to user PATH
269+ # Optionally: -AddToPath
270+ # ###############################################################################
250271if ($AddToPath ) {
272+ Write-Run " Adding $InstallPath to user PATH..."
251273 $current = [Environment ]::GetEnvironmentVariable(' Path' , ' User' )
252274 if ($current -notlike " *${InstallPath} *" ) {
253275 $new = if ([string ]::IsNullOrEmpty($current )) { $InstallPath } else { $current + ' ;' + $InstallPath }
254276 [Environment ]::SetEnvironmentVariable(' Path' , $new , ' User' )
255- Write-Ok " Added $InstallPath to user PATH. Restart terminals to pick up change."
277+ Write-RunDone $true
278+ Write-Debug " Added $InstallPath to user PATH. Restart terminals to pick up change."
256279 }
257280 else {
258- Write-Info " $InstallPath already in user PATH."
281+ Write-RunDone $true
282+ Write-Warn " $InstallPath already in user PATH."
259283 }
260284}
261285
286+ # ###############################################################################
287+ # Cope Scripts and inc folder
288+ # ###############################################################################
262289# If not deleting, perform copy to install path
263290if (-not $DeleteProfileFunction ) {
291+ Write-Run " Copying $ScriptFileName to $InstallPath ..."
292+ [array ]$errors = @ ()
293+ [array ]$warnings = @ ()
264294 # Use a variable for Test-Path result to avoid parsing issues on some PowerShell versions
265295 $destExists = Test-Path $dest
266- # When checking for existing destination or aborting, ensure we use `exit1 `
296+ # When checking for existing destination or aborting, ensure we use `exit 1 `
267297 if ($destExists ) {
268298 if (-not $Force ) {
269299 $resp = Read-Host " File $dest already exists. Overwrite? (y/N)"
270300 if ($resp -notin @ (' y' , ' Y' )) {
301+ Write-RunDone $false
271302 Write-Warn " Aborting installation to avoid overwriting existing file."
272303 exit 1
273304 }
274305 }
275306 }
276307 try {
277308 Copy-Item - Path $source - Destination $dest - Force:$Force - ErrorAction Stop
278- Write-Ok " Copied $ScriptFileName to $dest "
309+ Write-Debug " Copied $ScriptFileName to $dest "
279310 }
280311 catch {
281- Write-Err " Failed to copy $ScriptFileName to ${dest} : $_ "
282- exit 1
312+ $errors += " Failed to copy $ScriptFileName to ${dest} : $_ "
283313 }
284- # If -AsModule specified, install as simple module
285- if ($AsModule ) {
286- $moduleDir = Join-Path $ env: USERPROFILE ' Documents\PowerShell\Modules\Create-VSSolution '
314+ # Copy 'inc' folder if it exists
315+ if (Test-Path $sourceInc ) {
316+ Write-Info " Copying 'inc' folder to $InstallPath "
287317 try {
288- if (-not (Test-Path - Path $moduleDir )) {
289- New-Item - ItemType Directory - Path $moduleDir - Force - ErrorAction Stop | Out-Null
290- Write-Ok " Created module directory: $moduleDir "
291- }
292- $moduleDest = Join-Path $moduleDir $ScriptFileName
293- Copy-Item - Path $source - Destination $moduleDest - Force:$Force - ErrorAction Stop
294- Write-Ok " Installed Create-VSSolution as module in: $moduleDest "
318+ Copy-Item - Path $sourceInc - Destination $InstallPath - Recurse - Force:$Force - ErrorAction Stop
319+ Write-Debug " Copied 'inc' folder to $InstallPath "
295320 }
296321 catch {
297- Write-Err " Failed to install module: $_ "
298- exit 1
322+ $errors += " Failed to copy 'inc' folder to ${InstallPath} : $_ "
299323 }
300324 }
325+ else {
326+ $errors += " 'inc' folder not found at expected location: $sourceInc "
327+ }
328+ if ($errors.Count -eq 0 ) {
329+ Write-RunDone $true
330+ }
331+ else {
332+ Write-RunDone $false
333+ foreach ($err in $errors ) {
334+ Write-Err " - $err "
335+ }
336+ exit 1
337+ }
301338}
302339
303- # Optionally install as a simple module
340+ # ###############################################################################
341+ # Install as a simple module
342+ # Optionally: -AsModule
343+ # ###############################################################################
304344if ($AsModule ) {
345+ Write-Run " Installing Create-VSSolution as a PowerShell module..."
305346 $moduleDir = Join-Path $env: USERPROFILE ' Documents\PowerShell\Modules\Create-VSSolution'
306347 if (-not (Test-Path $moduleDir )) { New-Item - ItemType Directory - Path $moduleDir - Force | Out-Null }
307348 $moduleFile = Join-Path $moduleDir ' Create-VSSolution.psm1'
308349 try {
309350 if ($Force ) { Copy-Item - Path $source - Destination $moduleFile - Force - ErrorAction Stop } else { Copy-Item - Path $source - Destination $moduleFile - ErrorAction Stop }
351+ Copy-Item - Path $sourceInc - Destination (Join-Path $moduleDir ' inc' ) - Recurse - Force:$Force - ErrorAction Stop
310352 Unblock-File - Path $moduleFile - ErrorAction SilentlyContinue
311353 }
312354 catch {
355+ Write-RunDone $false
313356 Write-Err " Failed to copy module file: $_ "
314357 exit 1
315358 }
@@ -327,7 +370,8 @@ if ($AsModule) {
327370 Description = ' Create-VSSolution PowerShell module'
328371 } | Out-String | Set-Content - Path $psd1
329372 }
330- Write-Ok " Installed as module at $moduleDir . Import with 'Import-Module Create-VSSolution' or call the exported functions after a restart."
373+ Write-RunDone $true
374+ Write-Info " Module import with 'Import-Module Create-VSSolution' or call the exported functions after a restart."
331375}
332376
333- if ( $VerboseMode -ge 2 ) { Write-Host " Done." - ForegroundColor Green }
377+ Write-Info " Done."
0 commit comments