Skip to content

Commit 36563c0

Browse files
authored
Add the installation script to facilitate the AIShell installation and uninstallation (#285)
1 parent 79f2c77 commit 36563c0

File tree

1 file changed

+207
-0
lines changed

1 file changed

+207
-0
lines changed

tools/scripts/install-aishell.ps1

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
param(
5+
[Parameter(HelpMessage = "Specify this parameter to uninstall AI Shell")]
6+
[switch] $Uninstall
7+
)
8+
9+
$Script:MacSymbolicLink = '/usr/local/bin/aish'
10+
$Script:MacInstallationLocation = "/usr/local/AIShell"
11+
$Script:WinInstallationLocation = "$env:LOCALAPPDATA\Programs\AIShell"
12+
$Script:InstallLocation = $null
13+
$Script:PackageURL = $null
14+
15+
function Resolve-Environment {
16+
if ($PSVersionTable.PSVersion -lt [version]"7.4.6") {
17+
throw "PowerShell v7.4.6 or higher is required for using the AIShell module. You can download it at https://github.com/PowerShell/PowerShell/releases/tag/v7.4.6 "
18+
}
19+
if ($IsLinux) {
20+
throw "Sorry, this install script is only compatible with Windows and macOS. If you want to install on Linux, please download the package directly from the GitHub repo at aka.ms/AIShell-Repo."
21+
}
22+
23+
($platShortName, $platFullName, $pkgExt, $location) = if ($IsWindows) {
24+
'win', 'Windows', 'zip', $Script:WinInstallationLocation
25+
} else {
26+
'osx', 'macOS', 'tar.gz', $Script:MacInstallationLocation
27+
}
28+
29+
$architecture = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString()
30+
if ($architecture -notin @('X86', 'X64', 'Arm64')) {
31+
throw "AI Shell doesn't support the $architecture architecture on $platFullName."
32+
}
33+
34+
$Script:InstallLocation = $location
35+
$Script:PackageURL = "https://github.com/PowerShell/AIShell/releases/download/v1.0.0-preview.1/AIShell-1.0.0-preview.1-${platShortName}-$($architecture.ToLower()).${pkgExt}"
36+
}
37+
38+
function Install-AIShellApp {
39+
[CmdletBinding()]
40+
param()
41+
42+
$destination = $Script:InstallLocation
43+
$packageUrl = $Script:PackageURL
44+
45+
$destinationExists = Test-Path -Path $destination
46+
if ($destinationExists) {
47+
$anyFile = Get-ChildItem -Path $destination | Select-Object -First 1
48+
if ($anyFile) {
49+
$remove = $PSCmdlet.ShouldContinue("Do you want to remove it for a new installation?", "AI Shell was already installed (or partially installed) at '$destination'.")
50+
if ($remove) {
51+
$destinationExists = $false
52+
if ($IsWindows) {
53+
Remove-Item -Path $destination -Recurse -Force -ErrorAction Stop
54+
} else {
55+
sudo rm -rf $destination
56+
if ($LASTEXITCODE -ne 0) {
57+
throw "Failed to remove '$destination'."
58+
}
59+
}
60+
} else {
61+
throw "Operation cancelled. You can remove the current installation by './install-aishell.ps1 -Uninstall' and try again."
62+
}
63+
}
64+
}
65+
66+
if (-not $destinationExists) {
67+
# Create the directory if not existing.
68+
if ($IsWindows) {
69+
$null = New-Item -Path $destination -ItemType Directory -Force
70+
} else {
71+
# '/usr/local' requires sudo.
72+
sudo mkdir $destination
73+
if ($LASTEXITCODE -ne 0) {
74+
throw "Failed to create the installation folder '$destination'."
75+
}
76+
}
77+
}
78+
79+
$fileName = [System.IO.Path]::GetFileName($packageUrl)
80+
$tempPath = Join-Path ([System.IO.Path]::GetTempPath()) $fileName
81+
if (Test-Path $tempPath) {
82+
Remove-Item $tempPath -Force -ErrorAction Stop
83+
}
84+
85+
# Download AIShell package.
86+
Write-Host "Downloading AI Shell package '$fileName' ..."
87+
Invoke-WebRequest -Uri $packageUrl -OutFile $tempPath -ErrorAction Stop
88+
89+
try {
90+
# Extract AIShell package.
91+
Write-Host "Extracting AI Shell to '$destination' ..."
92+
Unblock-File -Path $tempPath
93+
if ($IsWindows) {
94+
Expand-Archive -Path $tempPath -DestinationPath $destination -Force -ErrorAction Stop
95+
96+
# Set the process-scope and user-scope Path env variables to include AIShell.
97+
$envPath = $env:Path
98+
if (-not $envPath.Contains($destination)) {
99+
Write-Host "Adding AI Shell app to the Path environment variable ..."
100+
$env:Path = "${destination};${envPath}"
101+
$userPath = [Environment]::GetEnvironmentVariable('Path', [EnvironmentVariableTarget]::User)
102+
$newUserPath = $userPath.EndsWith(';') ? "${userPath}${destination}" : "${userPath};${destination}"
103+
[Environment]::SetEnvironmentVariable('Path', $newUserPath, [EnvironmentVariableTarget]::User)
104+
}
105+
} else {
106+
sudo tar -xzf $tempPath -C $destination
107+
if ($LASTEXITCODE -ne 0) {
108+
throw "Failed to extract '$tempPath' to the folder '$destination'."
109+
}
110+
111+
$aishPath = Join-Path $destination 'aish'
112+
sudo chmod +x $aishPath
113+
if ($LASTEXITCODE -ne 0) {
114+
throw "Failed to set the execution permission to the executable '$aishPath'."
115+
}
116+
117+
# No need to setup the Path env variable as the symbolic link is already within Path.
118+
$symlink = $Script:MacSymbolicLink
119+
if (-not (Test-Path -Path $symlink)) {
120+
sudo ln -s $aishPath $symlink
121+
if ($LASTEXITCODE -ne 0) {
122+
throw "Failed to create the symbolic link '$symlink' to '$aishPath'."
123+
}
124+
}
125+
}
126+
} finally {
127+
if (Test-Path -Path $tempPath) {
128+
Remove-Item -Path $tempPath -Force -ErrorAction SilentlyContinue
129+
}
130+
}
131+
}
132+
133+
function Uninstall-AIShellApp {
134+
$destination = $Script:InstallLocation
135+
if (Test-Path $destination) {
136+
Write-Host "Removing AI Shell app from '$destination' ..."
137+
if ($IsWindows) {
138+
Remove-Item -Path $destination -Recurse -Force -ErrorAction Stop
139+
140+
# Update the user-scope Path env variables to remove AIShell.
141+
$userPath = [Environment]::GetEnvironmentVariable('Path', [EnvironmentVariableTarget]::User)
142+
if ($userPath.Contains($destination)) {
143+
Write-Host "Removing AI Shell app from the user-scope Path environment variable ..."
144+
$newUserPath = $userPath.Split(';', [StringSplitOptions]::RemoveEmptyEntries -bor [StringSplitOptions]::TrimEntries) |
145+
Where-Object { $_ -ne $destination } |
146+
Join-String -Separator ';'
147+
[Environment]::SetEnvironmentVariable("Path", $newUserPath, [EnvironmentVariableTarget]::User)
148+
}
149+
} else {
150+
sudo rm -rf $destination
151+
if ($LASTEXITCODE -ne 0) {
152+
throw "Failed to remove the AIShell app from '$destination'."
153+
}
154+
155+
$symlink = $Script:MacSymbolicLink
156+
sudo rm $symlink
157+
if ($LASTEXITCODE -ne 0) {
158+
throw "Failed to remove the symbolic link '$symlink'."
159+
}
160+
}
161+
} else {
162+
Write-Host "AI Shell app was not found at '$destination'. Skip removing it."
163+
}
164+
}
165+
166+
function Install-AIShellModule {
167+
if ($IsWindows) {
168+
Write-Host "Installing the PowerShell module 'AIShell' ..."
169+
Install-PSResource -Name AIShell -Repository PSGallery -Prerelease -TrustRepository -ErrorAction Stop -WarningAction SilentlyContinue
170+
} else {
171+
Write-Host -ForegroundColor Yellow "Currently the AIShell PowerShell module will only work in iTerm2 terminal and still has limited support but if you would like to test it, you can install it with 'Install-PSResource -Name AIShell -Repository PSGallery -Prerelease'."
172+
Write-Host -ForegroundColor Yellow "The AI Shell app has been added to your path, please run 'aish' to use the standalone experience."
173+
}
174+
}
175+
176+
function Uninstall-AIShellModule {
177+
if (Get-InstalledPSResource -Name "AIShell" -ErrorAction SilentlyContinue) {
178+
try {
179+
Write-Host "Uninstalling AIShell Module ..."
180+
Uninstall-PSResource -Name AIShell -ErrorAction Stop
181+
} catch {
182+
throw "Failed to uninstall the 'AIShell' module. Please check if the module got imported in any active PowerShell session. If so, please exit the session and try this script again."
183+
}
184+
}
185+
}
186+
187+
<###################################
188+
#
189+
# Setup/Execute
190+
#
191+
###################################>
192+
193+
Resolve-Environment
194+
195+
if ($Uninstall) {
196+
Uninstall-AIShellApp
197+
Uninstall-AIShellModule
198+
199+
$message = $IsWindows ? "AI Shell App and PowerShell module have" : "AI Shell App has"
200+
Write-Host "`n$message been successfully uninstalled." -ForegroundColor Green
201+
} else {
202+
Install-AIShellApp
203+
Install-AIShellModule
204+
205+
$message = $IsWindows ? "'Start-AIShell'" : "'aish'"
206+
Write-Host "`nInstallation succeeded. To learn more about AI Shell please visit https://aka.ms/AIShell-Docs. To get started please run $message to start AI Shell." -ForegroundColor Green
207+
}

0 commit comments

Comments
 (0)