Skip to content

Commit cb7397c

Browse files
Copilotbytemain
andauthored
Adapt uv-build to upstream asset metadata
Agent-Logs-Url: https://github.com/version-fox/vfox-python/sessions/016602d1-26fe-4323-9761-716964a16a9c Co-authored-by: bytemain <13938334+bytemain@users.noreply.github.com>
1 parent 3636d16 commit cb7397c

2 files changed

Lines changed: 102 additions & 223 deletions

File tree

docs/python-build-standalone-api-response.md

Lines changed: 0 additions & 219 deletions
This file was deleted.

lib/util.lua

Lines changed: 102 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ local function isHttpsUrl(value)
257257
return type(value) == "string" and startsWith(value, "https://") and not string.find(value, "[\r\n%z]")
258258
end
259259

260+
local function commandSucceeded(status)
261+
return status == 0 or status == true
262+
end
263+
260264
local function startsWithPath(value, prefix)
261265
if value == prefix then
262266
return true
@@ -356,14 +360,18 @@ local function buildUvBuildUrl(osType, archType, libc)
356360
end
357361

358362
local function uvBuildVersion(build)
363+
if build.display_version ~= nil then
364+
return build.display_version
365+
end
359366
if build.variant == "freethreaded" then
360367
return build.version .. "t"
361368
end
362369
return build.version
363370
end
364371

365372
local function isSupportedUvBuild(build)
366-
if build.name ~= "cpython" then
373+
local implementation = build.implementation or build.name
374+
if implementation ~= "cpython" then
367375
return false
368376
end
369377
if build.version == nil then
@@ -372,7 +380,7 @@ local function isSupportedUvBuild(build)
372380
if build.arch and build.arch.variant ~= nil then
373381
return false
374382
end
375-
if build.variant ~= nil and build.variant ~= "freethreaded" then
383+
if build.variant ~= nil and build.variant ~= "default" and build.variant ~= "freethreaded" then
376384
return false
377385
end
378386
if not isHttpsUrl(build.url) then
@@ -381,6 +389,86 @@ local function isSupportedUvBuild(build)
381389
return true
382390
end
383391

392+
local function uvBuildSha256(build)
393+
if type(build.asset) ~= "table" or type(build.asset.sha256) ~= "string" then
394+
return nil
395+
end
396+
397+
local sha256 = string.lower(build.asset.sha256)
398+
if string.match(sha256, "^[0-9a-f]+$") and string.len(sha256) == 64 then
399+
return sha256
400+
end
401+
402+
error("Invalid uv-build sha256 for " .. build.url)
403+
end
404+
405+
local function uvBuildAssetName(build)
406+
if type(build.filename) == "string" then
407+
return string.lower(build.filename)
408+
end
409+
if type(build.url) == "string" then
410+
return string.lower(build.url)
411+
end
412+
return ""
413+
end
414+
415+
local function uvBuildAssetPriority(build)
416+
local name = uvBuildAssetName(build)
417+
if string.find(name, "pgo+lto-full", 1, true) or string.find(name, "pgo%2blto-full", 1, true) then
418+
return 10
419+
end
420+
if string.find(name, "install_only_stripped", 1, true) then
421+
return 20
422+
end
423+
if string.find(name, "install_only", 1, true) then
424+
return 30
425+
end
426+
if not string.find(name, "debug", 1, true) then
427+
return 40
428+
end
429+
return 90
430+
end
431+
432+
local function verifyUvBuildArchive(path, sha256)
433+
if sha256 == nil then
434+
return
435+
end
436+
437+
print("Verifying Python uv-build archive sha256...")
438+
439+
local status
440+
if RUNTIME.osType == "windows" or OS_TYPE == "windows" then
441+
local command = 'certutil -hashfile ' .. shellQuote(path) .. ' SHA256 | findstr /i /c:"' .. sha256 .. '" > NUL'
442+
status = os.execute(command)
443+
else
444+
local command = nil
445+
local hasSha256sum = io.popen("command -v sha256sum 2>/dev/null")
446+
local sha256sumPath = hasSha256sum and hasSha256sum:read("*l") or nil
447+
if hasSha256sum then
448+
hasSha256sum:close()
449+
end
450+
451+
local hasShasum = io.popen("command -v shasum 2>/dev/null")
452+
local shasumPath = hasShasum and hasShasum:read("*l") or nil
453+
if hasShasum then
454+
hasShasum:close()
455+
end
456+
457+
if sha256sumPath and sha256sumPath ~= "" then
458+
command = "printf '%s %s\n' " .. shellQuote(sha256) .. " " .. shellQuote(path) .. " | sha256sum -c -"
459+
elseif shasumPath and shasumPath ~= "" then
460+
command = "printf '%s %s\n' " .. shellQuote(sha256) .. " " .. shellQuote(path) .. " | shasum -a 256 -c -"
461+
else
462+
error("Unable to verify uv-build archive sha256: sha256sum or shasum is required")
463+
end
464+
status = os.execute(command)
465+
end
466+
467+
if not commandSucceeded(status) then
468+
error("uv-build archive sha256 verification failed")
469+
end
470+
end
471+
384472
local function uvBuildDownloadUrl(build)
385473
local mirror = os.getenv(UV_BUILD_MIRROR_ENV)
386474
if mirror == nil or mirror == "" then
@@ -410,16 +498,25 @@ local function getUvBuilds(osType, archType, libc)
410498
end
411499

412500
local jsonObj = json.decode(resp.body)
413-
return jsonObj.versions or {}
501+
return jsonObj.items or jsonObj.versions or {}
414502
end
415503

416504
local function findUvBuild(version)
417505
local osType, archType, libc = getUvBuildPlatform()
506+
local selectedBuild = nil
507+
local selectedPriority = nil
418508
for _, build in ipairs(getUvBuilds(osType, archType, libc)) do
419509
if isSupportedUvBuild(build) and uvBuildVersion(build) == version then
420-
return build
510+
local priority = uvBuildAssetPriority(build)
511+
if selectedBuild == nil or priority < selectedPriority then
512+
selectedBuild = build
513+
selectedPriority = priority
514+
end
421515
end
422516
end
517+
if selectedBuild ~= nil then
518+
return selectedBuild
519+
end
423520
error("No uv-build prebuilt Python found for version " .. version .. " on " .. osType .. "/" .. archType .. "/" .. libc)
424521
end
425522

@@ -504,6 +601,7 @@ function uvBuildInstall(ctx)
504601
if err ~= nil then
505602
error("Downloading uv-build archive failed")
506603
end
604+
verifyUvBuildArchive(archivePath, uvBuildSha256(build))
507605

508606
print("Extracting Python uv-build archive...")
509607
local status = os.execute("tar -xf " .. shellQuote(archivePath) .. " --strip-components=1 -C " .. shellQuote(path))

0 commit comments

Comments
 (0)