Skip to content

Commit 4ddcf30

Browse files
authored
Add Enter-IronPythonEnvironment.ps1 (#1437)
* Add Enter-IronPythonEnvironment.ps1 * Add parameter PromptColor * Include enter env script when creating environments * Make script runnable on PS Desktop Edition * Save in UTF-8-BOM * Use lowercase lib directory name on Unix * Add subdir Scripts to PATH on Windows * Revert "Use lowercase lib directory name on Unix"
1 parent 0c086dd commit 4ddcf30

2 files changed

Lines changed: 156 additions & 3 deletions

File tree

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Licensed to the .NET Foundation under one or more agreements.
2+
# The .NET Foundation licenses this file to you under the Apache 2.0 License.
3+
# See the LICENSE file in the project root for more information.
4+
5+
<#
6+
.SYNOPSIS
7+
8+
Activates an IronPython environment, placing its commands at the head of $Env:PATH.
9+
10+
.DESCRIPTION
11+
12+
This script modifies the current PowerShell environment such that a given IronPython installation becomes the active one. By default, the installation containing this script is being activated, or, if the script is not part of an installation, the latest MSI-installed version of IronPython (Windows only).
13+
14+
IronPython environments do not nest. Entering a new environment from within an active environment automatically exits the current one.
15+
16+
The following modifications are made:
17+
18+
* The Env:PATH variable is modified by adding the path to the environment commands at the beginning of the existing list of paths.
19+
* The PowerShell prompt is modified to display the name of the environment.
20+
* A new function Exit-IronPythonEnvironment is defined, with an alias "exipy". Use this function to undo all modifications done on entering.
21+
22+
When switch -Isolated is used, additional modifications are performed:
23+
24+
* Variable Env:IRONPYTHONPATH is cleared.
25+
* Alias:ipy, if exists, is deleted.
26+
* Function:ipy, if exists, is deleted.
27+
#>
28+
[CmdletBinding()]
29+
param (
30+
# Path to an IronPython environment to enter.
31+
[Parameter(Position=0)]
32+
[SupportsWildcards()]
33+
[string] $Path,
34+
35+
# On enter, unset Env:IRONPYTHONPATH, Alias:ipy, and Function:ipy. Restore on exit.
36+
[switch] $Isolated,
37+
38+
# Color of the environment name printed on the prompt.
39+
[ConsoleColor] $PromptColor = [ConsoleColor]::DarkGray
40+
)
41+
42+
if (-not $Path) {
43+
# Locate default environment to activate
44+
if (Test-Path (Join-Path $PSScriptRoot "IronPython.dll")) {
45+
$Path = $PSScriptRoot
46+
} elseif ($IsWindows -and (Test-Path HKLM:\SOFTWARE\IronPython\*\InstallPath)) {
47+
$installKey = (Resolve-Path HKLM:\SOFTWARE\IronPython\*\InstallPath)[-1] # grab the latest
48+
$Path = Get-ItemPropertyValue -Path $installKey -Name '(default)'
49+
} else {
50+
Write-Error "Cannot locate default environment."
51+
exit 1
52+
}
53+
}
54+
55+
if (-not (Test-Path $Path -PathType Container)) {
56+
Write-Error "Environment not found: $Path"
57+
exit 1
58+
}
59+
60+
if ((Resolve-Path $Path).Count -gt 1) {
61+
Write-Error "Environment path resolved to multiple locations:"
62+
Resolve-Path $Path | Write-Error
63+
exit 1
64+
}
65+
66+
function global:Exit-IronPythonEnvironment ([switch] $NonDestructive) {
67+
<#
68+
.SYNOPSIS
69+
Undo all environment modifications done by Enter-IronPythonEnvironment
70+
71+
.PARAMETER NonDestructive
72+
Keep function Exit-IronPythonEnvironment and its alias. Subsequent invocations of this function while not within an IronPython environment will result in no-op.
73+
#>
74+
75+
if (Test-Path Function:IronPythonParentPrompt) {
76+
Copy-Item Function:IronPythonParentPrompt Function:prompt
77+
Remove-Item Function:IronPythonParentPrompt
78+
}
79+
80+
if (Test-Path Variable:IronPythonParentEnvironment) {
81+
$Env:IRONPYTHONPATH = $IronPythonParentEnvironment["libpath"]
82+
$Env:PATH = $IronPythonParentEnvironment["binpath"]
83+
84+
$oldAlias = $IronPythonParentEnvironment["alias"]
85+
if ($null -ne $oldAlias) {
86+
Set-Alias -Name ipy `
87+
-Value $oldAlias.Definition `
88+
-Description $oldAlias.Description `
89+
-Option $oldAlias.Options `
90+
-Scope global
91+
}
92+
if ($null -ne $IronPythonParentEnvironment["function"]) {
93+
Copy-Item $IronPythonParentEnvironment["function"] Function:ipy
94+
}
95+
Remove-Item Variable:IronPythonParentEnvironment
96+
}
97+
98+
Remove-Variable -Name IronPythonEnvironment* -Scope global
99+
100+
if (-not $NonDestructive) {
101+
Remove-Item Function:Exit-IronPythonEnvironment
102+
Remove-Item Alias:exipy -ErrorAction Ignore
103+
}
104+
}
105+
106+
Exit-IronPythonEnvironment -NonDestructive
107+
108+
$global:IronPythonEnvironmentPath = Resolve-Path $Path
109+
$global:IronPythonEnvironmentName = Split-Path $IronPythonEnvironmentPath -Leaf
110+
$global:IronPythonEnvironmentColor = "$PromptColor"
111+
112+
# Save stuff that already exists
113+
114+
$global:IronPythonParentEnvironment = @{ "binpath" = $Env:PATH }
115+
116+
if ($Isolated) {
117+
if (Test-Path Alias:ipy) {
118+
$IronPythonParentEnvironment["alias"] = Get-Item Alias:ipy
119+
Remove-Item Alias:ipy
120+
}
121+
122+
if (Test-Path Function:ipy) {
123+
$IronPythonParentEnvironment["function"] = Get-Item function:ipy
124+
Remove-Item Function:ipy
125+
}
126+
127+
if (Test-Path Env:IRONPYTHONPATH) {
128+
$IronPythonParentEnvironment["libpath"] = $Env:IRONPYTHONPATH
129+
Remove-Item Env:IRONPYTHONPATH
130+
}
131+
}
132+
133+
function global:IronPythonParentPrompt {""}
134+
Copy-Item Function:prompt Function:IronPythonParentPrompt
135+
136+
# Set new stuff for the environment to be operational
137+
138+
function global:prompt {
139+
Write-Host -NoNewline -ForegroundColor $IronPythonEnvironmentColor "«$IronPythonEnvironmentName» "
140+
IronPythonParentPrompt
141+
}
142+
143+
[string[]] $newEnvPaths = @($IronPythonEnvironmentPath)
144+
if ($IsWindows) {
145+
$newEnvPaths += Join-Path $IronPythonEnvironmentPath "Scripts"
146+
}
147+
$newEnvPaths += $env:PATH
148+
$env:PATH = $newEnvPaths -join [IO.Path]::PathSeparator
149+
150+
Set-Alias exipy Exit-IronPythonEnvironment -Scope global

Src/Scripts/Install-IronPython.ps1

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ if ($IsMacOS -or $IsLinux) {
8383
# Add items that are missing in the zip file, directly from the bin directory
8484
if ($projectRoot) {
8585
$binPath = Join-Path $projectRoot "bin/Release/net6.0"
86-
Copy-Item (Join-Path $binPath "ipy") $Path
87-
if ($IsMacOS -or $IsLinux) {
86+
Copy-Item (Join-Path $projectRoot "Src/Scripts/Enter-IronPythonEnvironment.ps1") $Path
87+
if ($IsWindows){
88+
Copy-Item (Join-Path $binPath "ipy.exe") $Path
89+
} else {
90+
Copy-Item (Join-Path $binPath "ipy") $Path
8891
Copy-Item (Join-Path $binPath "Mono.Unix.dll") $Path
8992
$arch = uname -m
9093
switch ($arch) {
@@ -98,4 +101,4 @@ if ($projectRoot) {
98101
$libs = Join-Path $binPath "runtimes" "$os-$arch" "native/*" -Resolve
99102
Copy-Item $libs $Path
100103
}
101-
}
104+
}

0 commit comments

Comments
 (0)