diff --git a/powershell/download-tea.ps1 b/powershell/download-tea.ps1 new file mode 100644 index 0000000..24a5de3 --- /dev/null +++ b/powershell/download-tea.ps1 @@ -0,0 +1,258 @@ +<# +.SYNOPSIS + Downloads and installs the Gitea Tea CLI tool for Windows. + +.DESCRIPTION + This script automatically downloads, verifies, and installs the Tea CLI (Gitea command-line tool). + It supports automatic detection of the latest version, SHA256 checksum verification, and intelligent + installation location based on administrator privileges. + +.PARAMETER TeaVersion + Specifies the version of Tea to install. If not provided, the script will automatically fetch + the latest version from the Gitea releases page. + +.PARAMETER Force + Bypasses the overwrite confirmation prompt if Tea is already installed. + +.EXAMPLE + .\download-tea.ps1 + Automatically detects and installs the latest version of Tea. + +.EXAMPLE + .\download-tea.ps1 -TeaVersion "0.11.1" + Installs a specific version of Tea (v0.11.1). + +.EXAMPLE + .\download-tea.ps1 -Force + Installs the latest version and overwrites any existing installation without prompting. + +.EXAMPLE + .\download-tea.ps1 -TeaVersion "0.11.1" -Force + Installs version 0.11.1 and overwrites existing installation without prompting. + +.NOTES + - Requires internet connection to download from https://gitea.com + - Automatically detects system architecture (AMD64 or 386) + - Installation location: + * With Admin rights: C:\Program Files\tea + * Without Admin rights: %LOCALAPPDATA%\Programs\tea + - Automatically updates PATH environment variable + - After installation, restart your terminal or reload PATH with: + $env:Path = [System.Environment]::GetEnvironmentVariable("Path","User") + ";" + [System.Environment]::GetEnvironmentVariable("Path","Machine") + +.LINK + https://gitea.com/gitea/tea +#> + +# Parameters +param( + [string]$TeaVersion, + [switch]$Force +) + +# 1. Determine version to install +if (-not $TeaVersion) { + Write-Host "No version specified. Fetching latest release..." + try { + # Fetch the releases page and parse HTML to find the latest version + $releasePage = Invoke-WebRequest -Uri "https://gitea.com/gitea/tea/releases" -UseBasicParsing -ErrorAction Stop + # Parse the HTML to find the latest version tag (format: /gitea/tea/releases/tag/v0.x.x) + if ($releasePage.Content -match '/gitea/tea/releases/tag/v([\d.]+)') { + $TeaVersion = $matches[1] + Write-Host "Latest version found: v$TeaVersion" -ForegroundColor Green + } + else { + Write-Error "Could not determine the latest version from the releases page." + Write-Host "Please specify a version manually using -TeaVersion parameter." + exit 1 + } + } + catch { + Write-Error "Failed to fetch latest version: $($_.Exception.Message)" + Write-Host "Please specify a version manually using -TeaVersion parameter." + exit 1 + } +} +else { + Write-Host "Using specified version: v$TeaVersion" +} + +# 2. Define variables for the download +# Detect system architecture (AMD64 = 64-bit, 386 = 32-bit) +$Architecture = if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") { "amd64" } else { "386" } + +# Construct download URLs +$DownloadUrl = "https://gitea.com/gitea/tea/releases/download/v$TeaVersion/tea-$TeaVersion-windows-$Architecture.exe" +$ChecksumUrl = "https://gitea.com/gitea/tea/releases/download/v$TeaVersion/checksums.txt" + +# Determine installation directory based on admin privileges +# Admin: Install to Program Files (system-wide) +# Non-Admin: Install to user's AppData (user-specific) +$IsAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) +$InstallDir = if ($IsAdmin) { "C:\Program Files\tea" } else { "$env:LOCALAPPDATA\Programs\tea" } + +# Define file names and temp locations +$FileName = "tea.exe" +$TempFile = "$env:TEMP\tea-$TeaVersion.exe" +$TempChecksum = "$env:TEMP\tea-checksums.txt" + +# 3. Check if file already exists +if ((Test-Path -Path "$InstallDir\$FileName") -and -not $Force) { + # Prompt user before overwriting existing installation + $response = Read-Host "tea.exe already exists in $InstallDir. Overwrite? (Y/N)" + if ($response -ne 'Y' -and $response -ne 'y') { + Write-Host "Installation cancelled." + exit 0 + } +} + +# 4. Create the installation directory if it doesn't exist +Write-Host "Creating installation directory: $InstallDir" +if (-not (Test-Path -Path $InstallDir)) { + New-Item -Path $InstallDir -ItemType Directory -Force | Out-Null +} + +# 5. Download the binary and checksum +Write-Host "Downloading tea CLI v$TeaVersion for $Architecture..." +try { + # Download to temp location first for safety + Invoke-WebRequest -Uri $DownloadUrl -OutFile $TempFile -UseBasicParsing -ErrorAction Stop + Write-Host "Binary downloaded successfully." +} +catch { + Write-Error "Failed to download the file. Please check the URL and version number. Error: $($_.Exception.Message)" + # Cleanup temp files on failure + Remove-Item -Path $TempFile -ErrorAction SilentlyContinue + exit 1 +} + +# Try to download checksum file for verification (optional but recommended) +$checksumAvailable = $false +try { + Write-Host "Attempting to download checksum file..." + Invoke-WebRequest -Uri $ChecksumUrl -OutFile $TempChecksum -UseBasicParsing -ErrorAction Stop + $checksumAvailable = $true + Write-Host "Checksum file downloaded." +} +catch { + Write-Warning "Checksum file not available for this version. Skipping verification." +} + +# 6. Verify checksum (if available) +if ($checksumAvailable) { + Write-Host "Verifying file integrity..." + try { + # Calculate SHA256 hash of downloaded file + $downloadedHash = (Get-FileHash -Path $TempFile -Algorithm SHA256).Hash.ToLower() + + # Parse checksums.txt to find the hash for our specific file + $expectedFileName = "tea-$TeaVersion-windows-$Architecture.exe" + $checksumContent = Get-Content -Path $TempChecksum -Raw + $expectedHash = $null + + # checksums.txt format is: "hash filename" + foreach ($line in ($checksumContent -split "`n")) { + if ($line -match "^([a-fA-F0-9]+)\s+$expectedFileName") { + $expectedHash = $matches[1].ToLower() + break + } + } + + if (-not $expectedHash) { + Write-Warning "Could not find checksum for $expectedFileName in checksums.txt" + $response = Read-Host "Continue without checksum verification? (Y/N)" + if ($response -ne 'Y' -and $response -ne 'y') { + Remove-Item -Path $TempFile -ErrorAction SilentlyContinue + Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue + exit 1 + } + } + elseif ($downloadedHash -eq $expectedHash) { + Write-Host "Checksum verification passed." -ForegroundColor Green + } + else { + Write-Error "Checksum verification failed! Downloaded file may be corrupted or tampered with." + Write-Error "Expected: $expectedHash" + Write-Error "Got: $downloadedHash" + Remove-Item -Path $TempFile -ErrorAction SilentlyContinue + Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue + exit 1 + } + } + catch { + Write-Warning "Could not verify checksum: $($_.Exception.Message)" + $response = Read-Host "Continue without checksum verification? (Y/N)" + if ($response -ne 'Y' -and $response -ne 'y') { + Remove-Item -Path $TempFile -ErrorAction SilentlyContinue + Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue + exit 1 + } + } +} + +# 7. Move file to installation directory +try { + Move-Item -Path $TempFile -Destination "$InstallDir\$FileName" -Force -ErrorAction Stop + Write-Host "Installed to $InstallDir\$FileName" + # Cleanup checksum file after successful installation + Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue +} +catch { + Write-Error "Failed to move file to installation directory: $($_.Exception.Message)" + Remove-Item -Path $TempFile -ErrorAction SilentlyContinue + Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue + exit 1 +} + +# 8. Add the directory to PATH +Write-Host "" +Write-Host "Updating PATH environment variable..." +try { + # Try Machine (system-wide) PATH first - requires Administrator privileges + $machinePath = [Environment]::GetEnvironmentVariable("Path", "Machine") + if ($machinePath -notlike "*$InstallDir*") { + [Environment]::SetEnvironmentVariable("Path", "$machinePath;$InstallDir", "Machine") + Write-Host "Added to system PATH (Machine level)." -ForegroundColor Green + Write-Host "You may need to restart your terminal for changes to take effect." + } + else { + Write-Host "Directory is already in system PATH." + } +} +catch { + Write-Warning "Could not modify System PATH (requires Administrator rights)." + Write-Host "Attempting to add to User PATH instead..." + + # Fallback to User PATH - doesn't require Administrator privileges + try { + $userPath = [Environment]::GetEnvironmentVariable("Path", "User") + if ($userPath -notlike "*$InstallDir*") { + [Environment]::SetEnvironmentVariable("Path", "$userPath;$InstallDir", "User") + Write-Host "Added to User PATH." -ForegroundColor Green + Write-Host "You may need to restart your terminal for changes to take effect." + } + else { + Write-Host "Directory is already in User PATH." + } + } + catch { + Write-Warning "Could not modify User PATH either. You may need to add '$InstallDir' to your PATH manually." + } +} + +# 9. Verification +Write-Host "" +Write-Host "Verification:" +try { + # Test the installation by running tea --version + $version = & "$InstallDir\$FileName" --version 2>&1 + Write-Host $version -ForegroundColor Green +} +catch { + Write-Warning "Could not execute tea. PATH may not be updated in this session." +} + +Write-Host "" +Write-Host "Installation complete! Run 'tea login add' to start configuring your Gitea instance." -ForegroundColor Cyan +Write-Host "Note: If 'tea' command is not found, restart your terminal or reload PATH with:" -ForegroundColor Yellow +Write-Host ' $env:Path = [System.Environment]::GetEnvironmentVariable("Path","User") + ";" + [System.Environment]::GetEnvironmentVariable("Path","Machine")' -ForegroundColor Gray \ No newline at end of file