diff options
| -rw-r--r-- | lua/mason-core/managers/gem/init.lua | 59 | ||||
| -rw-r--r-- | lua/mason-core/providers/init.lua | 7 | ||||
| -rw-r--r-- | lua/mason-registry/api.lua | 9 | ||||
| -rw-r--r-- | lua/mason/providers/registry-api/init.lua | 8 | ||||
| -rw-r--r-- | tests/mason-core/managers/gem_spec.lua | 60 |
5 files changed, 65 insertions, 78 deletions
diff --git a/lua/mason-core/managers/gem/init.lua b/lua/mason-core/managers/gem/init.lua index 0f26fafb..79e9921b 100644 --- a/lua/mason-core/managers/gem/init.lua +++ b/lua/mason-core/managers/gem/init.lua @@ -6,7 +6,7 @@ local spawn = require "mason-core.spawn" local Optional = require "mason-core.optional" local installer = require "mason-core.installer" local platform = require "mason-core.platform" -local fs = require "mason-core.fs" +local providers = require "mason-core.providers" local M = {} @@ -98,26 +98,6 @@ end ---@alias GemOutdatedPackage {name:string, current_version: string, latest_version: string} ----Parses a string input like "package (0.1.0 < 0.2.0)" into its components ----@param outdated_gem string ----@return GemOutdatedPackage -function M.parse_outdated_gem(outdated_gem) - local package_name, version_expression = outdated_gem:match "^(.+) %((.+)%)" - if not package_name or not version_expression then - -- unparsable - return nil - end - local current_version, latest_version = unpack(vim.split(version_expression, "<")) - - ---@type GemOutdatedPackage - local outdated_package = { - name = vim.trim(package_name), - current_version = vim.trim(current_version), - latest_version = vim.trim(latest_version), - } - return outdated_package -end - ---Parses the stdout of the `gem list` command into a table<package_name, version> ---@param output string function M.parse_gem_list_output(output) @@ -132,10 +112,6 @@ function M.parse_gem_list_output(output) return gem_versions end -local function not_empty(s) - return s ~= nil and s ~= "" -end - ---@async ---@param receipt InstallReceipt<InstallReceiptPackageSource> ---@param install_dir string @@ -143,25 +119,26 @@ function M.check_outdated_primary_package(receipt, install_dir) if receipt.primary_source.type ~= "gem" then return Result.failure "Receipt does not have a primary source of type gem" end - return spawn.gem({ "outdated", cwd = install_dir, env = env(install_dir) }):map_catching(function(result) - ---@type string[] - local lines = vim.split(result.stdout, "\n") - local outdated_gems = vim.tbl_map(M.parse_outdated_gem, vim.tbl_filter(not_empty, lines)) - - local outdated_gem = _.find_first(function(gem) - return gem.name == receipt.primary_source.package and gem.current_version ~= gem.latest_version - end, outdated_gems) - - return Optional.of_nilable(outdated_gem) - :map(function(gem) + return M.get_installed_primary_package_version(receipt, install_dir) + :and_then(function(installed_version) + return providers.rubygems.get_latest_version(receipt.primary_source.package):map(function(latest) return { - name = receipt.primary_source.package, - current_version = assert(gem.current_version, "current_version missing in gem"), - latest_version = assert(gem.latest_version, "latest_version missing in gem"), + installed = installed_version, + latest = latest.version, } end) - :or_else_throw "Primary package is not outdated." - end) + end) + :and_then(function(versions) + if versions.installed ~= versions.latest then + return Result.success { + name = receipt.primary_source.package, + current_version = versions.installed, + latest_version = versions.latest, + } + else + return Result.failure "Primary package is not outdated." + end + end) end ---@async diff --git a/lua/mason-core/providers/init.lua b/lua/mason-core/providers/init.lua index 76bd431b..bf8e2155 100644 --- a/lua/mason-core/providers/init.lua +++ b/lua/mason-core/providers/init.lua @@ -24,10 +24,17 @@ local Result = require "mason-core.result" ---@field get_latest_version? async fun(pkg: string): Result # Result<PyPiPackage> ---@field get_all_versions? async fun(pkg: string): Result # Result<string[]> # Sorting should not be relied upon due to "proprietary" sorting algo in pip that is difficult to replicate in mason-registry-api. +---@alias RubyGem { name: string, version: string } + +---@class RubyGemsProvider +---@field get_latest_version? async fun(gem: string): Result # Result<RubyGem> +---@field get_all_versions? async fun(gem: string): Result # Result<string[]> + ---@class Provider ---@field github? GitHubProvider ---@field npm? NpmProvider ---@field pypi? PyPiProvider +---@field rubygems? RubyGemsProvider local function service_mt(service) return setmetatable({}, { diff --git a/lua/mason-registry/api.lua b/lua/mason-registry/api.lua index 25a9a8bb..6f658c83 100644 --- a/lua/mason-registry/api.lua +++ b/lua/mason-registry/api.lua @@ -78,4 +78,13 @@ api.pypi = { }, } +api.rubygems = { + versions = { + ---@type ApiSignature<{ gem: string }> + latest = get "/api/rubygems/{gem}/versions/latest", + ---@type ApiSignature<{ gem: string }> + all = get "/api/rubygemspypi/{gem}/versions/all", + }, +} + return api diff --git a/lua/mason/providers/registry-api/init.lua b/lua/mason/providers/registry-api/init.lua index 24c35ee8..f5a9aef7 100644 --- a/lua/mason/providers/registry-api/init.lua +++ b/lua/mason/providers/registry-api/init.lua @@ -37,4 +37,12 @@ return { return api.pypi.versions.all { package = pkg } end, }, + rubygems = { + get_latest_version = function(gem) + return api.rubygems.versions.latest { gem = gem } + end, + get_all_versions = function(gem) + return api.rubygems.versions.all { gem = gem } + end, + }, } diff --git a/tests/mason-core/managers/gem_spec.lua b/tests/mason-core/managers/gem_spec.lua index 4cc7705b..f99666e6 100644 --- a/tests/mason-core/managers/gem_spec.lua +++ b/tests/mason-core/managers/gem_spec.lua @@ -1,10 +1,12 @@ local spy = require "luassert.spy" +local stub = require "luassert.stub" local match = require "luassert.match" local mock = require "luassert.mock" local installer = require "mason-core.installer" local gem = require "mason-core.managers.gem" local Result = require "mason-core.result" local spawn = require "mason-core.spawn" +local api = require "mason-registry.api" describe("gem manager", function() it( @@ -100,16 +102,19 @@ strscan (default: 3.0.1) async_test(function() spawn.gem = spy.new(function() return Result.success { - stdout = [[bigdecimal (3.1.1 < 3.1.2) -cgi (0.3.1 < 0.3.2) -logger (1.5.0 < 1.5.1) -ostruct (0.5.2 < 0.5.3) -reline (0.3.0 < 0.3.1) -securerandom (0.1.1 < 0.2.0) -solargraph (0.44.0 < 0.44.3) + stdout = [[shellwords (default: 0.1.0) +singleton (default: 0.1.1) +solargraph (0.44.0) +stringio (default: 3.0.1) +strscan (default: 3.0.1) ]], } end) + stub(api, "get") + api.get.on_call_with("/api/rubygems/solargraph/versions/latest").returns(Result.success { + name = "solargraph", + version = "0.44.3", + }) local result = gem.check_outdated_primary_package( mock.new { @@ -121,16 +126,6 @@ solargraph (0.44.0 < 0.44.3) "/tmp/install/dir" ) - assert.spy(spawn.gem).was_called(1) - assert.spy(spawn.gem).was_called_with(match.tbl_containing { - "outdated", - cwd = "/tmp/install/dir", - env = match.tbl_containing { - GEM_HOME = "/tmp/install/dir", - GEM_PATH = "/tmp/install/dir", - PATH = match.matches "^/tmp/install/dir/bin:.*$", - }, - }) assert.is_true(result:is_success()) assert.same({ name = "solargraph", @@ -147,9 +142,19 @@ solargraph (0.44.0 < 0.44.3) async_test(function() spawn.gem = spy.new(function() return Result.success { - stdout = "", + stdout = [[shellwords (default: 0.1.0) +singleton (default: 0.1.1) +solargraph (0.44.0) +stringio (default: 3.0.1) +strscan (default: 3.0.1) +]], } end) + stub(api, "get") + api.get.on_call_with("/api/rubygems/solargraph/versions/latest").returns(Result.success { + name = "solargraph", + version = "0.44.0", + }) local result = gem.check_outdated_primary_package( mock.new { @@ -167,25 +172,6 @@ solargraph (0.44.0 < 0.44.3) end) ) - it("parses outdated gem output", function() - local normalize = gem.parse_outdated_gem - assert.same({ - name = "solargraph", - current_version = "0.42.2", - latest_version = "0.44.2", - }, normalize [[solargraph (0.42.2 < 0.44.2)]]) - assert.same({ - name = "sorbet-runtime", - current_version = "0.5.9307", - latest_version = "0.5.9468", - }, normalize [[sorbet-runtime (0.5.9307 < 0.5.9468)]]) - end) - - it("returns nil when unable to parse outdated gem", function() - assert.is_nil(gem.parse_outdated_gem "a whole bunch of gibberish!") - assert.is_nil(gem.parse_outdated_gem "") - end) - it("should parse gem list output", function() assert.same( { |
