Skip to content

fix: resolve latest android sdk version numerically - #11

Merged
jdx merged 1 commit into
mainfrom
codex/fix-android-sdk-default-version
Jul 16, 2026
Merged

fix: resolve latest android sdk version numerically#11
jdx merged 1 commit into
mainfrom
codex/fix-android-sdk-default-version

Conversation

@jdx

@jdx jdx commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

  • order Android command-line tool versions numerically with newest first
  • keep numeric versions ahead of any unexpected nonnumeric values without treating versions as semver
  • add a regression test covering 1.0, 2.1, 9.0, 10.0, and 22.0
  • run the ordering test with Lua on the Ubuntu integration job

Root cause

The available hook sorted opaque strings lexicographically in ascending order. vfox resolves an unspecified version from the first returned entry, so 1.0 was selected while values such as 10.0 and 22.0 were ordered incorrectly. Android command-line tool releases use numeric identifiers, so this backend now applies tool-specific numeric ordering.

Validation

  • mise x stylua@latest -- stylua --check metadata.lua hooks test/version_order.lua
  • mise x actionlint@latest -- actionlint .github/workflows/test.yml
  • mise x lua@5.4 -- lua test/version_order.lua .
  • isolated mise latest android-sdk resolves to 22.0
  • ./test/run.sh

Resolves #5.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the version sorting logic in hooks/available.lua to sort Android command-line tool versions numerically in descending order, and introduces a test suite in test/version_order.lua. The review feedback correctly points out that using tonumber directly on version strings will fail for multi-dot versions (e.g., 22.0.1), resulting in incorrect sorting. It is recommended to parse version strings into segment lists for a robust comparison and to expand the test cases to cover these multi-part versions.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread hooks/available.lua
Comment on lines 35 to 48
table.sort(versions, function(a, b)
return a.version < b.version
local a_number = tonumber(a.version)
local b_number = tonumber(b.version)

if a_number and b_number then
return a_number > b_number
elseif a_number then
return true
elseif b_number then
return false
end

return a.version > b.version
end)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using tonumber directly on the version string only works for single-dot numeric versions (e.g., 12.0 or 2.1) because they are valid floating-point numbers in Lua. If a version with multiple dots (e.g., 12.0.1 or 12.1.0) is encountered, tonumber will return nil. This causes the version to be treated as non-numeric, resulting in incorrect sorting (sorting it after older numeric versions).

To make the version comparison robust and future-proof, we can parse the version strings into lists of numeric components by splitting them on . and comparing them segment-by-segment.

    local function parse_version(version_str)
        local parts = {}
        for part in string.gmatch(version_str, "[^.]+") do
            local num = tonumber(part)
            if not num then return nil end
            table.insert(parts, num)
        end
        return parts
    end

    table.sort(versions, function(a, b)
        local a_parts = parse_version(a.version)
        local b_parts = parse_version(b.version)

        if a_parts and b_parts then
            for i = 1, math.max(#a_parts, #b_parts) do
                local a_val = a_parts[i] or 0
                local b_val = b_parts[i] or 0
                if a_val ~= b_val then
                    return a_val > b_val
                end
            end
            return false
        elseif a_parts then
            return true
        elseif b_parts then
            return false
        end

        return a.version > b.version
    end)

Comment thread test/version_order.lua
Comment on lines +3 to +12
local repository_xml = [[
<sdk-repository>
<remotePackage path="cmdline-tools;1.0"></remotePackage>
<remotePackage path="cmdline-tools;9.0"></remotePackage>
<remotePackage path="cmdline-tools;10.0"></remotePackage>
<remotePackage path="cmdline-tools;22.0"></remotePackage>
<remotePackage path="cmdline-tools;2.1"></remotePackage>
<remotePackage path="cmdline-tools;latest"></remotePackage>
</sdk-repository>
]]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To ensure that multi-part numeric versions (e.g., 22.0.1, 22.1.0) are correctly handled and sorted by the new comparison logic, let's add them to the mock repository XML.

local repository_xml = [[
<sdk-repository>
  <remotePackage path="cmdline-tools;1.0"></remotePackage>
  <remotePackage path="cmdline-tools;9.0"></remotePackage>
  <remotePackage path="cmdline-tools;10.0"></remotePackage>
  <remotePackage path="cmdline-tools;22.0"></remotePackage>
  <remotePackage path="cmdline-tools;22.0.1"></remotePackage>
  <remotePackage path="cmdline-tools;22.1.0"></remotePackage>
  <remotePackage path="cmdline-tools;2.1"></remotePackage>
  <remotePackage path="cmdline-tools;latest"></remotePackage>
</sdk-repository>
]]

Comment thread test/version_order.lua
PLUGIN = {}
assert(loadfile(plugin_dir .. "/hooks/available.lua"))()
local versions = PLUGIN:Available({})
local expected = { "22.0", "10.0", "9.0", "2.1", "1.0" }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Update the expected sorted list to include the new multi-part versions in their correct descending order.

local expected = { "22.1.0", "22.0.1", "22.0", "10.0", "9.0", "2.1", "1.0" }

@jdx
jdx merged commit d94bb26 into main Jul 16, 2026
4 checks passed
@jdx
jdx deleted the codex/fix-android-sdk-default-version branch July 16, 2026 21:07
@IndiTheo

Copy link
Copy Markdown

Thank you very much, @jdx, for the quick response in mise-plugins/mise-android-sdk#39 and for the fix. Appreciate that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Installs 1.0 by default

2 participants