Skip to content

Commit 9fa26cf

Browse files
committed
Install script using uv tool install for Bash and PowerShell.
1 parent c9a8f78 commit 9fa26cf

2 files changed

Lines changed: 389 additions & 0 deletions

File tree

scripts/install_seiscat_uv.ps1

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
#!/usr/bin/env pwsh
2+
# Copyright (c) 2021-2026 Claudio Satriano <satriano@ipgp.fr>
3+
# SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
<#
6+
.SYNOPSIS
7+
Install or update SeisCat with uv on Windows.
8+
9+
.DESCRIPTION
10+
This script:
11+
1) Checks if uv is installed and installs it if missing.
12+
2) Installs/updates SeisCat with optional plotting dependencies.
13+
3) Installs/updates argcomplete.
14+
4) Runs activate-global-python-argcomplete.
15+
16+
.PARAMETER DryRun
17+
Print planned commands without executing them.
18+
19+
.PARAMETER Help
20+
Show usage help and exit.
21+
22+
.EXAMPLE
23+
pwsh -NoProfile -File scripts/install_seiscat_uv.ps1
24+
25+
.EXAMPLE
26+
pwsh -NoProfile -File scripts/install_seiscat_uv.ps1 -DryRun
27+
28+
.EXAMPLE
29+
pwsh -NoProfile -File scripts/install_seiscat_uv.ps1 -Help
30+
#>
31+
32+
param(
33+
[switch]$DryRun,
34+
[Alias('h')][switch]$Help
35+
)
36+
37+
Set-StrictMode -Version Latest
38+
$ErrorActionPreference = 'Stop'
39+
40+
function Write-Info {
41+
param([Parameter(Mandatory = $true)][string]$Message)
42+
Write-Host "[INFO] $Message" -ForegroundColor Cyan
43+
}
44+
45+
function Write-Ok {
46+
param([Parameter(Mandatory = $true)][string]$Message)
47+
Write-Host "[OK] $Message" -ForegroundColor Green
48+
}
49+
50+
function Write-WarnMsg {
51+
param([Parameter(Mandatory = $true)][string]$Message)
52+
Write-Host "[WARN] $Message" -ForegroundColor Yellow
53+
}
54+
55+
function Fail {
56+
param([Parameter(Mandatory = $true)][string]$Message)
57+
Write-Host "[ERROR] $Message" -ForegroundColor Red
58+
exit 1
59+
}
60+
61+
function Show-Usage {
62+
@'
63+
Usage:
64+
pwsh -NoProfile -File scripts/install_seiscat_uv.ps1 [-DryRun] [-Help]
65+
66+
Options:
67+
-DryRun Print all steps and commands without executing them.
68+
-Help Show this help message and exit.
69+
'@ | Write-Host
70+
}
71+
72+
function Test-Command {
73+
param([Parameter(Mandatory = $true)][string]$Name)
74+
return $null -ne (Get-Command $Name -ErrorAction SilentlyContinue)
75+
}
76+
77+
function Invoke-StepCommand {
78+
param(
79+
[Parameter(Mandatory = $true)][string]$Display,
80+
[Parameter(Mandatory = $true)][scriptblock]$ScriptBlock
81+
)
82+
83+
Write-Info "Running: $Display"
84+
if ($DryRun) {
85+
Write-WarnMsg "Dry-run mode enabled: command not executed."
86+
return
87+
}
88+
89+
& $ScriptBlock
90+
}
91+
92+
function Update-PathForCurrentSession {
93+
$candidateDirs = @(
94+
(Join-Path $HOME ".local\\bin"),
95+
(Join-Path $HOME ".cargo\\bin")
96+
)
97+
98+
foreach ($dir in $candidateDirs) {
99+
if ((Test-Path $dir) -and ($env:PATH -notlike "*$dir*")) {
100+
$env:PATH = "$dir;$env:PATH"
101+
}
102+
}
103+
}
104+
105+
function Install-Uv {
106+
Write-Info "uv is not installed. Installing uv..."
107+
108+
if (Test-Command "winget") {
109+
Write-Info "Installing uv with winget..."
110+
Invoke-StepCommand -Display "winget install --id Astral-sh.uv -e --accept-package-agreements --accept-source-agreements" -ScriptBlock {
111+
winget install --id Astral-sh.uv -e --accept-package-agreements --accept-source-agreements
112+
}
113+
}
114+
elseif (Test-Command "scoop") {
115+
Write-Info "Installing uv with scoop..."
116+
Invoke-StepCommand -Display "scoop install uv" -ScriptBlock {
117+
scoop install uv
118+
}
119+
}
120+
elseif (Test-Command "choco") {
121+
Write-Info "Installing uv with chocolatey..."
122+
Invoke-StepCommand -Display "choco install uv -y" -ScriptBlock {
123+
choco install uv -y
124+
}
125+
}
126+
else {
127+
Write-Info "No package manager detected. Installing uv via official install script..."
128+
Invoke-StepCommand -Display "Invoke-RestMethod -Uri https://astral.sh/uv/install.ps1 | run" -ScriptBlock {
129+
& ([scriptblock]::Create((Invoke-RestMethod -Uri "https://astral.sh/uv/install.ps1")))
130+
}
131+
}
132+
133+
Update-PathForCurrentSession
134+
135+
if ($DryRun) {
136+
Write-Ok "uv installation skipped in dry-run mode."
137+
return
138+
}
139+
140+
if (-not (Test-Command "uv")) {
141+
Fail "uv installation did not complete successfully. Open a new terminal and retry."
142+
}
143+
144+
Write-Ok "uv installed successfully: $(uv --version)"
145+
}
146+
147+
function Activate-Argcomplete {
148+
Write-Info "Step 4/4: Running activate-global-python-argcomplete..."
149+
150+
$activationCmd = Get-Command "activate-global-python-argcomplete" -ErrorAction SilentlyContinue
151+
152+
if ($null -ne $activationCmd) {
153+
try {
154+
Invoke-StepCommand -Display "activate-global-python-argcomplete --user" -ScriptBlock {
155+
& $activationCmd.Source --user
156+
}
157+
Write-Ok "Global argcomplete activation completed (--user mode)."
158+
}
159+
catch {
160+
Write-WarnMsg "activate-global-python-argcomplete --user failed. Retrying without --user..."
161+
Invoke-StepCommand -Display "activate-global-python-argcomplete" -ScriptBlock {
162+
& $activationCmd.Source
163+
}
164+
Write-Ok "Global argcomplete activation completed."
165+
}
166+
return
167+
}
168+
169+
Write-WarnMsg "activate-global-python-argcomplete is not on PATH. Trying via uv tool run..."
170+
try {
171+
Invoke-StepCommand -Display "uv tool run --from argcomplete activate-global-python-argcomplete --user" -ScriptBlock {
172+
uv tool run --from argcomplete activate-global-python-argcomplete --user
173+
}
174+
Write-Ok "Global argcomplete activation completed via uv tool run (--user mode)."
175+
}
176+
catch {
177+
Write-WarnMsg "argcomplete activation command failed on this shell."
178+
Write-WarnMsg "On Windows, this command mainly targets bash-like shells."
179+
Write-WarnMsg "If you use Git Bash, run activate-global-python-argcomplete there."
180+
}
181+
}
182+
183+
if ($Help) {
184+
Show-Usage
185+
exit 0
186+
}
187+
188+
Write-Info "Starting SeisCat installation with uv for Windows..."
189+
190+
if ($DryRun) {
191+
Write-WarnMsg "Dry-run mode enabled: no commands will be executed and no files will be modified."
192+
}
193+
194+
Write-Info "Step 1/4: Checking if uv is installed..."
195+
if (Test-Command "uv") {
196+
Write-Ok "uv is already installed: $(uv --version)"
197+
}
198+
else {
199+
Install-Uv
200+
}
201+
202+
Write-Info "Step 2/4: Installing/updating seiscat with plotly, cartopy, folium, and pandas support using uv tool install..."
203+
Invoke-StepCommand -Display "uv tool install seiscat --with plotly --with cartopy --with folium --with pandas --upgrade --force" -ScriptBlock {
204+
uv tool install seiscat --with plotly --with cartopy --with folium --with pandas --upgrade --force
205+
}
206+
Write-Ok "seiscat installed/updated with plotly, cartopy, folium, and pandas support."
207+
208+
Write-Info "Step 3/4: Installing/updating argcomplete using uv tool install..."
209+
Invoke-StepCommand -Display "uv tool install argcomplete --upgrade --force" -ScriptBlock {
210+
uv tool install argcomplete --upgrade --force
211+
}
212+
Write-Ok "argcomplete installed/updated successfully."
213+
214+
Activate-Argcomplete
215+
216+
Write-Ok "All steps completed."
217+
Write-Info "If seiscat is not found in this terminal, open a new terminal window and try again."

scripts/install_seiscat_uv.sh

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#!/usr/bin/env bash
2+
# Copyright (c) 2021-2026 Claudio Satriano <satriano@ipgp.fr>
3+
# SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
set -euo pipefail
6+
7+
DRY_RUN=false
8+
9+
if [ -t 1 ]; then
10+
C_RESET='\033[0m'
11+
C_BLUE='\033[1;34m'
12+
C_GREEN='\033[1;32m'
13+
C_YELLOW='\033[1;33m'
14+
C_RED='\033[1;31m'
15+
else
16+
C_RESET=''
17+
C_BLUE=''
18+
C_GREEN=''
19+
C_YELLOW=''
20+
C_RED=''
21+
fi
22+
23+
info() {
24+
printf '%b[INFO]%b %s\n' "$C_BLUE" "$C_RESET" "$1"
25+
}
26+
27+
ok() {
28+
printf '%b[OK]%b %s\n' "$C_GREEN" "$C_RESET" "$1"
29+
}
30+
31+
warn() {
32+
printf '%b[WARN]%b %s\n' "$C_YELLOW" "$C_RESET" "$1"
33+
}
34+
35+
fail() {
36+
printf '%b[ERROR]%b %s\n' "$C_RED" "$C_RESET" "$1" >&2
37+
exit 1
38+
}
39+
40+
parse_args() {
41+
if [ "${1:-}" = '--dry-run' ]; then
42+
DRY_RUN=true
43+
shift
44+
elif [ "${1:-}" = '-h' ] || [ "${1:-}" = '--help' ]; then
45+
echo 'Usage: scripts/install_seiscat_uv.sh [--dry-run]'
46+
exit 0
47+
fi
48+
49+
if [ $# -ne 0 ]; then
50+
fail "Unknown argument: $1"
51+
fi
52+
}
53+
54+
run_cmd() {
55+
info "Running: $*"
56+
if [ "$DRY_RUN" = true ]; then
57+
warn 'Dry-run mode enabled: command not executed.'
58+
return 0
59+
fi
60+
"$@"
61+
}
62+
63+
activate_argcomplete() {
64+
local shell_name
65+
local zsh_marker='# >>> seiscat argcomplete >>>'
66+
local zsh_end_marker='# <<< seiscat argcomplete <<<'
67+
68+
shell_name="$(basename "${SHELL:-}")"
69+
70+
if run_cmd activate-global-python-argcomplete --user; then
71+
ok 'Legacy global argcomplete activation completed (--user mode).'
72+
else
73+
warn 'activate-global-python-argcomplete --user failed.'
74+
warn 'Retrying without --user (may require elevated permissions)...'
75+
run_cmd activate-global-python-argcomplete
76+
ok 'Legacy global argcomplete activation completed.'
77+
fi
78+
79+
if [ "$shell_name" = 'zsh' ]; then
80+
info 'Applying zsh-specific completion snippet for seiscat...'
81+
if [ "$DRY_RUN" = true ]; then
82+
warn 'Dry-run mode enabled: ~/.zshrc will not be modified.'
83+
return 0
84+
fi
85+
touch "$HOME/.zshrc"
86+
if grep -Fq "$zsh_marker" "$HOME/.zshrc"; then
87+
awk -v start="$zsh_marker" -v end="$zsh_end_marker" '
88+
$0 == start { in_block = 1; next }
89+
$0 == end { in_block = 0; next }
90+
!in_block { print }
91+
' "$HOME/.zshrc" > "$HOME/.zshrc.tmp"
92+
mv "$HOME/.zshrc.tmp" "$HOME/.zshrc"
93+
info 'Updated existing managed zsh completion snippet in ~/.zshrc.'
94+
fi
95+
96+
{
97+
printf '\n%s\n' "$zsh_marker"
98+
printf 'autoload -U compinit\n'
99+
printf 'if ! typeset -f compdef >/dev/null 2>&1; then\n'
100+
printf ' compinit\n'
101+
printf 'fi\n'
102+
printf 'autoload -U +X bashcompinit && bashcompinit\n'
103+
printf "eval \"\$(register-python-argcomplete seiscat)\"\n"
104+
printf '%s\n' "$zsh_end_marker"
105+
} >> "$HOME/.zshrc"
106+
ok 'Installed zsh completion snippet in ~/.zshrc.'
107+
info 'Open a new terminal or run: source ~/.zshrc'
108+
fi
109+
}
110+
111+
install_uv() {
112+
info 'uv is not installed. Installing uv...'
113+
114+
if command -v curl >/dev/null 2>&1; then
115+
info 'Running: curl -LsSf https://astral.sh/uv/install.sh | sh'
116+
if [ "$DRY_RUN" = false ]; then
117+
curl -LsSf https://astral.sh/uv/install.sh | sh
118+
else
119+
warn 'Dry-run mode enabled: command not executed.'
120+
fi
121+
elif command -v wget >/dev/null 2>&1; then
122+
info 'Running: wget -qO- https://astral.sh/uv/install.sh | sh'
123+
if [ "$DRY_RUN" = false ]; then
124+
wget -qO- https://astral.sh/uv/install.sh | sh
125+
else
126+
warn 'Dry-run mode enabled: command not executed.'
127+
fi
128+
else
129+
fail 'Neither curl nor wget is available. Install one of them, then re-run this script.'
130+
fi
131+
132+
export PATH="$HOME/.local/bin:$PATH"
133+
134+
if [ "$DRY_RUN" = true ]; then
135+
ok 'uv installation skipped in dry-run mode.'
136+
return 0
137+
fi
138+
139+
if ! command -v uv >/dev/null 2>&1; then
140+
fail 'uv installation did not complete successfully. Add ~/.local/bin to PATH and retry.'
141+
fi
142+
143+
ok 'uv installed successfully.'
144+
}
145+
146+
main() {
147+
info 'Starting SeisCat installation with uv for Linux/macOS/WSL...'
148+
149+
info 'Step 1/4: Checking if uv is installed...'
150+
if command -v uv >/dev/null 2>&1; then
151+
ok "uv is already installed: $(uv --version)"
152+
else
153+
install_uv
154+
fi
155+
156+
info 'Step 2/4: Installing/updating seiscat with plotly, cartopy, folium, and pandas support using uv tool install...'
157+
run_cmd uv tool install seiscat --with plotly --with cartopy --with folium --with pandas --upgrade --force
158+
ok 'seiscat installed/updated with plotly, cartopy, folium, and pandas support.'
159+
160+
info 'Step 3/4: Installing argcomplete using uv tool install...'
161+
run_cmd uv tool install argcomplete --upgrade --force
162+
ok 'argcomplete installed successfully.'
163+
164+
info 'Step 4/4: Running activate-global-python-argcomplete...'
165+
activate_argcomplete
166+
167+
ok 'All steps completed.'
168+
info 'If seiscat is not found in your shell, restart your terminal or ensure ~/.local/bin is in PATH.'
169+
}
170+
171+
parse_args "$@"
172+
main

0 commit comments

Comments
 (0)