Skip to content

Commit

Permalink
feat(linker): use relative targets for symlinks
Browse files Browse the repository at this point in the history
Closes #1156.
  • Loading branch information
williamboman committed Oct 13, 2023
1 parent 2d317ae commit 760af96
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 27 deletions.
16 changes: 9 additions & 7 deletions lua/mason-core/installer/linker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ end
---@async
---@param context InstallContext
---@param link_context LinkContext
---@param link_fn async fun(new_abs_path: string, target_abs_path: string): Result
---@param link_fn async fun(new_abs_path: string, target_abs_path: string, target_rel_path: string): Result
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)
Expand All @@ -83,6 +83,7 @@ local function link(context, link_context, link_fn)
end
local new_abs_path = link_context.prefix(name, context.location)
local target_abs_path = path.concat { context.package:get_install_path(), rel_path }
local target_rel_path = path.relative(new_abs_path, target_abs_path)

do
-- 1. Ensure destination directory exists
Expand All @@ -109,7 +110,7 @@ local function link(context, link_context, link_fn)
end

-- 3. Execute link.
try(link_fn(new_abs_path, target_abs_path))
try(link_fn(new_abs_path, target_abs_path, target_rel_path))
context.receipt:with_link(link_context.type, name, rel_path)
end
end)
Expand All @@ -118,8 +119,8 @@ end
---@param context InstallContext
---@param link_context LinkContext
local function symlink(context, link_context)
return link(context, link_context, function(new_abs_path, target_abs_path)
return Result.pcall(fs.async.symlink, target_abs_path, new_abs_path)
return link(context, link_context, function(new_abs_path, _, target_rel_path)
return Result.pcall(fs.async.symlink, target_rel_path, new_abs_path)
end)
end

Expand All @@ -133,7 +134,8 @@ end

---@param context InstallContext
local function win_bin_wrapper(context)
return link(context, LinkContext.BIN, function(new_abs_path, target_abs_path)
return link(context, LinkContext.BIN, function(new_abs_path, __, target_rel_path)
local windows_target_rel_path = target_rel_path:gsub("/", "\\")
return Result.pcall(
fs.async.write_file,
new_abs_path,
Expand All @@ -147,8 +149,8 @@ local function win_bin_wrapper(context)
SETLOCAL
CALL :find_dp0
endLocal & goto #_undefined_# 2>NUL || title %%COMSPEC%% & "%s" %%*
]]):format(target_abs_path))
endLocal & goto #_undefined_# 2>NUL || title %%COMSPEC%% & "%%dp0%%\%s" %%*
]]):format(windows_target_rel_path))
)
end)
end
Expand Down
2 changes: 1 addition & 1 deletion lua/mason-core/path.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function M.relative(from, to)

local common_parent, distance = find_closest_common_parent(from_normalized, to_normalized)
local relative_path_component = distance == 0 and "." or (".."):rep(distance, "/")
return vim.fs.joinpath(relative_path_component, to_normalized:sub(#common_parent + 1))
return M.concat { relative_path_component, to_normalized:sub(#common_parent + 1) }
end

return M
33 changes: 14 additions & 19 deletions tests/mason-core/installer/linker_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ EXIT /b
SETLOCAL
CALL :find_dp0
endLocal & goto #_undefined_# 2>NUL || title %%COMSPEC%% & "%s" %%*]]
endLocal & goto #_undefined_# 2>NUL || title %%COMSPEC%% & "%%dp0%%\%s" %%*]]

describe("linker", function()
local snapshot
Expand Down Expand Up @@ -63,13 +63,10 @@ describe("linker", function()
assert.spy(fs.async.symlink).was_called(2)
assert
.spy(fs.async.symlink)
.was_called_with(path.concat { dummy:get_install_path(), "another-executable" }, ctx.location:bin "another-executable")
.was_called_with("../packages/dummy/another-executable", ctx.location:bin "another-executable")
assert
.spy(fs.async.symlink)
.was_called_with(
path.concat { dummy:get_install_path(), "nested", "path", "my-executable" },
ctx.location:bin "my-executable"
)
.was_called_with("../packages/dummy/nested/path/my-executable", ctx.location:bin "my-executable")
end)

it("should write executable wrapper on Windows", function()
Expand Down Expand Up @@ -101,14 +98,15 @@ describe("linker", function()

assert.spy(fs.async.symlink).was_called(0)
assert.spy(fs.async.write_file).was_called(2)
assert.spy(fs.async.write_file).was_called_with(
ctx.location:bin "another-executable.cmd",
WIN_CMD_SCRIPT:format(path.concat { dummy:get_install_path(), "another-executable" })
)
assert.spy(fs.async.write_file).was_called_with(
ctx.location:bin "my-executable.cmd",
WIN_CMD_SCRIPT:format(path.concat { dummy:get_install_path(), "nested", "path", "my-executable" })
)
assert
.spy(fs.async.write_file)
.was_called_with(ctx.location:bin "another-executable.cmd", WIN_CMD_SCRIPT:format "..\\packages\\dummy\\another-executable")
assert
.spy(fs.async.write_file)
.was_called_with(
ctx.location:bin "my-executable.cmd",
WIN_CMD_SCRIPT:format "..\\packages\\dummy\\nested\\path\\my-executable"
)
end)

it("should symlink share files", function()
Expand Down Expand Up @@ -142,13 +140,10 @@ describe("linker", function()

assert.spy(fs.async.write_file).was_called(0)
assert.spy(fs.async.symlink).was_called(2)
assert.spy(fs.async.symlink).was_called_with("../packages/dummy/share-file", ctx.location:share "share-file")
assert
.spy(fs.async.symlink)
.was_called_with(path.concat { dummy:get_install_path(), "share-file" }, ctx.location:share "share-file")
assert.spy(fs.async.symlink).was_called_with(
path.concat { dummy:get_install_path(), "nested", "path", "to", "share-file" },
ctx.location:share "nested/path/share-file"
)
.was_called_with("../../../packages/dummy/nested/path/to/share-file", ctx.location:share "nested/path/share-file")

assert.spy(fs.async.mkdirp).was_called(2)
assert.spy(fs.async.mkdirp).was_called_with(ctx.location:share "nested/path")
Expand Down

0 comments on commit 760af96

Please sign in to comment.