template/tools/Remove-BuildDependencies.ps1
|
[CmdletBinding(SupportsShouldProcess)] param( [string]$ProjectRoot, [switch]$AllowPreinstalledModules ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' if ([string]::IsNullOrWhiteSpace($ProjectRoot)) { $ProjectRoot = Split-Path -Path $PSScriptRoot -Parent } $ProjectRoot = (Resolve-Path -LiteralPath $ProjectRoot).Path $requirementsPaths = @((Join-Path -Path $ProjectRoot -ChildPath 'requirements.psd1')) $moduleNames = @('PSDepend') $preservedPesterMajorVersion = 3 $sourceRoot = Join-Path -Path $ProjectRoot -ChildPath 'src' $moduleRoots = @( if (Test-Path -LiteralPath $sourceRoot -PathType Container) { Get-ChildItem -LiteralPath $sourceRoot -Directory } Get-ChildItem -LiteralPath $ProjectRoot -Directory | Where-Object Name -ne 'src' ) $manifestCandidates = @( $moduleRoots | ForEach-Object { $candidate = Join-Path -Path $_.FullName -ChildPath "$($_.Name).psd1" if (Test-Path -LiteralPath $candidate -PathType Leaf) { $candidate } } ) if ($manifestCandidates.Count -eq 1) { $manifestData = Import-PowerShellDataFile -LiteralPath $manifestCandidates[0] foreach ($requiredModule in @($manifestData.RequiredModules)) { if ($requiredModule -is [string]) { $moduleNames += $requiredModule } elseif ($requiredModule.ModuleName) { $moduleNames += [string]$requiredModule.ModuleName } } $templateRequirements = Join-Path -Path (Split-Path -Path $manifestCandidates[0] -Parent) ` -ChildPath 'template/requirements.psd1' if (Test-Path -LiteralPath $templateRequirements -PathType Leaf) { $requirementsPaths += $templateRequirements } } foreach ($path in $requirementsPaths) { if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { continue } $requirements = Import-PowerShellDataFile -LiteralPath $path $moduleNames += @($requirements.Keys | Where-Object { $_ -ne 'PSDependOptions' }) } $moduleNames = @($moduleNames | Sort-Object -Unique) $cleanPester = $moduleNames -contains 'Pester' $moduleNames = @($moduleNames | Where-Object { $_ -ne 'Pester' }) foreach ($moduleName in $moduleNames) { Get-Module -Name $moduleName | Remove-Module -Force -ErrorAction SilentlyContinue } if ($cleanPester) { Get-Module -Name Pester | Where-Object { $_.Version.Major -ne $preservedPesterMajorVersion } | Remove-Module -Force -ErrorAction SilentlyContinue } $moduleRoots = @( $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | ForEach-Object { try { [System.IO.Path]::GetFullPath($_.TrimEnd([System.IO.Path]::DirectorySeparatorChar)) } catch { Write-Verbose "Ignoring malformed PSModulePath entry: $_" } } | Sort-Object -Unique ) foreach ($moduleRoot in $moduleRoots) { foreach ($moduleName in $moduleNames) { $modulePath = Join-Path -Path $moduleRoot -ChildPath $moduleName if (Test-Path -LiteralPath $modulePath -PathType Container) { if ($PSCmdlet.ShouldProcess($modulePath, 'Remove preinstalled build dependency')) { try { Remove-Item -LiteralPath $modulePath -Recurse -Force } catch { if (-not $AllowPreinstalledModules) { throw } Write-Warning "Unable to remove protected preinstalled module path: $modulePath" } } } } } if ($cleanPester) { $pesterModulePaths = @( Get-Module -Name Pester -ListAvailable | Where-Object { $_.Version.Major -ne $preservedPesterMajorVersion } | Select-Object -ExpandProperty ModuleBase -Unique ) foreach ($pesterModulePath in $pesterModulePaths) { $resolvedPesterPath = [System.IO.Path]::GetFullPath($pesterModulePath) $versionDirectoryName = Split-Path -Path $resolvedPesterPath -Leaf $pesterDirectoryName = Split-Path -Path (Split-Path -Path $resolvedPesterPath -Parent) -Leaf $parsedVersion = $null $isVersionDirectory = [version]::TryParse($versionDirectoryName, [ref]$parsedVersion) if ($pesterDirectoryName -ne 'Pester' -or -not $isVersionDirectory) { $message = "Refusing to remove unexpected Pester module path: $resolvedPesterPath" if (-not $AllowPreinstalledModules) { throw $message } Write-Warning $message continue } if ($PSCmdlet.ShouldProcess($resolvedPesterPath, 'Remove non-inbox Pester dependency')) { try { Remove-Item -LiteralPath $resolvedPesterPath -Recurse -Force } catch { if (-not $AllowPreinstalledModules) { throw } Write-Warning "Unable to remove protected Pester module path: $resolvedPesterPath" } } } } $remaining = @( foreach ($moduleRoot in $moduleRoots) { foreach ($moduleName in $moduleNames) { $modulePath = Join-Path -Path $moduleRoot -ChildPath $moduleName if (Test-Path -LiteralPath $modulePath -PathType Container) { $modulePath } } } if ($cleanPester) { Get-Module -Name Pester -ListAvailable | Where-Object { $_.Version.Major -ne $preservedPesterMajorVersion } | Select-Object -ExpandProperty ModuleBase -Unique } ) if ($remaining.Count -gt 0) { $message = "Unable to remove build dependencies: $($remaining -join ', ')" if (-not $AllowPreinstalledModules) { throw $message } Write-Warning $message } $removedDescription = @($moduleNames) if ($cleanPester) { $removedDescription += "Pester except major version $preservedPesterMajorVersion" } Write-Host "Removed all installed versions of: $($removedDescription -join ', ')" |