windows/bootstrap: skip winget; install portable MinGit and Go
DesktopAppInstaller on this host returns 0x8a15000f with an empty winget index; source reset does not recover it. Fetch MinGit and the go.dev windows-amd64 zip into LOCALAPPDATA instead.
This commit is contained in:
+60
-51
@@ -11,65 +11,74 @@ $Dest = Join-Path $env:LOCALAPPDATA 'rclone-dropbox-bisync'
|
|||||||
$Dropbox = 'D:\Dropbox'
|
$Dropbox = 'D:\Dropbox'
|
||||||
$Workdir = 'D:\rclone-bisync'
|
$Workdir = 'D:\rclone-bisync'
|
||||||
|
|
||||||
function Refresh-Path {
|
# Do not use winget: 0x8a15000f (empty source cache) is common and not recoverable
|
||||||
$env:Path = [Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' +
|
# from this script. Fetch portable MinGit + Go into LOCALAPPDATA instead.
|
||||||
[Environment]::GetEnvironmentVariable('Path', 'User')
|
$Tools = Join-Path $Dest 'tools'
|
||||||
|
|
||||||
|
function Prepend-UserPath($Dir) {
|
||||||
|
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
||||||
|
if ([string]::IsNullOrEmpty($userPath)) { $userPath = '' }
|
||||||
|
if ($userPath -notlike "*$Dir*") {
|
||||||
|
[Environment]::SetEnvironmentVariable('Path', $(if ($userPath) { "$Dir;$userPath" } else { $Dir }), 'User')
|
||||||
|
}
|
||||||
|
if ($env:Path -notlike "*$Dir*") { $env:Path = "$Dir;$env:Path" }
|
||||||
}
|
}
|
||||||
|
|
||||||
# 0x8a15000f: winget source index missing/corrupt (common on a fresh DesktopAppInstaller).
|
function Get-File($Url, $Out) {
|
||||||
function Repair-WingetSource {
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
if ($script:WingetSourceRepaired) { return }
|
Invoke-WebRequest -Uri $Url -OutFile $Out -UseBasicParsing
|
||||||
$winget = Get-Command winget -ErrorAction SilentlyContinue
|
|
||||||
if (-not $winget) { return }
|
|
||||||
$prev = $ErrorActionPreference
|
|
||||||
$ErrorActionPreference = 'Continue'
|
|
||||||
try {
|
|
||||||
& winget source reset --force --disable-interactivity 2>&1 | Out-Null
|
|
||||||
& winget source update --disable-interactivity 2>&1 | Out-Null
|
|
||||||
} finally {
|
|
||||||
$ErrorActionPreference = $prev
|
|
||||||
}
|
|
||||||
$script:WingetSourceRepaired = $true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Install-WithWinget($WingetId) {
|
function Ensure-Git {
|
||||||
Repair-WingetSource
|
if (Get-Command git -ErrorAction SilentlyContinue) { return }
|
||||||
$wingetArgs = @(
|
$root = Join-Path $Tools 'mingit'
|
||||||
'install', '-e', '--id', $WingetId,
|
$cmd = Join-Path $root 'cmd'
|
||||||
'--accept-package-agreements', '--accept-source-agreements',
|
if (-not (Test-Path (Join-Path $cmd 'git.exe'))) {
|
||||||
'--disable-interactivity', '--source', 'winget'
|
Write-Host 'Fetching MinGit...'
|
||||||
)
|
$rel = Invoke-RestMethod -Uri 'https://api.github.com/repos/git-for-windows/git/releases/latest'
|
||||||
$prev = $ErrorActionPreference
|
$asset = $rel.assets |
|
||||||
$ErrorActionPreference = 'Continue'
|
Where-Object { $_.name -match '^MinGit-.+-64-bit\.zip$' -and $_.name -notmatch 'busybox' } |
|
||||||
try {
|
Select-Object -First 1
|
||||||
& winget @wingetArgs
|
if (-not $asset) { throw 'No MinGit-*-64-bit.zip on git-for-windows latest release' }
|
||||||
if ($LASTEXITCODE -eq 0) { return }
|
$zip = Join-Path $env:TEMP $asset.name
|
||||||
# Index still empty: reset once more, then retry without pinning the source
|
Get-File $asset.browser_download_url $zip
|
||||||
# (some hosts only have msstore until cdn.winget.microsoft.com is reachable).
|
New-Item -ItemType Directory -Force -Path $root | Out-Null
|
||||||
& winget source reset --force --disable-interactivity 2>&1 | Out-Null
|
Expand-Archive -Path $zip -DestinationPath $root -Force
|
||||||
& winget source update --disable-interactivity 2>&1 | Out-Null
|
|
||||||
& winget install -e --id $WingetId --accept-package-agreements --accept-source-agreements --disable-interactivity
|
|
||||||
if ($LASTEXITCODE -eq 0) { return }
|
|
||||||
} finally {
|
|
||||||
$ErrorActionPreference = $prev
|
|
||||||
}
|
}
|
||||||
throw "winget failed to install $WingetId (exit $LASTEXITCODE / 0x8a15000f = empty source cache). Run: winget source reset --force; winget source update"
|
Prepend-UserPath $cmd
|
||||||
}
|
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "git.exe missing under $cmd"
|
||||||
function Ensure-Cmd($Name, $WingetId) {
|
|
||||||
if (Get-Command $Name -ErrorAction SilentlyContinue) { return }
|
|
||||||
if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
|
|
||||||
throw "Need $Name on PATH (or winget to install $WingetId)"
|
|
||||||
}
|
|
||||||
Install-WithWinget $WingetId
|
|
||||||
Refresh-Path
|
|
||||||
if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) {
|
|
||||||
throw "$Name still missing after winget install $WingetId; open a new PowerShell and retry"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ensure-Cmd git Git.Git
|
function Ensure-Go {
|
||||||
Ensure-Cmd go GoLang.Go
|
if (Get-Command go -ErrorAction SilentlyContinue) { return }
|
||||||
|
$root = Join-Path $Tools 'go'
|
||||||
|
$bin = Join-Path $root 'go\bin'
|
||||||
|
if (-not (Test-Path (Join-Path $bin 'go.exe'))) {
|
||||||
|
Write-Host 'Fetching Go...'
|
||||||
|
$dl = Invoke-RestMethod -Uri 'https://go.dev/dl/?mode=json'
|
||||||
|
$file = $null
|
||||||
|
foreach ($rel in $dl) {
|
||||||
|
$file = $rel.files |
|
||||||
|
Where-Object { $_.os -eq 'windows' -and $_.arch -eq 'amd64' -and $_.kind -eq 'archive' } |
|
||||||
|
Select-Object -First 1
|
||||||
|
if ($file) { break }
|
||||||
|
}
|
||||||
|
if (-not $file) { throw 'No windows-amd64 Go archive on go.dev/dl' }
|
||||||
|
$zip = Join-Path $env:TEMP $file.filename
|
||||||
|
Get-File "https://go.dev/dl/$($file.filename)" $zip
|
||||||
|
New-Item -ItemType Directory -Force -Path $root | Out-Null
|
||||||
|
Expand-Archive -Path $zip -DestinationPath $root -Force
|
||||||
|
}
|
||||||
|
Prepend-UserPath $bin
|
||||||
|
if (-not (Get-Command go -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "go.exe missing under $bin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ensure-Git
|
||||||
|
Ensure-Go
|
||||||
|
|
||||||
New-Item -ItemType Directory -Force -Path $Src, (Join-Path $Dest 'bin') | Out-Null
|
New-Item -ItemType Directory -Force -Path $Src, (Join-Path $Dest 'bin') | Out-Null
|
||||||
if (-not (Test-Path (Join-Path $Src 'packaging\.git'))) {
|
if (-not (Test-Path (Join-Path $Src 'packaging\.git'))) {
|
||||||
|
|||||||
Reference in New Issue
Block a user