aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alex Lam S.L <alexlamsl@gmail.com> 2023-08-07 03:42:08 +0300
committerGravatar GitHub <noreply@github.com> 2023-08-06 17:42:08 -0700
commitb93f304c063698ada698eddc4321c5c7010e5e5d (patch)
tree3cf55bba48ba549cc1283cc1d48b02b8cb73dc36
parenta9b3d58353061212b7fddfd1ec13dd9f7a414f11 (diff)
downloadbun-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.zig24
-rw-r--r--test/cli/install/bun-add.test.ts66
-rw-r--r--test/cli/install/bun-remove.test.ts30
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",
+ });
+});