aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Boman <william@redwill.se>2022-10-09 23:14:15 +0200
committerGitHub <noreply@github.com>2022-10-09 23:14:15 +0200
commitf336a8fac9090b4f8f5b3b430b5870efbd4b9113 (patch)
tree5f2199e61ac2b0f3814df7dabe7c7eb7cf07cc80
parentfeat(registry): add iferr tool for Go (#528) (diff)
downloadmason-f336a8fac9090b4f8f5b3b430b5870efbd4b9113.tar
mason-f336a8fac9090b4f8f5b3b430b5870efbd4b9113.tar.gz
mason-f336a8fac9090b4f8f5b3b430b5870efbd4b9113.tar.bz2
mason-f336a8fac9090b4f8f5b3b430b5870efbd4b9113.tar.lz
mason-f336a8fac9090b4f8f5b3b430b5870efbd4b9113.tar.xz
mason-f336a8fac9090b4f8f5b3b430b5870efbd4b9113.tar.zst
mason-f336a8fac9090b4f8f5b3b430b5870efbd4b9113.zip
feat(npm): speed up checking for new versions (#530)
-rw-r--r--lua/mason-core/managers/npm/init.lua40
-rw-r--r--lua/mason-core/package/version-check.lua9
-rw-r--r--lua/mason-core/result.lua9
-rw-r--r--tests/mason-core/managers/npm_spec.lua58
-rw-r--r--tests/mason-core/result_spec.lua21
5 files changed, 91 insertions, 46 deletions
diff --git a/lua/mason-core/managers/npm/init.lua b/lua/mason-core/managers/npm/init.lua
index 84d9258a..0fe9fafb 100644
--- a/lua/mason-core/managers/npm/init.lua
+++ b/lua/mason-core/managers/npm/init.lua
@@ -1,10 +1,10 @@
local spawn = require "mason-core.spawn"
-local Optional = require "mason-core.optional"
local installer = require "mason-core.installer"
local Result = require "mason-core.result"
local path = require "mason-core.path"
local _ = require "mason-core.functional"
local platform = require "mason-core.platform"
+local api = require "mason-registry.api"
local list_copy = _.list_copy
@@ -110,26 +110,26 @@ function M.check_outdated_primary_package(receipt, install_dir)
return Result.failure "Receipt does not have a primary source of type npm"
end
local primary_package = receipt.primary_source.package
- local npm_outdated = spawn.npm { "outdated", "--json", primary_package, cwd = install_dir }
- if npm_outdated:is_success() then
- return Result.failure "Primary package is not outdated."
- end
- return npm_outdated:recover_catching(function(result)
- assert(result.exit_code == 1, "Expected npm outdated to return exit code 1.")
- local data = vim.json.decode(result.stdout)
-
- return Optional.of_nilable(data[primary_package])
- :map(function(outdated_package)
- if outdated_package.current ~= outdated_package.latest then
- return {
- name = primary_package,
- current_version = assert(outdated_package.current, "missing current npm package version"),
- latest_version = assert(outdated_package.latest, "missing latest npm package version"),
- }
- end
+ return M.get_installed_primary_package_version(receipt, install_dir)
+ :and_then(function(installed_version)
+ return api.get(("/api/npm/%s/latest-version"):format(primary_package)):map(function(response)
+ return {
+ installed = installed_version,
+ latest = response.version,
+ }
end)
- :or_else_throw()
- end)
+ end)
+ :and_then(function(versions)
+ if versions.installed ~= versions.latest then
+ return Result.success {
+ name = primary_package,
+ current_version = versions.installed,
+ latest_version = versions.latest,
+ }
+ else
+ return Result.failure "Primary package is not outdated."
+ end
+ end)
end
return M
diff --git a/lua/mason-core/package/version-check.lua b/lua/mason-core/package/version-check.lua
index 3359446a..203b5057 100644
--- a/lua/mason-core/package/version-check.lua
+++ b/lua/mason-core/package/version-check.lua
@@ -8,6 +8,7 @@ local go = require "mason-core.managers.go"
local luarocks = require "mason-core.managers.luarocks"
local npm = require "mason-core.managers.npm"
local pip3 = require "mason-core.managers.pip3"
+local log = require "mason-core.log"
---@param field_name string
local function version_in_receipt(field_name)
@@ -52,7 +53,7 @@ local get_new_version_by_type = {
["github_tag"] = github.check_outdated_primary_package_tag,
}
----@param provider_mapping table<string, async fun(receipt: InstallReceipt, install_dir: string)>: Result
+---@param provider_mapping table<string, async fun(receipt: InstallReceipt, install_dir: string): Result>
local function version_check(provider_mapping)
---@param receipt InstallReceipt
---@param install_dir string
@@ -64,6 +65,12 @@ local function version_check(provider_mapping)
)
end
return check(receipt, install_dir)
+ :on_success(function(version)
+ log.debug("Version check", version)
+ end)
+ :on_failure(function(failure)
+ log.debug("Version check failed", tostring(failure))
+ end)
end
end
diff --git a/lua/mason-core/result.lua b/lua/mason-core/result.lua
index 95c69afa..5c7af3be 100644
--- a/lua/mason-core/result.lua
+++ b/lua/mason-core/result.lua
@@ -147,6 +147,15 @@ function Result:ok()
end
end
+---@param fn fun(value: any): Result
+function Result:and_then(fn)
+ if self:is_success() then
+ return fn(self.value)
+ else
+ return self
+ end
+end
+
---@param fn fun(): any
---@return Result
function Result.run_catching(fn)
diff --git a/tests/mason-core/managers/npm_spec.lua b/tests/mason-core/managers/npm_spec.lua
index 78845ff1..71d93301 100644
--- a/tests/mason-core/managers/npm_spec.lua
+++ b/tests/mason-core/managers/npm_spec.lua
@@ -1,3 +1,4 @@
+local stub = require "luassert.stub"
local spy = require "luassert.spy"
local match = require "luassert.match"
local mock = require "luassert.mock"
@@ -6,6 +7,7 @@ local npm = require "mason-core.managers.npm"
local Result = require "mason-core.result"
local spawn = require "mason-core.spawn"
local path = require "mason-core.path"
+local api = require "mason-registry.api"
describe("npm manager", function()
it(
@@ -83,7 +85,7 @@ describe("npm version check", function()
it(
"should return current version",
async_test(function()
- spawn.npm = spy.new(function()
+ stub(spawn, "npm", function()
return Result.success {
stdout = [[
{
@@ -113,26 +115,27 @@ describe("npm version check", function()
assert.spy(spawn.npm).was_called_with { "ls", "--json", cwd = path.package_prefix "dummy" }
assert.is_true(result:is_success())
assert.equals("2.0.0", result:get_or_nil())
-
- spawn.npm = nil
end)
)
it(
"should return outdated primary package",
async_test(function()
- spawn.npm = spy.new(function()
- -- npm outdated returns with exit code 1 if outdated packages are found!
- return Result.failure {
- exit_code = 1,
+ stub(api, "get")
+ api.get.on_call_with("/api/npm/bash-language-server/latest-version").returns(Result.success {
+ name = "bash-language-server",
+ version = "2.0.0",
+ })
+ stub(spawn, "npm", function()
+ return Result.success {
stdout = [[
{
- "bash-language-server": {
- "current": "1.17.0",
- "wanted": "1.17.0",
- "latest": "2.0.0",
- "dependent": "bash",
- "location": "/tmp/install/dir"
+ "name": "bash",
+ "dependencies": {
+ "bash-language-server": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/bash-language-server/-/bash-language-server-1.17.0.tgz"
+ }
}
}
]],
@@ -149,32 +152,38 @@ describe("npm version check", function()
path.package_prefix "dummy"
)
- assert.spy(spawn.npm).was_called(1)
- assert.spy(spawn.npm).was_called_with {
- "outdated",
- "--json",
- "bash-language-server",
- cwd = path.package_prefix "dummy",
- }
assert.is_true(result:is_success())
assert.same({
name = "bash-language-server",
current_version = "1.17.0",
latest_version = "2.0.0",
}, result:get_or_nil())
-
- spawn.npm = nil
end)
)
it(
"should return failure if primary package is not outdated",
async_test(function()
- spawn.npm = spy.new(function()
+ stub(spawn, "npm", function()
return Result.success {
- stdout = "{}",
+ stdout = [[
+ {
+ "name": "bash",
+ "dependencies": {
+ "bash-language-server": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/bash-language-server/-/bash-language-server-1.17.0.tgz"
+ }
+ }
+ }
+ ]],
}
end)
+ stub(api, "get")
+ api.get.on_call_with("/api/npm/bash-language-server/latest-version").returns(Result.success {
+ name = "bash-language-server",
+ version = "1.17.0",
+ })
local result = npm.check_outdated_primary_package(
mock.new {
@@ -188,7 +197,6 @@ describe("npm version check", function()
assert.is_true(result:is_failure())
assert.equals("Primary package is not outdated.", result:err_or_nil())
- spawn.npm = nil
end)
)
end)
diff --git a/tests/mason-core/result_spec.lua b/tests/mason-core/result_spec.lua
index 737d8c56..ee722281 100644
--- a/tests/mason-core/result_spec.lua
+++ b/tests/mason-core/result_spec.lua
@@ -153,4 +153,25 @@ describe("result", function()
assert.is_true(getmetatable(opt) == Optional)
assert.is_false(opt:is_present())
end)
+
+ it("should chain results", function()
+ local success = Result.success("First"):and_then(function(value)
+ return Result.success(value .. " Second")
+ end)
+ local failure = Result.success("Error"):and_then(Result.failure)
+
+ assert.is_true(success:is_success())
+ assert.equals("First Second", success:get_or_nil())
+ assert.is_true(failure:is_failure())
+ assert.equals("Error", failure:err_or_nil())
+ end)
+
+ it("should not chain results upon failure", function()
+ local chain = spy.new()
+ local failure = Result.failure("Error"):and_then(chain)
+
+ assert.is_true(failure:is_failure())
+ assert.equals("Error", failure:err_or_nil())
+ assert.spy(chain).was_not_called()
+ end)
end)