Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions docs/e2e.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,9 @@ JDK, so `java` can only come from what vfox installs:
6. `PreUse` maps the spellings users type to the installed version without
another download: the bare major (`java@21`, left to vfox core's fuzzy
matching), the spec the JDK was installed with (`java@21.0.8-tem`, whose
build number `PreUse` finds among the installed versions; not yet for
OpenJDK, whose input `PreUse` hands back unchanged) and the asdf-style
`<long-name>-<version>[-fx]` (`java@temurin-21.0.8+9`, rewritten to
`21.0.8+9-tem`).
build number `PreUse` finds among the installed versions) and the
asdf-style `<long-name>-<version>[-fx]` (`java@temurin-21.0.8+9`,
rewritten to `21.0.8+9-tem`; `java@openjdk-25.0.2+10` to `25.0.2+10`).

The default matrix runs every distribution against both vfox channels
(`latest`, `main`):
Expand Down
10 changes: 5 additions & 5 deletions hooks/available.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,20 @@ function PLUGIN:Available(ctx)
local seen = {}
for _, jdk in ipairs(jdks) do
local v = jdk.java_version
local short = jdk.short
local short = jdk.short or short_name

-- Add -fx suffix for JavaFX bundled versions (after distribution name)
local fx_suffix = ""
if jdk.javafx_bundled == true then
fx_suffix = "-fx"
end

if query == "all" then
v = v .. "-" .. short .. fx_suffix
elseif query == "open" then
-- OpenJDK versions carry no distribution suffix, as PreInstall names
-- them, whether the query is open, openjdk or all.
if short == "open" then
v = v .. fx_suffix
else
v = v .. "-" .. short_name .. fx_suffix
v = v .. "-" .. short .. fx_suffix
end

if not seen[v] then
Expand Down
30 changes: 15 additions & 15 deletions hooks/pre_use.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,24 +75,24 @@ function PLUGIN:PreUse(ctx)
local input_version = ctx.version
local distribution_version = distribution_version_parser.parse_version(input_version)

-- If it is a pure numeric major version (such as "8"), and the distribution is openjdk, let the core perform fuzzy matching.
if distribution_version and distribution_version.distribution.short_name == "open" then
if not string.find(distribution_version.version, "%.") then -- Pure numbers, no minor versions
-- Return no result, let vfox core perform fuzzy matching. Not "": vfox
-- after 1.0.12 rejects a bare string ("cannot unmarshal string").
return nil
end
-- If it is a pure numeric major version (such as "8"), let the core perform
-- fuzzy matching, which takes any distribution. Spelled as OpenJDK (8-open,
-- openjdk-8), it selects the newest OpenJDK release below instead.
if input_version:match("^%d+$") then
-- Return no result, let vfox core perform fuzzy matching. Not "": vfox
-- after 1.0.12 rejects a bare string ("cannot unmarshal string").
return nil
end

if distribution_version and distribution_version.distribution.short_name ~= "open" then
if distribution_version then
-- OpenJDK versions are installed without a distribution suffix, so
-- 25.0.2+10-open and openjdk-25.0.2+10 both name 25.0.2+10.
local suffix = distribution_version.javafx_bundled and "-fx" or ""
if distribution_version.distribution.short_name ~= "open" then
suffix = "-" .. distribution_version.distribution.short_name .. suffix
end
return {
version = installed_version(
ctx.installedSdks or {},
distribution_version.version,
"-"
.. distribution_version.distribution.short_name
.. (distribution_version.javafx_bundled and "-fx" or "")
),
version = installed_version(ctx.installedSdks or {}, distribution_version.version, suffix),
}
else
return {
Expand Down
21 changes: 6 additions & 15 deletions tests/e2e/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,26 +260,17 @@ func LegacyIdentifier(distribution, version string) string {
return version + "-" + Base(distribution)
}

// UseSpec renders the spec `vfox use` must take as `vfox install` did,
// leaving PreUse to find the build number among the installed versions
// (21.0.8-tem selects 21.0.8+9-tem). OpenJDK is left out for now: PreUse
// hands its input back unchanged (vfox-java#70).
func UseSpec(distribution, version string) (string, bool) {
if Base(distribution) == "open" {
return "", false
}
return Spec(distribution, version), true
}

// Alias renders the asdf-style spelling "<long-name>-<version>[-fx]" of an
// installed version, which PreUse must rewrite back to installed. OpenJDK
// has none: its versions carry no suffix for PreUse to rewrite.
// installed version, which PreUse must rewrite back to installed
// (temurin-21.0.8+9 to 21.0.8+9-tem, openjdk-25.0.2+10 to 25.0.2+10).
func Alias(distribution, installed string) (string, bool) {
d, ok := distributions[Base(distribution)]
if !ok || Base(distribution) == "open" {
if !ok {
return "", false
}
core, found := strings.CutSuffix(installed, "-"+distribution)
// Installed versions end the way specs do: "-tem", "-librca-fx", or
// nothing for OpenJDK.
core, found := strings.CutSuffix(installed, Spec(distribution, ""))
if !found {
return "", false
}
Expand Down
17 changes: 1 addition & 16 deletions tests/e2e/common/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,23 +201,9 @@ func TestSpecs(t *testing.T) {
}
}

func TestUseSpec(t *testing.T) {
for _, c := range []struct{ dist, version, want string }{
{"tem", "21.0.8", "21.0.8-tem"},
{"librca-fx", "25.0.4", "25.0.4-librca-fx"},
{"graalce", "25.0.2", "25.0.2-graalce"},
} {
if got, ok := UseSpec(c.dist, c.version); !ok || got != c.want {
t.Errorf("UseSpec(%s, %s) = %q, %v; want %q", c.dist, c.version, got, ok, c.want)
}
}
if got, ok := UseSpec("open", "25.0.2"); ok {
t.Errorf("UseSpec(open, 25.0.2) = %q, want none", got)
}
}

func TestAlias(t *testing.T) {
for _, c := range []struct{ dist, installed, want string }{
{"open", "25.0.2+10", "openjdk-25.0.2+10"},
{"tem", "21.0.8+9-tem", "temurin-21.0.8+9"},
{"librca-fx", "25.0.4+9-librca-fx", "liberica-25.0.4+9-fx"},
{"jb", "21.0.5+79248-jb", "jetbrains-21.0.5+79248"},
Expand All @@ -228,7 +214,6 @@ func TestAlias(t *testing.T) {
}
}
for _, c := range []struct{ dist, installed string }{
{"open", "25.0.2+10"}, // no suffix to rewrite
{"zulu", "21.0.8+9-zulu"}, // long name unknown to the suite
{"tem", "21.0.8+9-librca"}, // not this distribution's version
} {
Expand Down
8 changes: 3 additions & 5 deletions tests/e2e/linux/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,13 @@ func verifyToolchain(ctx context.Context, t *testing.T, ctr tc.Container, distri
// 2. the spec the JDK was installed with (e.g. java@21.0.8-tem), whose
// build number PreUse finds among the installed versions;
// 3. the asdf-style <long-name>-<version>[-fx] spelling (e.g.
// java@temurin-21.0.8+9), which PreUse rewrites to <version>-<short>.
// java@temurin-21.0.8+9), which PreUse rewrites to <version>-<short>
// (<version> for OpenJDK, installed without a suffix).
//
// After each `vfox use`, java on PATH must still be the installed JDK.
func verifyPreUse(ctx context.Context, t *testing.T, ctr tc.Container, distribution, version, installed string) {
t.Helper()
spellings := []string{common.Major(version)}
if spec, ok := common.UseSpec(distribution, version); ok {
spellings = append(spellings, spec)
}
spellings := []string{common.Major(version), common.Spec(distribution, version)}
if alias, ok := common.Alias(distribution, installed); ok {
spellings = append(spellings, alias)
}
Expand Down
8 changes: 3 additions & 5 deletions tests/e2e/windows/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,13 @@ func verifyToolchain(ctx context.Context, t *testing.T, ctr tc.Container, box sl
// 2. the spec the JDK was installed with (e.g. java@21.0.8-tem), whose
// build number PreUse finds among the installed versions;
// 3. the asdf-style <long-name>-<version>[-fx] spelling (e.g.
// java@temurin-21.0.8+9), which PreUse rewrites to <version>-<short>.
// java@temurin-21.0.8+9), which PreUse rewrites to <version>-<short>
// (<version> for OpenJDK, installed without a suffix).
//
// After each `vfox use`, java on PATH must still be the installed JDK.
func verifyPreUse(ctx context.Context, t *testing.T, ctr tc.Container, box slotBox, activation, distribution, version, installed string) {
t.Helper()
spellings := []string{common.Major(version)}
if spec, ok := common.UseSpec(distribution, version); ok {
spellings = append(spellings, spec)
}
spellings := []string{common.Major(version), common.Spec(distribution, version)}
if alias, ok := common.Alias(distribution, installed); ok {
spellings = append(spellings, alias)
}
Expand Down
29 changes: 27 additions & 2 deletions tests/pre_install_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ local function pkg(java_version, fx)
end

-- Foojay answers observed on 2026-10-17 for linux/amd64 tar.gz packages, keyed
-- by "<distribution> <version>[ <latest>]".
-- by "<distribution>[ <version>][ <latest>]".
local foojay = {
["temurin 21"] = { pkg("21+35") },
["temurin 21 available"] = { pkg("21.0.12.1+1") },
Expand All @@ -39,9 +39,13 @@ local foojay = {
["zulu 21 available"] = { pkg("21.0.12.1+1"), pkg("21.0.12.1+1", true) },
["openjdk 21"] = { pkg("21+35") },
["openjdk 21 available"] = { pkg("21.0.2+13") },
["openjdk 25.0.2"] = { pkg("25.0.2+10") },
["openjdk 28-ea"] = { pkg("28-ea+19"), pkg("28-ea+18") },
["jetbrains 21"] = { pkg("21+2121") },
["jetbrains 21 available"] = { pkg("21.0.11+1163116") },
-- Searching asks for no version; abridged.
["openjdk"] = { pkg("25.0.2+10"), pkg("21.0.2+13") },
["temurin"] = { pkg("25.0.2+10"), pkg("21.0.8+9") },
}

local requests = {}
Expand All @@ -56,7 +60,10 @@ package.preload.http = function()
for key, value in request.url:sub(#JDKS + 1):gmatch("([^&=]+)=([^&]*)") do
params[key] = value
end
local key = params.distribution .. " " .. params.version
local key = params.distribution
if params.version ~= "" then
key = key .. " " .. params.version
end
if params.latest then
key = key .. " " .. params.latest
end
Expand Down Expand Up @@ -112,6 +119,9 @@ check("17-graal", "17.0.12-graal", true)
-- Anything longer than a major still matches exactly.
check("21.0.8-tem", "21.0.8+9-tem", false)
check("28.ea", "28-ea+19", false)
-- OpenJDK versions carry no suffix, however the input spells the distribution.
check("25.0.2-open", "25.0.2+10", false)
check("openjdk-25.0.2", "25.0.2+10", false)
-- On Windows the tar.gz retry keeps asking for the newest release.
RUNTIME.osType = "windows"
assert(check("21-jb", "21.0.11+1163116-jb", true) == 2, "21-jb: expected a zip lookup and a tar.gz retry")
Expand All @@ -122,4 +132,19 @@ requests = {}
PLUGIN:Available({ args = { "tem" } })
assert(#requests == 1 and not requests[1]:find("latest=", 1, true), "Available: unexpected lookup " .. requests[1])

-- Searching lists OpenJDK versions without a suffix, the way PreInstall names
-- them, so vfox marks them installed whether the query is open, openjdk or all.
local function listed(query)
local versions = {}
for _, item in ipairs(PLUGIN:Available({ args = { query } })) do
versions[item.version] = true
end
return versions
end
for _, query in ipairs({ "open", "openjdk", "all" }) do
assert(listed(query)["25.0.2+10"], "Available " .. query .. ": 25.0.2+10 is not listed")
end
local all = listed("all")
assert(all["25.0.2+10-tem"] and all["21.0.8+9-tem"], "Available all: Temurin versions lost their suffix")

print("PASS: " .. cases .. " PreInstall Foojay lookup cases")
23 changes: 23 additions & 0 deletions tests/pre_use_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ for _, version in ipairs({
"26-ea+13-graal",
"25.0.2-graalce",
"21.0.12+8-lnxabi2-fx",
-- OpenJDK versions carry no distribution suffix.
"25.0.2+10",
"21+35",
"21.0.2+13",
"28-ea+18",
"28-ea+19",
}) do
installed[version] = { name = "java", version = version, path = "/sdks/java-" .. version }
end
Expand Down Expand Up @@ -66,6 +72,23 @@ local cases = {
{ "25-graal", "25-graal" },
{ "8-zulu", "8-zulu" },
{ "26-graal", "26-graal" },
-- OpenJDK, however the input spells it, selects the version installed without a suffix.
{ "25.0.2", "25.0.2+10" },
{ "25.0.2-open", "25.0.2+10" },
{ "25.0.2+10-open", "25.0.2+10" },
{ "openjdk-25.0.2", "25.0.2+10" },
{ "openjdk-25.0.2+10", "25.0.2+10" },
{ "21-open", "21.0.2+13" },
{ "openjdk-21", "21.0.2+13" },
{ "28.ea", "28-ea+19" },
{ "28.ea.18", "28-ea+18" },
-- Never another distribution, JavaFX flavour or an EA build either.
{ "21.0.8", "21.0.8" },
{ "21.0.12-open", "21.0.12" },
{ "25.0.4-fx", "25.0.4-fx" },
{ "25.0.2-open-fx", "25.0.2-fx" },
{ "17-open", "17" },
{ "28-open", "28" },
}
for _, case in ipairs(cases) do
local result = PLUGIN:PreUse({ version = case[1], installedSdks = installed })
Expand Down
Loading