aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/install/bin.zig31
-rw-r--r--src/install/install.zig4
-rw-r--r--test/bun.js/install/bun-install.test.ts2
3 files changed, 21 insertions, 16 deletions
diff --git a/src/install/bin.zig b/src/install/bin.zig
index 2d1113556..dfd29c927 100644
--- a/src/install/bin.zig
+++ b/src/install/bin.zig
@@ -257,7 +257,6 @@ pub const Bin = extern struct {
pub const Linker = struct {
bin: Bin,
- package_installed_path: stringZ = "",
package_installed_node_modules: std.os.fd_t = std.math.maxInt(std.os.fd_t),
root_node_modules_folder: std.os.fd_t = std.math.maxInt(std.os.fd_t),
@@ -309,6 +308,8 @@ pub const Bin = extern struct {
setPermissions(this.root_node_modules_folder, dest_path);
}
+ const dot_bin = ".bin" ++ std.fs.path.sep_str;
+
// It is important that we use symlinkat(2) with relative paths instead of symlink()
// That way, if you move your node_modules folder around, the symlinks in .bin still work
// If we used absolute paths for the symlinks, you'd end up with broken symlinks
@@ -319,14 +320,22 @@ pub const Bin = extern struct {
var remain: []u8 = &dest_buf;
if (!link_global) {
- target_buf[0..".bin/".len].* = ".bin/".*;
- from_remain = target_buf[".bin/".len..];
- dest_buf[0.."..".len].* = "..".*;
- remain = dest_buf["..".len..];
- std.mem.copy(u8, remain, this.package_installed_path);
- remain = remain[this.package_installed_path.len..];
+ const root_dir = std.fs.Dir{ .fd = this.root_node_modules_folder };
+ const from = root_dir.realpath(dot_bin, &target_buf) catch |err| {
+ this.err = err;
+ return;
+ };
+ const to = bun.getFdPath(this.package_installed_node_modules, &dest_buf) catch |err| {
+ this.err = err;
+ return;
+ };
+ const rel = Path.relative(from, to);
+ std.mem.copy(u8, remain, rel);
+ remain = remain[rel.len..];
remain[0] = std.fs.path.sep;
remain = remain[1..];
+ from_remain[0..dot_bin.len].* = dot_bin.*;
+ from_remain = from_remain[dot_bin.len..];
} else {
if (this.global_bin_dir.fd >= std.math.maxInt(std.os.fd_t)) {
this.err = error.MissingGlobalBinDir;
@@ -480,7 +489,7 @@ pub const Bin = extern struct {
target_buf_remain[0] = 0;
var from_path: [:0]u8 = target_buf[0 .. @ptrToInt(target_buf_remain.ptr) - @ptrToInt(&target_buf) :0];
var to_path = if (!link_global)
- std.fmt.bufPrintZ(&dest_buf, ".bin/{s}", .{entry.name}) catch continue
+ std.fmt.bufPrintZ(&dest_buf, dot_bin ++ "{s}", .{entry.name}) catch continue
else
std.fmt.bufPrintZ(&dest_buf, "{s}", .{entry.name}) catch continue;
@@ -500,8 +509,8 @@ pub const Bin = extern struct {
var remain: []u8 = &dest_buf;
if (!link_global) {
- target_buf[0..".bin/".len].* = ".bin/".*;
- from_remain = target_buf[".bin/".len..];
+ target_buf[0..dot_bin.len].* = dot_bin.*;
+ from_remain = target_buf[dot_bin.len..];
dest_buf[0.."../".len].* = "../".*;
remain = dest_buf["../".len..];
} else {
@@ -631,7 +640,7 @@ pub const Bin = extern struct {
target_buf_remain = target_buf_remain[entry.name.len..];
target_buf_remain[0] = 0;
var to_path = if (!link_global)
- std.fmt.bufPrintZ(&dest_buf, ".bin/{s}", .{entry.name}) catch continue
+ std.fmt.bufPrintZ(&dest_buf, dot_bin ++ "{s}", .{entry.name}) catch continue
else
std.fmt.bufPrintZ(&dest_buf, "{s}", .{entry.name}) catch continue;
diff --git a/src/install/install.zig b/src/install/install.zig
index ee46ad079..7bc79b015 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -5708,7 +5708,6 @@ pub const PackageManager = struct {
manager: *PackageManager,
lockfile: *Lockfile,
progress: *std.Progress,
- node_modules_path: stringZ,
node_modules_folder: std.fs.IterableDir,
skip_verify_installed_version_number: bool,
skip_delete: bool,
@@ -5928,7 +5927,6 @@ pub const PackageManager = struct {
var bin_linker = Bin.Linker{
.bin = bin,
- .package_installed_path = this.node_modules_path["node_modules".len..],
.package_installed_node_modules = this.node_modules_folder.dir.fd,
.global_bin_path = this.options.bin_path,
.global_bin_dir = this.options.global_bin_dir.dir,
@@ -6186,7 +6184,6 @@ pub const PackageManager = struct {
.resolutions = resolutions,
.lockfile = lockfile,
.node = &install_node,
- .node_modules_path = "node_modules",
.node_modules_folder = node_modules_folder,
.progress = progress,
.skip_verify_installed_version_number = skip_verify_installed_version_number,
@@ -6208,7 +6205,6 @@ pub const PackageManager = struct {
// We deliberately do not close this folder.
// If the package hasn't been downloaded, we will need to install it later
// We use this file descriptor to know where to put it.
- installer.node_modules_path = node_modules.relative_path;
installer.node_modules_folder = try cwd.openIterableDir(node_modules.relative_path, .{});
var remaining = node_modules.dependencies;
diff --git a/test/bun.js/install/bun-install.test.ts b/test/bun.js/install/bun-install.test.ts
index a47bbd2ce..7de46869f 100644
--- a/test/bun.js/install/bun-install.test.ts
+++ b/test/bun.js/install/bun-install.test.ts
@@ -1764,7 +1764,7 @@ it("should consider peerDependencies during hoisting", async () => {
expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual(["baz-exec", "baz-run"]);
expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-exec"))).toBe(join("..", "baz", "index.js"));
expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(
- join("..", "bar", "node_modules", "baz", "index.js"),
+ join("..", "..", "bar", "node_modules", "baz", "index.js"),
);
expect(await readlink(join(package_dir, "node_modules", "bar"))).toBe(join("..", "bar"));
expect(await readdirSorted(join(package_dir, "bar"))).toEqual(["node_modules", "package.json"]);