Skip to content

Commit 308bb7d

Browse files
authored
fix: propagate search failures and normalize Node.js package architecture (#28)
Fixes #16 Fixes #23
1 parent 5051bfe commit 308bb7d

4 files changed

Lines changed: 98 additions & 3 deletions

File tree

‎.github/workflows/test.yml‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Test Plugin
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [main]
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
16+
with:
17+
persist-credentials: false
18+
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6
19+
with:
20+
go-version: '1.24.0'
21+
cache: false
22+
- name: Test Node.js hooks with vfox's Lua interpreter
23+
run: go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/hooks_test.lua

‎hooks/available.lua‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ function PLUGIN:Available(ctx)
1313
local resp, err = http.get({
1414
url = util.getBaseUrl() .. util.VersionSourceUrl
1515
})
16-
if err ~= nil or resp.status_code ~= 200 then
17-
return {}
16+
if err ~= nil then
17+
error("Failed to fetch Node.js versions: " .. tostring(err))
18+
end
19+
if resp.status_code ~= 200 then
20+
error("Failed to fetch Node.js versions: HTTP " .. tostring(resp.status_code))
1821
end
1922
local body = json.decode(resp.body)
2023
local result = {}
@@ -34,4 +37,4 @@ function PLUGIN:Available(ctx)
3437
table.sort(result, util.compare_versions)
3538
available_result = result
3639
return result
37-
end
40+
end

‎hooks/pre_install.lua‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,15 @@ function PLUGIN:PreInstall(ctx)
2424
end
2525

2626
local arch_type = RUNTIME.archType
27+
if arch_type == nil or arch_type == "" then
28+
error("Cannot determine Node.js package architecture from RUNTIME.archType")
29+
end
2730
local ext = ".tar.gz"
2831
local osType = RUNTIME.osType
2932
if RUNTIME.archType == "amd64" then
3033
arch_type = "x64"
34+
elseif RUNTIME.archType == "386" then
35+
arch_type = "x86"
3136
end
3237
if RUNTIME.osType == "windows" then
3338
ext = ".zip"
@@ -52,6 +57,9 @@ function PLUGIN:PreInstall(ctx)
5257
error("get checksum failed")
5358
end
5459
local checksum = util.get_checksum(resp.body, filename)
60+
if checksum == nil then
61+
error("Node.js package " .. filename .. " is not listed in " .. baseUrl .. "SHASUMS256.txt")
62+
end
5563
return {
5664
version = version,
5765
url = baseUrl .. filename,

‎tests/hooks_test.lua‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package.path = './lib/?.lua;' .. package.path
2+
local state = {failed=0, passed=0}
3+
package.preload.http = function() return {get=function(args)
4+
state.requests = state.requests + 1
5+
return state.response, state.request_error
6+
end} end
7+
package.preload.json = function() return {decode=function() return state.decoded end} end
8+
PLUGIN = {}
9+
dofile('hooks/available.lua')
10+
dofile('hooks/pre_install.lua')
11+
local function test(name, fn)
12+
state.response, state.request_error, state.decoded, state.requests = nil, nil, nil, 0
13+
available_result = nil
14+
local ok, err = pcall(fn)
15+
if ok then state.passed=state.passed+1 else state.failed=state.failed+1; print('FAIL '..name..': '..tostring(err)) end
16+
end
17+
local function expect_error(fn, message)
18+
local ok, err=pcall(fn)
19+
assert(not ok, 'expected error')
20+
assert(tostring(err):find(message,1,true), tostring(err))
21+
end
22+
for _, failure in ipairs({'timeout','HTTP 503'}) do
23+
test('search failure and recovery '..failure, function()
24+
if failure=='timeout' then state.request_error='timeout' else state.response={status_code=503} end
25+
expect_error(function() PLUGIN:Available({}) end, failure)
26+
state.request_error=nil; state.response={status_code=200,body='index'}
27+
state.decoded={{version='v20.16.0',npm='10.8.1',lts='Iron'}}
28+
assert(PLUGIN:Available({})[1].version=='20.16.0')
29+
assert(state.requests==2, 'failed response was cached')
30+
end)
31+
end
32+
local cases = {
33+
{'windows','amd64','win-x64.zip'},
34+
{'windows','386','win-x86.zip'},
35+
{'windows','arm64','win-arm64.zip'},
36+
{'linux','amd64','linux-x64.tar.gz'},
37+
{'darwin','arm64','darwin-arm64.tar.gz'},
38+
}
39+
for _, case in ipairs(cases) do
40+
test('package '..case[1]..'/'..case[2], function()
41+
RUNTIME={osType=case[1],archType=case[2]}
42+
local filename='node-v20.16.0-'..case[3]
43+
local hash=string.rep('a',64)
44+
state.response={status_code=200,body=hash..' '..filename..'\n'}
45+
local result=PLUGIN:PreInstall({version='20.16.0'})
46+
assert(result.url:sub(-#filename)==filename,result.url)
47+
assert(result.sha256==hash,'checksum missing')
48+
end)
49+
end
50+
test('missing architecture',function()
51+
RUNTIME={osType='windows'}
52+
expect_error(function() PLUGIN:PreInstall({version='20.16.0'}) end,'architecture')
53+
assert(state.requests==0)
54+
end)
55+
test('missing package',function()
56+
RUNTIME={osType='windows',archType='arm64'}
57+
state.response={status_code=200,body=string.rep('a',64)..' node-v20.16.0-win-x64.zip\n'}
58+
expect_error(function() PLUGIN:PreInstall({version='20.16.0'}) end,'node-v20.16.0-win-arm64.zip')
59+
end)
60+
print(state.passed..' passed, '..state.failed..' failed')
61+
assert(state.failed==0)

0 commit comments

Comments
 (0)