diff --git a/install.ps1 b/install.ps1 index e4788b0..e88f044 100644 --- a/install.ps1 +++ b/install.ps1 @@ -4,46 +4,80 @@ One-liner (PowerShell): irm https://git.armoredarmadillo.com/brockdarnold/eve-watcher/raw/branch/main/install.ps1 | iex - Paste it ONCE. It puts the watcher repo in %USERPROFILE%\eve-watcher, forces the - working tree to match the latest code, and runs update.py - which installs deps + - Tesseract, starts the watchers, auto-detects the ore-hold readout (no manual snip), - and registers logon + daily auto-update. You never have to install or update again. + Paste it ONCE. It auto-installs anything missing (Python, and Git if available), + downloads the watchers to %USERPROFILE%\eve-watcher (via git if possible, else a + plain zip - no git required), then runs update.py which installs deps + Tesseract, + starts the watchers, auto-detects the ore-hold readout (no manual snip), and sets + up logon + daily auto-update. Nothing to install or configure by hand. - Safe to re-run anytime: it force-syncs to the latest code (reset --hard) and never - touches your gitignored config.ini. + Safe to re-run anytime. Your gitignored config.ini is never touched. #> $ErrorActionPreference = "Stop" -$repo = "https://git.armoredarmadillo.com/brockdarnold/eve-watcher.git" -$dir = Join-Path $env:USERPROFILE "eve-watcher" +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$repo = "https://git.armoredarmadillo.com/brockdarnold/eve-watcher.git" +$zipUrl = "https://git.armoredarmadillo.com/brockdarnold/eve-watcher/archive/main.zip" +$dir = Join-Path $env:USERPROFILE "eve-watcher" -function Need($cmd, $hint) { - if (-not (Get-Command $cmd -ErrorAction SilentlyContinue)) { throw "$cmd not found. $hint" } +function Have($c) { [bool](Get-Command $c -ErrorAction SilentlyContinue) } +function Refresh-Path { + $m = [Environment]::GetEnvironmentVariable("Path", "Machine") + $u = [Environment]::GetEnvironmentVariable("Path", "User") + $env:Path = (@($m, $u) | Where-Object { $_ }) -join ';' } -function GitMust($desc) { if ($LASTEXITCODE -ne 0) { throw "git $desc failed (exit $LASTEXITCODE)" } } - -Need git "Install it: winget install --id Git.Git -e (then re-run)" -Need python "Install Python 3 from https://www.python.org (check 'Add to PATH'), then re-run." - -# Make $dir a git clone of $repo whose working tree is FORCED to the latest commit. -# init+fetch+reset is bulletproof: it can't fail on a non-empty folder (old installer) -# or on Windows CRLF/dirty-tree issues the way `git clone` / `git pull` can. -if (-not (Test-Path (Join-Path $dir ".git"))) { - if (Test-Path $dir) { Write-Host "Converting existing folder to a git clone (keeping config.ini)..." } - else { Write-Host "Creating $dir ..."; New-Item -ItemType Directory -Path $dir -Force | Out-Null } - git -C $dir init -q; GitMust "init" +function Ensure-Tool($cmd, $wingetId) { + if (Have $cmd) { return $true } + if (Have winget) { + Write-Host "Installing $cmd (one-time, may prompt UAC)..." + try { winget install --id $wingetId -e --silent --accept-package-agreements --accept-source-agreements | Out-Null } catch {} + Refresh-Path # so the just-installed tool is found in THIS session + } + return (Have $cmd) +} +function Download-Zip { + Write-Host "Downloading watcher (no git needed)..." + $tmp = Join-Path $env:TEMP "eve-watcher.zip" + Invoke-WebRequest -Uri $zipUrl -OutFile $tmp -UseBasicParsing + $ex = Join-Path $env:TEMP ("ew_" + [guid]::NewGuid().ToString("N")) + Expand-Archive -Path $tmp -DestinationPath $ex -Force + New-Item -ItemType Directory -Path $dir -Force | Out-Null + Copy-Item -Path (Join-Path $ex "eve-watcher\*") -Destination $dir -Recurse -Force # archive has no config.ini + Remove-Item $tmp, $ex -Recurse -Force -ErrorAction SilentlyContinue } -if (-not (git -C $dir remote)) { git -C $dir remote add origin $repo } -else { git -C $dir remote set-url origin $repo } -Write-Host "Syncing to latest code..." -git -C $dir fetch -q origin; GitMust "fetch" -git -C $dir checkout -q -B main origin/main; GitMust "checkout" -git -C $dir reset --hard -q origin/main; GitMust "reset" # config.ini is gitignored -> untouched -if (-not (Test-Path (Join-Path $dir "update.py"))) { throw "update.py missing after sync - aborting." } +# Pick up anything installed earlier in a now-stale session (e.g. git just installed +# by hand but PATH not refreshed - exactly the "git not found after installing" case). +Refresh-Path + +# Python is the runtime - required. Git is optional (nice for updates/edits). +if (-not (Ensure-Tool python "Python.Python.3.12")) { + throw "Python is required and couldn't be auto-installed. Get it from https://www.python.org (check 'Add to PATH'), then re-run." +} +$haveGit = Ensure-Tool git "Git.Git" + +if ($haveGit) { + if (-not (Test-Path (Join-Path $dir ".git"))) { + if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } + git -C $dir init -q + } + if (-not (git -C $dir remote)) { git -C $dir remote add origin $repo } else { git -C $dir remote set-url origin $repo } + git -C $dir fetch -q origin + if ($LASTEXITCODE -eq 0) { + git -C $dir checkout -q -B main origin/main + git -C $dir reset --hard -q origin/main # config.ini gitignored -> untouched + } else { + Write-Warning "git fetch failed - using zip download instead." + Download-Zip + } +} else { + Write-Host "Git not available - installing without it (zip mode)." + Download-Zip +} + +if (-not (Test-Path (Join-Path $dir "update.py"))) { throw "update.py missing after install - aborting." } Set-Location $dir python update.py Write-Host "" Write-Host "Installed at $dir. Auto-start + daily auto-update are configured - nothing else to do." -Write-Host "Make sure your in-game Ore Hold is open so it can auto-calibrate the live % reader." +Write-Host "Have your in-game Ore Hold window open so it can auto-calibrate the live % reader."