aboutsummaryrefslogtreecommitdiffstats
path: root/lua/mason-core/installer/linker.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/mason-core/installer/linker.lua')
-rw-r--r--lua/mason-core/installer/linker.lua69
1 files changed, 52 insertions, 17 deletions
diff --git a/lua/mason-core/installer/linker.lua b/lua/mason-core/installer/linker.lua
index a26d2592..415f61eb 100644
--- a/lua/mason-core/installer/linker.lua
+++ b/lua/mason-core/installer/linker.lua
@@ -1,17 +1,17 @@
+local Path = require "mason-core.path"
local Result = require "mason-core.result"
local _ = require "mason-core.functional"
local a = require "mason-core.async"
local fs = require "mason-core.fs"
local log = require "mason-core.log"
-local path = require "mason-core.path"
local platform = require "mason-core.platform"
local M = {}
---@alias LinkContext { type: '"bin"' | '"opt"' | '"share"', prefix: fun(path: string, location: InstallLocation): string }
----@type table<'"BIN"' | '"OPT"' | '"SHARE"', LinkContext>
local LinkContext = {
+ ---@type LinkContext
BIN = {
type = "bin",
---@param path string
@@ -20,6 +20,7 @@ local LinkContext = {
return location:bin(path)
end,
},
+ ---@type LinkContext
OPT = {
type = "opt",
---@param path string
@@ -28,6 +29,7 @@ local LinkContext = {
return location:opt(path)
end,
},
+ ---@type LinkContext
SHARE = {
type = "share",
---@param path string
@@ -38,6 +40,36 @@ local LinkContext = {
},
}
+local SystemLinkContext = {
+ ---@type LinkContext
+ BIN = {
+ type = "bin",
+ ---@param path string
+ ---@param location InstallLocation
+ prefix = function(path, location)
+ return location:opt(Path.concat { "mason", "system", "bin", path })
+ end,
+ },
+ ---@type LinkContext
+ OPT = {
+ type = "opt",
+ ---@param path string
+ ---@param location InstallLocation
+ prefix = function(path, location)
+ return location:opt(Path.concat { "mason", "system", "opt", path })
+ end,
+ },
+ ---@type LinkContext
+ SHARE = {
+ type = "share",
+ ---@param path string
+ ---@param location InstallLocation
+ prefix = function(path, location)
+ return location:opt(Path.concat { "mason", "system", "share", path })
+ end,
+ },
+}
+
---@param receipt InstallReceipt
---@param link_context LinkContext
---@param location InstallLocation
@@ -48,7 +80,7 @@ local function unlink(receipt, link_context, location)
return
end
for linked_file in pairs(links) do
- if receipt:get_schema_version() == "1.0" and link_context == LinkContext.BIN and platform.is.win then
+ if receipt:get_schema_version() == "1.0" and link_context.type == "bin" and platform.is.win then
linked_file = linked_file .. ".cmd"
end
local share_path = link_context.prefix(linked_file, location)
@@ -63,10 +95,11 @@ end
---@nodiscard
function M.unlink(pkg, receipt, location)
log.fmt_debug("Unlinking %s", pkg, receipt:get_links())
+ local link_context = pkg.spec.system and SystemLinkContext or LinkContext
return Result.try(function(try)
- try(unlink(receipt, LinkContext.BIN, location))
- try(unlink(receipt, LinkContext.SHARE, location))
- try(unlink(receipt, LinkContext.OPT, location))
+ try(unlink(receipt, link_context.BIN, location))
+ try(unlink(receipt, link_context.SHARE, location))
+ try(unlink(receipt, link_context.OPT, location))
end)
end
@@ -78,12 +111,12 @@ local function link(context, link_context, link_fn)
log.trace("Linking", context.package, link_context.type, context.links[link_context.type])
return Result.try(function(try)
for name, rel_path in pairs(context.links[link_context.type]) do
- if platform.is.win and link_context == LinkContext.BIN then
+ if platform.is.win and link_context.type == "bin" then
name = ("%s.cmd"):format(name)
end
local new_abs_path = link_context.prefix(name, context.location)
- local target_abs_path = path.concat { context:get_install_path(), rel_path }
- local target_rel_path = path.relative(new_abs_path, target_abs_path)
+ local target_abs_path = Path.concat { context:get_install_path(), rel_path }
+ local target_rel_path = Path.relative(new_abs_path, target_abs_path)
-- 1. Ensure destination directory exists
a.scheduler()
@@ -129,8 +162,9 @@ local function copyfile(context, link_context)
end
---@param context InstallContext
-local function win_bin_wrapper(context)
- return link(context, LinkContext.BIN, function(new_abs_path, __, target_rel_path)
+---@param link_context LinkContext
+local function win_bin_wrapper(context, link_context)
+ return link(context, link_context, function(new_abs_path, __, target_rel_path)
local windows_target_rel_path = target_rel_path:gsub("/", "\\")
return Result.pcall(
fs.async.write_file,
@@ -156,15 +190,16 @@ end
---@nodiscard
function M.link(context)
log.fmt_debug("Linking %s", context.package)
+ local link_context = context.package.spec.system and SystemLinkContext or LinkContext
return Result.try(function(try)
if platform.is.win then
- try(win_bin_wrapper(context))
- try(copyfile(context, LinkContext.SHARE))
- try(copyfile(context, LinkContext.OPT))
+ try(win_bin_wrapper(context, link_context.BIN))
+ try(copyfile(context, link_context.SHARE))
+ try(copyfile(context, link_context.OPT))
else
- try(symlink(context, LinkContext.BIN))
- try(symlink(context, LinkContext.SHARE))
- try(symlink(context, LinkContext.OPT))
+ try(symlink(context, link_context.BIN))
+ try(symlink(context, link_context.SHARE))
+ try(symlink(context, link_context.OPT))
end
end)
end