diff --git a/src/install/install.zig b/src/install/install.zig index d5c6d29bf6..3ee5fdb62f 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -1366,7 +1366,7 @@ pub const PackageInstall = struct { cached_package_dir, this.allocator, &[_]bun.OSPathSlice{}, - &[_]bun.OSPathSlice{bun.OSPathLiteral("node_modules")}, + &[_]bun.OSPathSlice{}, ) catch |err| return Result{ .fail = .{ .err = err, .step = .opening_cache_dir }, }; diff --git a/test/cli/install/vendor-baz-0.0.1.tgz b/test/cli/install/vendor-baz-0.0.1.tgz new file mode 100644 index 0000000000..22ae0e3e8c Binary files /dev/null and b/test/cli/install/vendor-baz-0.0.1.tgz differ diff --git a/test/regression/issue/08093.test.ts b/test/regression/issue/08093.test.ts new file mode 100644 index 0000000000..3a98f8e066 --- /dev/null +++ b/test/regression/issue/08093.test.ts @@ -0,0 +1,80 @@ +import { file, spawn } from "bun"; +import { afterAll, afterEach, beforeAll, beforeEach, expect, it } from "bun:test"; +import { bunExe, bunEnv as env } from "harness"; +import { access, writeFile } from "fs/promises"; +import { join } from "path"; +import { + dummyAfterAll, + dummyAfterEach, + dummyBeforeAll, + dummyBeforeEach, + dummyRegistry, + package_dir, + readdirSorted, + requested, + root_url, + setHandler, +} from "./../../cli/install/dummy.registry.js"; + +beforeAll(dummyBeforeAll); +afterAll(dummyAfterAll); +beforeEach(dummyBeforeEach); +afterEach(dummyAfterEach); + +it("should install vendored node_modules with hardlink", async () => { + const urls: string[] = []; + setHandler( + dummyRegistry(urls, { + "0.0.1": {}, + latest: "0.0.1", + }), + ); + await writeFile( + join(package_dir, "package.json"), + JSON.stringify({ + name: "foo", + version: "0.0.1", + dependencies: { + "vendor-baz": "0.0.1", + }, + }), + ); + const { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "install", "--backend", "hardlink"], + cwd: package_dir, + stdout: null, + stdin: "pipe", + stderr: "pipe", + env, + }); + + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err).toContain("Saved lockfile"); + expect(stdout).toBeDefined(); + const out = await new Response(stdout).text(); + expect(out).toContain("1 package installed"); + + expect(await exited).toBe(0); + expect(urls.sort()).toEqual([`${root_url}/vendor-baz`, `${root_url}/vendor-baz-0.0.1.tgz`]); + expect(requested).toBe(2); + + expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".cache", "vendor-baz"]); + expect(await readdirSorted(join(package_dir, "node_modules", "vendor-baz"))).toEqual([ + "cjs", + "index.js", + "package.json", + ]); + expect(await readdirSorted(join(package_dir, "node_modules", "vendor-baz", "cjs", "node_modules"))).toEqual([ + "foo-dep", + ]); + expect( + await readdirSorted(join(package_dir, "node_modules", "vendor-baz", "cjs", "node_modules", "foo-dep")), + ).toEqual(["index.js"]); + + expect(await file(join(package_dir, "node_modules", "vendor-baz", "package.json")).json()).toEqual({ + name: "vendor-baz", + version: "0.0.1", + }); + await access(join(package_dir, "bun.lockb")); +});