aboutsummaryrefslogtreecommitdiffstats
path: root/lua/mason-core/system-package.lua
diff options
context:
space:
mode:
authorWilliam Boman <william@redwill.se>2026-05-22 20:14:45 +0200
committerGitHub <noreply@github.com>2026-05-22 20:14:45 +0200
commit24e77d5289db0f7b6f4b405683047315b66dc75b (patch)
tree1d40c97d129c8d621d9c9d0645c7c268b49505b2 /lua/mason-core/system-package.lua
parentfeat(registry): add registry_cache setting for controlling cache behaviour (#... (diff)
downloadmason-24e77d5289db0f7b6f4b405683047315b66dc75b.tar
mason-24e77d5289db0f7b6f4b405683047315b66dc75b.tar.gz
mason-24e77d5289db0f7b6f4b405683047315b66dc75b.tar.bz2
mason-24e77d5289db0f7b6f4b405683047315b66dc75b.tar.lz
mason-24e77d5289db0f7b6f4b405683047315b66dc75b.tar.xz
mason-24e77d5289db0f7b6f4b405683047315b66dc75b.tar.zst
mason-24e77d5289db0f7b6f4b405683047315b66dc75b.zip
feat: add support for socket.dev firewall client (#2088)
Diffstat (limited to 'lua/mason-core/system-package.lua')
-rw-r--r--lua/mason-core/system-package.lua96
1 files changed, 96 insertions, 0 deletions
diff --git a/lua/mason-core/system-package.lua b/lua/mason-core/system-package.lua
new file mode 100644
index 00000000..798db774
--- /dev/null
+++ b/lua/mason-core/system-package.lua
@@ -0,0 +1,96 @@
+local Result = require "mason-core.result"
+local _ = require "mason-core.functional"
+local a = require "mason-core.async"
+local registry = require "mason-registry"
+local settings = require "mason.settings"
+local OneShotChannel = require("mason-core.async.control").OneShotChannel
+
+---@class SystemPackage
+---@field name string
+---@field condition? fun(): bool
+local SystemPackage = {}
+SystemPackage.__index = SystemPackage
+
+---@type table<string, OneShotChannel>
+SystemPackage.channels = {}
+
+function SystemPackage:new(system_pkg_name)
+ ---@type SystemPackage
+ local instance = {}
+ setmetatable(instance, self)
+ instance.name = system_pkg_name
+ return instance
+end
+
+function SystemPackage:conditional(fn)
+ self.condition = fn
+ return self
+end
+
+---@async
+function SystemPackage:get_package()
+ a.scheduler()
+ pcall(a.wait, registry.refresh_system)
+ if not registry.has_system_package(self.name) then
+ -- Force update to the very latest registry version
+ pcall(a.wait, registry.update)
+ end
+ if not registry.has_system_package(self.name) then
+ return Result.failure("Unable to find system package " .. self.name)
+ end
+ return Result.pcall(registry.get_system_package, self.name)
+end
+
+---@async
+---@return Result<boolean>
+function SystemPackage:needs_install()
+ return Result.try(function(try)
+ if self.condition and not self.condition() then
+ return false
+ end
+ local pkg = try(self:get_package())
+ if not pkg:is_installed() or pkg:is_installing() then
+ return true
+ end
+ if pkg:get_installed_version() ~= pkg:get_latest_version() then
+ return true
+ end
+ return false
+ end)
+end
+
+---@async
+function SystemPackage:await_channel()
+ assert(SystemPackage.channels[self.name], "Tried to await non-existing channel.")
+ local success, result = SystemPackage.channels[self.name]:receive()
+ if not success then
+ return Result.failure("Failed to install system package " .. self.name .. ". Error: " .. result)
+ end
+ return Result.success()
+end
+
+---@async
+---@return Result
+function SystemPackage:install()
+ return Result.try(function(try)
+ local pkg = try(self:get_package())
+ if not pkg:is_installing() then
+ local channel = OneShotChannel:new()
+ SystemPackage.channels[self.name] = channel
+ pkg:install({}, function(success, result)
+ channel:send(success, result)
+ end)
+ end
+ return self:await_channel()
+ end)
+end
+
+function SystemPackage:__tostring()
+ return ("SystemPackage(name=%s)"):format(self.name)
+end
+
+SystemPackage.sfw = SystemPackage:new("sfw@latest"):conditional(function()
+ return settings.current.firewall.enabled and settings.current.firewall.auto_managed
+end)
+
+return SystemPackage