diff options
| author | William Boman <william@redwill.se> | 2026-05-22 20:14:45 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-22 20:14:45 +0200 |
| commit | 24e77d5289db0f7b6f4b405683047315b66dc75b (patch) | |
| tree | 1d40c97d129c8d621d9c9d0645c7c268b49505b2 /lua/mason-core/system-package.lua | |
| parent | feat(registry): add registry_cache setting for controlling cache behaviour (#... (diff) | |
| download | mason-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.lua | 96 |
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 |
