# Source this file to sync and apply the PM environment; deactivate restores it. $ErrorActionPreference = 'Stop' $OutputEncoding = [System.Console]::OutputEncoding = [System.Console]::InputEncoding = [System.Text.Encoding]::UTF8 $PSDefaultParameterValues['*:Encoding'] = 'utf8' $repo = $PSScriptRoot $bootstrapSaved = @{} foreach ($key in @('PYTHONPATH', 'PYTHONHOME', 'VIRTUAL_ENV')) { $bootstrapSaved[$key] = [Environment]::GetEnvironmentVariable($key) Remove-Item "env:$key" -ErrorAction SilentlyContinue } try { # Run separately so setup's exit/failure cannot terminate the sourced shell. $shell = (Get-Process -Id $PID).Path & $shell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$repo\setup-hermes.ps1" -RuntimeOnly | Out-Host if ($LASTEXITCODE -ne 0) { throw 'activate: setup failed; shell environment unchanged' } } finally { foreach ($key in $bootstrapSaved.Keys) { if ($null -eq $bootstrapSaved[$key]) { Remove-Item "env:$key" -ErrorAction SilentlyContinue } else { Set-Item "env:$key" $bootstrapSaved[$key] } } } if (Test-Path function:deactivate) { deactivate } $py = $null foreach ($candidate in @("$repo\.venv\Scripts\python.exe", "$repo\venv\Scripts\python.exe")) { if (Test-Path -LiteralPath $candidate) { $py = $candidate; break } } if (-not $py) { $roots = @($env:HERMES_RUNTIME_DIR, "$repo\..\tools") $homeRoot = if ($env:HERMES_HOME) { $env:HERMES_HOME } else { "$env:LOCALAPPDATA\hermes" } $roots += (Join-Path $homeRoot 'tools') foreach ($root in $roots) { if (-not $root) { continue } foreach ($entry in @(Get-ChildItem -LiteralPath $root -Directory -Filter 'python-*' -ErrorAction SilentlyContinue)) { $candidate = Join-Path $entry.FullName 'python.exe' if (Test-Path -LiteralPath $candidate) { $py = $candidate; break } } if ($py) { break } } } if (-not $py) { throw 'activate: no bootstrap Python found; run setup-hermes.ps1' } $priorPath = $env:PYTHONPATH $priorHome = $env:PYTHONHOME try { $env:PYTHONPATH = $repo Remove-Item env:PYTHONHOME -ErrorAction SilentlyContinue $json = (& $py -m pm.environments) -join "`n" if ($LASTEXITCODE -ne 0) { throw 'activate: could not read the installed environment' } $composed = $json | ConvertFrom-Json } finally { if ($null -eq $priorPath) { Remove-Item env:PYTHONPATH -ErrorAction SilentlyContinue } else { $env:PYTHONPATH = $priorPath } if ($null -eq $priorHome) { Remove-Item env:PYTHONHOME -ErrorAction SilentlyContinue } else { $env:PYTHONHOME = $priorHome } } # __HERMES_ACTIVATED (the sentinel repo scripts and the shebang prologue read) # is part of the composed env, so it is saved and restored with the rest. $global:_hermesKeys = @($composed.PSObject.Properties.Name) $global:_hermesSaved = @{} foreach ($key in $global:_hermesKeys) { $global:_hermesSaved[$key] = [pscustomobject]@{ WasSet = (Test-Path "env:$key") Value = [Environment]::GetEnvironmentVariable($key) } } foreach ($property in $composed.PSObject.Properties) { Set-Item -Path "env:$($property.Name)" -Value ([string]$property.Value) } function global:deactivate { foreach ($key in $global:_hermesKeys) { $saved = $global:_hermesSaved[$key] if ($saved.WasSet) { Set-Item -Path "env:$key" -Value $saved.Value } else { Remove-Item -Path "env:$key" -ErrorAction SilentlyContinue } } $global:_hermesKeys = $null $global:_hermesSaved = $null Remove-Item function:deactivate }