public/Pop-EnvironmentStack.ps1
#requires -Version 3 Set-StrictMode -Version Latest function Pop-EnvironmentStack{ <# .SYNOPSIS Changes the current Environment Variable to the Environment Variable most recently pushed onto the stack. .DESCRIPTION The Pop-EnvironmentStack cmdlet changes the current Environment Variable to the Environment Variable most recently pushed onto the stack by using the Push-Environment cmdlet. You can pop a Environment Variable from the default stack or from a stack that you create by using a Push-Environment command. .EXAMPLE PS C:\> Pop-EnvironmentStack .EXAMPLE PS C:\> Pop-EnvironmentStack -Peek .EXAMPLE PS C:\> Pop-EnvironmentStack -Drop #> [CmdletBinding(DefaultParametersetName="Stack", SupportsShouldProcess)] Param( # Specifies the Environment Variable stack from which the Environment Variable is popped. Enter a Environment Variable stack name. # # Without this parameter, Pop-EnvironmentStack pops a Environment Variable from the current Environment Variable stack. # By default, the current Environment Variable stack is the unnamed default Environment Variable stack that Windows PowerShell creates. # To make a Environment Variable stack the current Environment Variable stack, use the StackName parameter of Set-Environment. [Parameter(Position=0, ParameterSetName="Stack", ValueFromPipelineByPropertyName)] [Parameter(Position=0, ParameterSetName="StackDrop", ValueFromPipelineByPropertyName)] [String]$StackName = "" , # Peek Replace Mode # "Append" : not remove Environment Variable [Parameter(ParameterSetName="Stack")] [ValidateSet("Replace", "Append")] [string]$ReplaceMode = "Replace" , # Peek Environment Stack [Parameter(ParameterSetName="Stack")] [switch]$Peek , # IgnoredKeyPattern is pattern list of keys we don't want to deal with # https://github.com/direnv/direnv/blob/master/internal/cmd/env_diff.go [Parameter(ParameterSetName="Stack")] [string[]]$IgnoredKeyPattern = @( "COMP_WORDBREAKS" "PS1" "OLDPWD" "PWD" "SHELL" "SHELLOPTS" "SHLVL" "_" "__fish*" "BASH_FUNC_*" ) , # Remove Environment Stack Top # not apply Environment Variable [Parameter(ParameterSetName="StackDrop")] [switch]$Drop ) Begin { function IgnoredEnv { Param ([string]$env_name) foreach ($pattern in $IgnoredKeyPattern) { if ($script:IsCaseSensitive) { if ($env_name -clike $pattern) { return $true } } else { if ($env_name -ilike $pattern) { return $true } } } return $false } } Process { if($StackName -eq ""){ $name = $script:DefaultEnvStackName }else{ $name = $StackName } if(-not $script:EnvStack.Contains($name)){ return } $stack = $script:EnvStack[$name] if($Drop){ if($PSCmdlet.ShouldProcess("StackName: ${name}", "Drop Environment Stack Top")){ [void]$stack.Pop() if($stack.Count -eq 0){ $script:EnvStack.Remove($name) } } return } if($Peek -or $WhatIfPreference){ $applyEnvs = $stack.Peek() }else{ $applyEnvs = $stack.Pop() } if($stack.Count -eq 0){ $script:EnvStack.Remove($name) } $currentEnvs = New-InternalEnvHashTable Get-EnvironmentVariable | ForEach-Object { $currentEnvs[$_.Name] = $_ } if($ReplaceMode -eq "Replace"){ $currentEnvs.Values | ForEach-Object { if(IgnoredEnv $_.Name){ Write-Debug -Message "Replace Ignored Name $($_.Name)" return } if(-not $applyEnvs.Contains($_.Name)){ if($PSCmdlet.ShouldProcess("$($_.Name)", "Remove Environment Variable")){ Remove-EnvironmentVariable -LiteralName ($_.Name) -Confirm:$false } } } } $applyEnvs.Values | ForEach-Object { if(IgnoredEnv $_.Name){ Write-Debug -Message "Apply Ignored Name $($_.Name)" return } if($currentEnvs.Contains($_.Name)){ if($currentEnvs[$_.Name].Value -cne $_.Value){ if($PSCmdlet.ShouldProcess("$($_.Name)", "Update Environment Variable")){ Set-EnvironmentVariable -Name $_.Name -Value $_.Value -Confirm:$false } } }else{ if($PSCmdlet.ShouldProcess("$($_.Name)", "New Environment Variable")){ Set-EnvironmentVariable -Name $_.Name -Value $_.Value -Confirm:$false } } } } } |