aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Boman <william@redwill.se>2023-10-13 17:05:12 +0200
committerWilliam Boman <william@redwill.se>2025-02-19 09:23:19 +0100
commit80944cbf22e10a4debe59d2f0166fb0cd7b1b1aa (patch)
tree9abe9afe34923fce89d6b9b90a1b41445a4d1cd4
parentfeat(path): add relative(from, to) (diff)
downloadmason-80944cbf22e10a4debe59d2f0166fb0cd7b1b1aa.tar
mason-80944cbf22e10a4debe59d2f0166fb0cd7b1b1aa.tar.gz
mason-80944cbf22e10a4debe59d2f0166fb0cd7b1b1aa.tar.bz2
mason-80944cbf22e10a4debe59d2f0166fb0cd7b1b1aa.tar.lz
mason-80944cbf22e10a4debe59d2f0166fb0cd7b1b1aa.tar.xz
mason-80944cbf22e10a4debe59d2f0166fb0cd7b1b1aa.tar.zst
mason-80944cbf22e10a4debe59d2f0166fb0cd7b1b1aa.zip
feat(linker): use relative targets for symlinks (#1525)
Closes #1156.
-rw-r--r--lua/mason-core/installer/linker.lua16
-rw-r--r--lua/mason-core/path.lua19
-rw-r--r--tests/mason-core/installer/linker_spec.lua33
-rw-r--r--tests/mason-core/path_spec.lua22
4 files changed, 31 insertions, 59 deletions
diff --git a/lua/mason-core/installer/linker.lua b/lua/mason-core/installer/linker.lua
index 5ab6044a..a5c54273 100644
--- a/lua/mason-core/installer/linker.lua
+++ b/lua/mason-core/installer/linker.lua
@@ -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)
@@ -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
@@ -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)
@@ -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
@@ -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,
@@ -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
diff --git a/lua/mason-core/path.lua b/lua/mason-core/path.lua
index 66f0f964..eec3148d 100644
--- a/lua/mason-core/path.lua
+++ b/lua/mason-core/path.lua
@@ -1,24 +1,9 @@
-local sep = (function()
- ---@diagnostic disable-next-line: undefined-global
- if jit then
- ---@diagnostic disable-next-line: undefined-global
- local os = string.lower(jit.os)
- if os == "linux" or os == "osx" or os == "bsd" then
- return "/"
- else
- return "\\"
- end
- else
- return string.sub(package.config, 1, 1)
- end
-end)()
-
local M = {}
---@param path_components string[]
---@return string
function M.concat(path_components)
- return table.concat(path_components, sep)
+ return vim.fs.normalize(table.concat(path_components, "/"))
end
---@path root_path string
@@ -55,7 +40,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
diff --git a/tests/mason-core/installer/linker_spec.lua b/tests/mason-core/installer/linker_spec.lua
index eb5ce394..9d3afeac 100644
--- a/tests/mason-core/installer/linker_spec.lua
+++ b/tests/mason-core/installer/linker_spec.lua
@@ -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
@@ -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()
@@ -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()
@@ -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")
diff --git a/tests/mason-core/path_spec.lua b/tests/mason-core/path_spec.lua
index 4aeb48f1..905df6ab 100644
--- a/tests/mason-core/path_spec.lua
+++ b/tests/mason-core/path_spec.lua
@@ -2,18 +2,8 @@ local path = require "mason-core.path"
describe("path", function()
it("concatenates paths", function()
- assert.equals("foo/bar/baz/~", path.concat { "foo", "bar", "baz", "~" })
- end)
-
- it("concatenates paths on Windows", function()
- local old_os = jit.os
- -- selene: allow(incorrect_standard_library_use)
- jit.os = "windows"
- package.loaded["mason-core.path"] = nil
- local path = require "mason-core.path"
- assert.equals([[foo\bar\baz\~]], path.concat { "foo", "bar", "baz", "~" })
- -- selene: allow(incorrect_standard_library_use)
- jit.os = old_os
+ assert.equals("foo/bar/baz", path.concat { "foo", "bar", "baz" })
+ assert.equals("foo/bar/baz", path.concat { "foo/", "bar/", "baz/" })
end)
it("identifies subdirectories", function()
@@ -28,7 +18,7 @@ describe("path", function()
{
from = "/home/user/dir1/fileA",
to = "/home/user/dir1/fileB",
- expected = "./fileB",
+ expected = "fileB",
},
{
from = "/home/user/dir1/fileA",
@@ -43,7 +33,7 @@ describe("path", function()
{
from = "/home/user/dir1/subdir/fileD",
to = "/home/user/dir1/subdir/fileF",
- expected = "./fileF",
+ expected = "fileF",
},
{
from = "/home/user/dir1/fileG",
@@ -58,12 +48,12 @@ describe("path", function()
{
from = "/fileK",
to = "/home/fileL",
- expected = "./home/fileL",
+ expected = "home/fileL",
},
{
from = "/home/user/fileM",
to = "/home/user/dir1/dir2/fileL",
- expected = "./dir1/dir2/fileL",
+ expected = "dir1/dir2/fileL",
},
}