diff options
author | 2023-08-07 03:42:08 +0300 | |
---|---|---|
committer | 2023-08-06 17:42:08 -0700 | |
commit | b93f304c063698ada698eddc4321c5c7010e5e5d (patch) | |
tree | 3cf55bba48ba549cc1283cc1d48b02b8cb73dc36 | |
parent | a9b3d58353061212b7fddfd1ec13dd9f7a414f11 (diff) | |
download | bun-b93f304c063698ada698eddc4321c5c7010e5e5d.tar.gz bun-b93f304c063698ada698eddc4321c5c7010e5e5d.tar.zst bun-b93f304c063698ada698eddc4321c5c7010e5e5d.zip |
[install] handle `bun add` of existing `peerDependencies` correctly (#4028)
-rw-r--r-- | src/install/install.zig | 24 | ||||
-rw-r--r-- | test/cli/install/bun-add.test.ts | 66 | ||||
-rw-r--r-- | test/cli/install/bun-remove.test.ts | 30 |
3 files changed, 98 insertions, 22 deletions
diff --git a/src/install/install.zig b/src/install/install.zig index 13338c53b..5e1b54aa6 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -4881,7 +4881,7 @@ pub const PackageManager = struct { ast_modifier: { // Try to use the existing spot in the dependencies list if possible for (updates) |*update| { - for (dependency_lists_to_check) |list| { + inline for ([_]string{ "dependencies", "devDependencies", "optionalDependencies" }) |list| { if (current_package_json.asProperty(list)) |query| { if (query.expr.data == .e_object) { if (query.expr.asProperty( @@ -6111,13 +6111,6 @@ pub const PackageManager = struct { } } - const dependency_lists_to_check = [_]string{ - "dependencies", - "devDependencies", - "optionalDependencies", - "peerDependencies", - }; - fn updatePackageJSONAndInstallWithManager( ctx: Command.Context, manager: *PackageManager, @@ -6299,21 +6292,20 @@ pub const PackageManager = struct { } } + const dependency_list = if (manager.options.update.development) + "devDependencies" + else if (manager.options.update.optional) + "optionalDependencies" + else + "dependencies"; var any_changes = false; - var dependency_list: string = "dependencies"; - if (manager.options.update.development) { - dependency_list = "devDependencies"; - } else if (manager.options.update.optional) { - dependency_list = "optionalDependencies"; - } - switch (op) { .remove => { // if we're removing, they don't have to specify where it is installed in the dependencies list // they can even put it multiple times and we will just remove all of them for (updates) |update| { - inline for (dependency_lists_to_check) |list| { + inline for ([_]string{ "dependencies", "devDependencies", "optionalDependencies", "peerDependencies" }) |list| { if (current_package_json.asProperty(list)) |query| { if (query.expr.data == .e_object) { var dependencies = query.expr.data.e_object.properties.slice(); diff --git a/test/cli/install/bun-add.test.ts b/test/cli/install/bun-add.test.ts index 9dd38c8cd..589b7a87e 100644 --- a/test/cli/install/bun-add.test.ts +++ b/test/cli/install/bun-add.test.ts @@ -459,7 +459,7 @@ it("should add dependency (GitHub)", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls.sort()).toEqual([]); + expect(urls.sort()).toBeEmpty(); expect(requested).toBe(0); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".bin", ".cache", "uglify-js"]); expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual(["uglifyjs"]); @@ -680,7 +680,7 @@ it("should add aliased dependency (GitHub)", async () => { " 1 packages installed", ]); expect(await exited).toBe(0); - expect(urls.sort()).toEqual([]); + expect(urls.sort()).toBeEmpty(); expect(requested).toBe(0); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".bin", ".cache", "uglify"]); expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual(["uglifyjs"]); @@ -993,7 +993,7 @@ it("should handle Git URL in dependencies (SCP-style)", async () => { " 1 packages installed", ]); expect(await exited1).toBe(0); - expect(urls.sort()).toEqual([]); + expect(urls.sort()).toBeEmpty(); expect(requested).toBe(0); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".bin", ".cache", "uglify-js"]); expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual(["uglifyjs"]); @@ -1053,7 +1053,7 @@ it("should handle Git URL in dependencies (SCP-style)", async () => { "Checked 1 installs across 2 packages (no changes)", ]); expect(await exited2).toBe(0); - expect(urls.sort()).toEqual([]); + expect(urls.sort()).toBeEmpty(); expect(requested).toBe(0); }, 20000); @@ -1255,7 +1255,7 @@ it("should add dependency without duplication", async () => { const out2 = await new Response(stdout2).text(); expect(out2.replace(/\s*\[[0-9\.]+m?s\] done\s*$/, "").split(/\r?\n/)).toEqual(["", " installed bar@0.0.2"]); expect(await exited2).toBe(0); - expect(urls.sort()).toEqual([]); + expect(urls.sort()).toBeEmpty(); expect(requested).toBe(2); expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".cache", "bar"]); expect(await readdirSorted(join(package_dir, "node_modules", "bar"))).toEqual(["package.json"]); @@ -1480,7 +1480,7 @@ it("should redirect 'install X --save' to 'add'", async () => { await installRedirectsToAdd(false); }); -async function installRedirectsToAdd(saveFlagFirst) { +async function installRedirectsToAdd(saveFlagFirst: boolean) { await writeFile( join(add_dir, "package.json"), JSON.stringify({ @@ -1516,3 +1516,57 @@ async function installRedirectsToAdd(saveFlagFirst) { expect(await exited).toBe(0); expect((await file(join(package_dir, "package.json")).text()).includes("bun-add.test")); } + +it("should add dependency alongside peerDependencies", async () => { + const urls: string[] = []; + setHandler(dummyRegistry(urls)); + await writeFile( + join(package_dir, "package.json"), + JSON.stringify({ + name: "foo", + peerDependencies: { + bar: "~0.0.1", + }, + }), + ); + const { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "add", "bar"], + cwd: package_dir, + stdout: null, + stdin: "pipe", + stderr: "pipe", + env, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err).not.toContain("error:"); + expect(err).toContain("Saved lockfile"); + expect(stdout).toBeDefined(); + const out = await new Response(stdout).text(); + expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([ + "", + " installed bar@0.0.2", + "", + "", + " 1 packages installed", + ]); + expect(await exited).toBe(0); + expect(urls.sort()).toEqual([`${root_url}/bar`, `${root_url}/bar-0.0.2.tgz`]); + expect(requested).toBe(2); + expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".cache", "bar"]); + expect(await readdirSorted(join(package_dir, "node_modules", "bar"))).toEqual(["package.json"]); + expect(await file(join(package_dir, "node_modules", "bar", "package.json")).json()).toEqual({ + name: "bar", + version: "0.0.2", + }); + expect(await file(join(package_dir, "package.json")).json()).toEqual({ + name: "foo", + dependencies: { + bar: "^0.0.2", + }, + peerDependencies: { + bar: "~0.0.1", + }, + }); + await access(join(package_dir, "bun.lockb")); +}); diff --git a/test/cli/install/bun-remove.test.ts b/test/cli/install/bun-remove.test.ts index bdf0873e9..5b029f143 100644 --- a/test/cli/install/bun-remove.test.ts +++ b/test/cli/install/bun-remove.test.ts @@ -287,3 +287,33 @@ it("should retain a new line in the end of package.json", async () => { ) + "\n", ); }); + +it("should remove peerDependencies", async () => { + await writeFile( + join(package_dir, "package.json"), + JSON.stringify({ + name: "foo", + peerDependencies: { + bar: "~0.0.1", + }, + }), + ); + const { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "remove", "bar"], + cwd: package_dir, + stdout: null, + stdin: "pipe", + stderr: "pipe", + env, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err).not.toContain("error:"); + expect(stdout).toBeDefined(); + const out = await new Response(stdout).text(); + expect(out.replace(/\s*\[[0-9\.]+m?s\]/, "").split(/\r?\n/)).toEqual([" done", ""]); + expect(await exited).toBe(0); + expect(await file(join(package_dir, "package.json")).json()).toEqual({ + name: "foo", + }); +}); |