function PLUGIN:PreInstall(ctx)
local http = require("http")
local env = require("env")
local version = ctx.version
local os_type = RUNTIME.osType
local android_sdk_os
if os_type == "darwin" then
android_sdk_os = "macosx"
elseif os_type == "linux" then
android_sdk_os = "linux"
elseif os_type == "windows" then
android_sdk_os = "windows"
else
error("Unsupported OS type: " .. os_type)
end
local arch_type = RUNTIME.archType
local android_sdk_arch
if arch_type == "amd64" or arch_type == "x86_64" then
android_sdk_arch = "x64"
elseif arch_type == "arm64" or arch_type == "aarch64" then
android_sdk_arch = "aarch64"
else
error("Unsupported architecture: " .. arch_type)
end
local base_url = env.ANDROID_SDK_MIRROR_URL or "https://dl.google.com/android/repository"
local metadata_url = base_url .. "/repository2-3.xml"
local resp = http.get({ url = metadata_url })
if resp.status_code ~= 200 then
error("Failed to fetch Android SDK metadata: HTTP " .. resp.status_code)
end
local package_pattern = 'remotePackage%s+path="cmdline%-tools;'
.. version:gsub("%-", "%%-")
.. '".-</remotePackage>'
local package_block = resp.body:match(package_pattern)
if not package_block then
error("Version " .. version .. " not found in Android SDK repository")
end
local archives_block = package_block:match("<archives>(.-)</archives>")
if not archives_block then
error("No archives found for version " .. version)
end
local best_archive = nil
for archive in archives_block:gmatch("<archive>(.-)</archive>") do
local host_os = archive:match("<host%-os>([^<]+)</host%-os>")
local host_arch = archive:match("<host%-arch>([^<]+)</host%-arch>")
if host_os == android_sdk_os then
if host_arch == nil or host_arch == android_sdk_arch then
best_archive = archive
if host_arch == android_sdk_arch then
break
end
end
end
end
if not best_archive then
error("No archive found for " .. android_sdk_os .. ":" .. android_sdk_arch)
end
local complete_block = best_archive:match("<complete>(.-)</complete>")
if not complete_block then
error("No complete block found in archive")
end
local url = complete_block:match("<url>([^<]+)</url>")
if not url then
error("No URL found in archive")
end
if not url:match("^https?://") then
url = base_url .. "/" .. url
end
local result = {
version = version,
url = url,
}
return result
end