17db96d56Sopenharmony_ci<# 27db96d56Sopenharmony_ci.Synopsis 37db96d56Sopenharmony_ciActivate a Python virtual environment for the current PowerShell session. 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ci.Description 67db96d56Sopenharmony_ciPushes the python executable for a virtual environment to the front of the 77db96d56Sopenharmony_ci$Env:PATH environment variable and sets the prompt to signify that you are 87db96d56Sopenharmony_ciin a Python virtual environment. Makes use of the command line switches as 97db96d56Sopenharmony_ciwell as the `pyvenv.cfg` file values present in the virtual environment. 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci.Parameter VenvDir 127db96d56Sopenharmony_ciPath to the directory that contains the virtual environment to activate. The 137db96d56Sopenharmony_cidefault value for this is the parent of the directory that the Activate.ps1 147db96d56Sopenharmony_ciscript is located within. 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci.Parameter Prompt 177db96d56Sopenharmony_ciThe prompt prefix to display when this virtual environment is activated. By 187db96d56Sopenharmony_cidefault, this prompt is the name of the virtual environment folder (VenvDir) 197db96d56Sopenharmony_cisurrounded by parentheses and followed by a single space (ie. '(.venv) '). 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci.Example 227db96d56Sopenharmony_ciActivate.ps1 237db96d56Sopenharmony_ciActivates the Python virtual environment that contains the Activate.ps1 script. 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci.Example 267db96d56Sopenharmony_ciActivate.ps1 -Verbose 277db96d56Sopenharmony_ciActivates the Python virtual environment that contains the Activate.ps1 script, 287db96d56Sopenharmony_ciand shows extra information about the activation as it executes. 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci.Example 317db96d56Sopenharmony_ciActivate.ps1 -VenvDir C:\Users\MyUser\Common\.venv 327db96d56Sopenharmony_ciActivates the Python virtual environment located in the specified location. 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci.Example 357db96d56Sopenharmony_ciActivate.ps1 -Prompt "MyPython" 367db96d56Sopenharmony_ciActivates the Python virtual environment that contains the Activate.ps1 script, 377db96d56Sopenharmony_ciand prefixes the current prompt with the specified string (surrounded in 387db96d56Sopenharmony_ciparentheses) while the virtual environment is active. 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_ci.Notes 417db96d56Sopenharmony_ciOn Windows, it may be required to enable this Activate.ps1 script by setting the 427db96d56Sopenharmony_ciexecution policy for the user. You can do this by issuing the following PowerShell 437db96d56Sopenharmony_cicommand: 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ciPS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ciFor more information on Execution Policies: 487db96d56Sopenharmony_cihttps://go.microsoft.com/fwlink/?LinkID=135170 497db96d56Sopenharmony_ci 507db96d56Sopenharmony_ci#> 517db96d56Sopenharmony_ciParam( 527db96d56Sopenharmony_ci [Parameter(Mandatory = $false)] 537db96d56Sopenharmony_ci [String] 547db96d56Sopenharmony_ci $VenvDir, 557db96d56Sopenharmony_ci [Parameter(Mandatory = $false)] 567db96d56Sopenharmony_ci [String] 577db96d56Sopenharmony_ci $Prompt 587db96d56Sopenharmony_ci) 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci<# Function declarations --------------------------------------------------- #> 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci<# 637db96d56Sopenharmony_ci.Synopsis 647db96d56Sopenharmony_ciRemove all shell session elements added by the Activate script, including the 657db96d56Sopenharmony_ciaddition of the virtual environment's Python executable from the beginning of 667db96d56Sopenharmony_cithe PATH variable. 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ci.Parameter NonDestructive 697db96d56Sopenharmony_ciIf present, do not remove this function from the global namespace for the 707db96d56Sopenharmony_cisession. 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci#> 737db96d56Sopenharmony_cifunction global:deactivate ([switch]$NonDestructive) { 747db96d56Sopenharmony_ci # Revert to original values 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci # The prior prompt: 777db96d56Sopenharmony_ci if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { 787db96d56Sopenharmony_ci Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt 797db96d56Sopenharmony_ci Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT 807db96d56Sopenharmony_ci } 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci # The prior PYTHONHOME: 837db96d56Sopenharmony_ci if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { 847db96d56Sopenharmony_ci Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME 857db96d56Sopenharmony_ci Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME 867db96d56Sopenharmony_ci } 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ci # The prior PATH: 897db96d56Sopenharmony_ci if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { 907db96d56Sopenharmony_ci Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH 917db96d56Sopenharmony_ci Remove-Item -Path Env:_OLD_VIRTUAL_PATH 927db96d56Sopenharmony_ci } 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci # Just remove the VIRTUAL_ENV altogether: 957db96d56Sopenharmony_ci if (Test-Path -Path Env:VIRTUAL_ENV) { 967db96d56Sopenharmony_ci Remove-Item -Path env:VIRTUAL_ENV 977db96d56Sopenharmony_ci } 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_ci # Just remove VIRTUAL_ENV_PROMPT altogether. 1007db96d56Sopenharmony_ci if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { 1017db96d56Sopenharmony_ci Remove-Item -Path env:VIRTUAL_ENV_PROMPT 1027db96d56Sopenharmony_ci } 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_ci # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: 1057db96d56Sopenharmony_ci if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { 1067db96d56Sopenharmony_ci Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force 1077db96d56Sopenharmony_ci } 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ci # Leave deactivate function in the global namespace if requested: 1107db96d56Sopenharmony_ci if (-not $NonDestructive) { 1117db96d56Sopenharmony_ci Remove-Item -Path function:deactivate 1127db96d56Sopenharmony_ci } 1137db96d56Sopenharmony_ci} 1147db96d56Sopenharmony_ci 1157db96d56Sopenharmony_ci<# 1167db96d56Sopenharmony_ci.Description 1177db96d56Sopenharmony_ciGet-PyVenvConfig parses the values from the pyvenv.cfg file located in the 1187db96d56Sopenharmony_cigiven folder, and returns them in a map. 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ciFor each line in the pyvenv.cfg file, if that line can be parsed into exactly 1217db96d56Sopenharmony_citwo strings separated by `=` (with any amount of whitespace surrounding the =) 1227db96d56Sopenharmony_cithen it is considered a `key = value` line. The left hand string is the key, 1237db96d56Sopenharmony_cithe right hand is the value. 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ciIf the value starts with a `'` or a `"` then the first and last character is 1267db96d56Sopenharmony_cistripped from the value before being captured. 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_ci.Parameter ConfigDir 1297db96d56Sopenharmony_ciPath to the directory that contains the `pyvenv.cfg` file. 1307db96d56Sopenharmony_ci#> 1317db96d56Sopenharmony_cifunction Get-PyVenvConfig( 1327db96d56Sopenharmony_ci [String] 1337db96d56Sopenharmony_ci $ConfigDir 1347db96d56Sopenharmony_ci) { 1357db96d56Sopenharmony_ci Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). 1387db96d56Sopenharmony_ci $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_ci # An empty map will be returned if no config file is found. 1417db96d56Sopenharmony_ci $pyvenvConfig = @{ } 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ci if ($pyvenvConfigPath) { 1447db96d56Sopenharmony_ci 1457db96d56Sopenharmony_ci Write-Verbose "File exists, parse `key = value` lines" 1467db96d56Sopenharmony_ci $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath 1477db96d56Sopenharmony_ci 1487db96d56Sopenharmony_ci $pyvenvConfigContent | ForEach-Object { 1497db96d56Sopenharmony_ci $keyval = $PSItem -split "\s*=\s*", 2 1507db96d56Sopenharmony_ci if ($keyval[0] -and $keyval[1]) { 1517db96d56Sopenharmony_ci $val = $keyval[1] 1527db96d56Sopenharmony_ci 1537db96d56Sopenharmony_ci # Remove extraneous quotations around a string value. 1547db96d56Sopenharmony_ci if ("'""".Contains($val.Substring(0, 1))) { 1557db96d56Sopenharmony_ci $val = $val.Substring(1, $val.Length - 2) 1567db96d56Sopenharmony_ci } 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_ci $pyvenvConfig[$keyval[0]] = $val 1597db96d56Sopenharmony_ci Write-Verbose "Adding Key: '$($keyval[0])'='$val'" 1607db96d56Sopenharmony_ci } 1617db96d56Sopenharmony_ci } 1627db96d56Sopenharmony_ci } 1637db96d56Sopenharmony_ci return $pyvenvConfig 1647db96d56Sopenharmony_ci} 1657db96d56Sopenharmony_ci 1667db96d56Sopenharmony_ci 1677db96d56Sopenharmony_ci<# Begin Activate script --------------------------------------------------- #> 1687db96d56Sopenharmony_ci 1697db96d56Sopenharmony_ci# Determine the containing directory of this script 1707db96d56Sopenharmony_ci$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition 1717db96d56Sopenharmony_ci$VenvExecDir = Get-Item -Path $VenvExecPath 1727db96d56Sopenharmony_ci 1737db96d56Sopenharmony_ciWrite-Verbose "Activation script is located in path: '$VenvExecPath'" 1747db96d56Sopenharmony_ciWrite-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" 1757db96d56Sopenharmony_ciWrite-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_ci# Set values required in priority: CmdLine, ConfigFile, Default 1787db96d56Sopenharmony_ci# First, get the location of the virtual environment, it might not be 1797db96d56Sopenharmony_ci# VenvExecDir if specified on the command line. 1807db96d56Sopenharmony_ciif ($VenvDir) { 1817db96d56Sopenharmony_ci Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" 1827db96d56Sopenharmony_ci} 1837db96d56Sopenharmony_cielse { 1847db96d56Sopenharmony_ci Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." 1857db96d56Sopenharmony_ci $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") 1867db96d56Sopenharmony_ci Write-Verbose "VenvDir=$VenvDir" 1877db96d56Sopenharmony_ci} 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_ci# Next, read the `pyvenv.cfg` file to determine any required value such 1907db96d56Sopenharmony_ci# as `prompt`. 1917db96d56Sopenharmony_ci$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ci# Next, set the prompt from the command line, or the config file, or 1947db96d56Sopenharmony_ci# just use the name of the virtual environment folder. 1957db96d56Sopenharmony_ciif ($Prompt) { 1967db96d56Sopenharmony_ci Write-Verbose "Prompt specified as argument, using '$Prompt'" 1977db96d56Sopenharmony_ci} 1987db96d56Sopenharmony_cielse { 1997db96d56Sopenharmony_ci Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" 2007db96d56Sopenharmony_ci if ($pyvenvCfg -and $pyvenvCfg['prompt']) { 2017db96d56Sopenharmony_ci Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" 2027db96d56Sopenharmony_ci $Prompt = $pyvenvCfg['prompt']; 2037db96d56Sopenharmony_ci } 2047db96d56Sopenharmony_ci else { 2057db96d56Sopenharmony_ci Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" 2067db96d56Sopenharmony_ci Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" 2077db96d56Sopenharmony_ci $Prompt = Split-Path -Path $venvDir -Leaf 2087db96d56Sopenharmony_ci } 2097db96d56Sopenharmony_ci} 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ciWrite-Verbose "Prompt = '$Prompt'" 2127db96d56Sopenharmony_ciWrite-Verbose "VenvDir='$VenvDir'" 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci# Deactivate any currently active virtual environment, but leave the 2157db96d56Sopenharmony_ci# deactivate function in place. 2167db96d56Sopenharmony_cideactivate -nondestructive 2177db96d56Sopenharmony_ci 2187db96d56Sopenharmony_ci# Now set the environment variable VIRTUAL_ENV, used by many tools to determine 2197db96d56Sopenharmony_ci# that there is an activated venv. 2207db96d56Sopenharmony_ci$env:VIRTUAL_ENV = $VenvDir 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ciif (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { 2237db96d56Sopenharmony_ci 2247db96d56Sopenharmony_ci Write-Verbose "Setting prompt to '$Prompt'" 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ci # Set the prompt to include the env name 2277db96d56Sopenharmony_ci # Make sure _OLD_VIRTUAL_PROMPT is global 2287db96d56Sopenharmony_ci function global:_OLD_VIRTUAL_PROMPT { "" } 2297db96d56Sopenharmony_ci Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT 2307db96d56Sopenharmony_ci New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt 2317db96d56Sopenharmony_ci 2327db96d56Sopenharmony_ci function global:prompt { 2337db96d56Sopenharmony_ci Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " 2347db96d56Sopenharmony_ci _OLD_VIRTUAL_PROMPT 2357db96d56Sopenharmony_ci } 2367db96d56Sopenharmony_ci $env:VIRTUAL_ENV_PROMPT = $Prompt 2377db96d56Sopenharmony_ci} 2387db96d56Sopenharmony_ci 2397db96d56Sopenharmony_ci# Clear PYTHONHOME 2407db96d56Sopenharmony_ciif (Test-Path -Path Env:PYTHONHOME) { 2417db96d56Sopenharmony_ci Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME 2427db96d56Sopenharmony_ci Remove-Item -Path Env:PYTHONHOME 2437db96d56Sopenharmony_ci} 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_ci# Add the venv to the PATH 2467db96d56Sopenharmony_ciCopy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH 2477db96d56Sopenharmony_ci$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" 248