Files

70 lines
3.6 KiB
PowerShell

param(
[Parameter(Mandatory = $true)]
[ValidateSet('flutter', 'java', 'android-cli')]
[string]$Tool
)
$ErrorActionPreference = 'Stop'
$taskProjectRoot = Split-Path -Parent $PSScriptRoot
$taskToolRoot = Join-Path $taskProjectRoot '.tools'
$taskDownloads = Join-Path $taskToolRoot 'downloads'
New-Item -ItemType Directory -Force -Path $taskDownloads | Out-Null
$taskPackages = @{
'flutter' = @{
Url = 'https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_windows_3.47.7-stable.zip'
Sha256 = 'c2c875da25a1a1448d18ee4e8f398b2f6fce888b4775d8f9130538e16d826cb4'
Zip = 'flutter-3.47.7.zip'
Marker = 'flutter/bin/flutter.bat'
}
'java' = @{
Url = 'https://aka.ms/download-jdk/microsoft-jdk-17.0.20.1-windows-x64.zip'
Sha256 = '3d9006956fc8af5601cd24ffc4f468bef48279c7ebd8171b9bdf90d0aabfbf1f'
Zip = 'jdk-17.zip'
Marker = 'jdk-17/bin/java.exe'
}
'android-cli' = @{
Url = 'https://dl.google.com/android/repository/commandlinetools-win-15859902_latest.zip'
Sha256 = '90ae805d20434428bffcb699c290860f19bb5f66a67e6b330067e3de801fb04a'
Zip = 'android-commandline.zip'
Marker = 'android-sdk/cmdline-tools/latest/bin/sdkmanager.bat'
}
}
$taskPackage = $taskPackages[$Tool]
if (Test-Path -LiteralPath (Join-Path $taskToolRoot $taskPackage.Marker)) {
Write-Output "$Tool is already installed."
exit 0
}
$taskArchive = Join-Path $taskDownloads $taskPackage.Zip
Write-Output "Downloading $Tool from the official distribution."
& curl.exe --fail --location --silent --show-error --retry 3 --retry-all-errors --connect-timeout 30 --speed-limit 1024 --speed-time 60 --continue-at - --output $taskArchive $taskPackage.Url
if ($LASTEXITCODE -ne 0) { throw "Download failed: $Tool" }
$taskActualHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $taskArchive).Hash.ToLowerInvariant()
if ($taskActualHash -ne $taskPackage.Sha256) { throw "SHA-256 verification failed: $Tool" }
Write-Output "Verified SHA-256 for $Tool; extracting."
if ($Tool -eq 'flutter') {
& tar.exe -xf $taskArchive -C $taskToolRoot
if ($LASTEXITCODE -ne 0) { throw 'Flutter extraction failed.' }
} else {
$taskStage = Join-Path $taskToolRoot "staging/$Tool"
New-Item -ItemType Directory -Force -Path $taskStage | Out-Null
& tar.exe -xf $taskArchive -C $taskStage
if ($LASTEXITCODE -ne 0) { throw "$Tool extraction failed." }
if ($Tool -eq 'java') {
$taskSource = (Get-ChildItem -LiteralPath $taskStage -Directory | Where-Object Name -Like 'jdk-*' | Select-Object -First 1).FullName
$taskDestination = Join-Path $taskToolRoot 'jdk-17'
} else {
$taskSource = Join-Path $taskStage 'cmdline-tools'
$taskDestination = Join-Path $taskToolRoot 'android-sdk/cmdline-tools/latest'
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $taskDestination) | Out-Null
}
# Validate the resolved paths before moving the unpacked tool directory.
$taskResolvedRoot = [IO.Path]::GetFullPath($taskToolRoot).TrimEnd('\') + '\'
foreach ($taskMovePath in @($taskSource, $taskDestination)) {
if (-not $taskMovePath -or -not [IO.Path]::GetFullPath($taskMovePath).StartsWith($taskResolvedRoot, [StringComparison]::OrdinalIgnoreCase)) {
throw 'Tool path is outside the project tool directory.'
}
}
Move-Item -LiteralPath $taskSource -Destination $taskDestination
}
if (-not (Test-Path -LiteralPath (Join-Path $taskToolRoot $taskPackage.Marker))) { throw "$Tool installation is incomplete." }
Write-Output "Installed $Tool."