Skip to content

Commit

Permalink
fix: #7932 (#8038)
Browse files Browse the repository at this point in the history
* updating package with child peerDependency doesn't keep old version

* [autofix.ci] apply automated fixes

* fixed TODO test

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
eriklangille and autofix-ci[bot] committed Jan 12, 2024
1 parent 4611b84 commit 1526366
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 56 deletions.
2 changes: 1 addition & 1 deletion src/install/lockfile.zig
Expand Up @@ -543,7 +543,7 @@ pub const Tree = struct {
for (this_dependencies) |dep_id| {
const dep = builder.dependencies[dep_id];
if (dep.name_hash != dependency.name_hash) continue;
if (builder.resolutions[dep_id] != package_id) {
if (builder.resolutions[dep_id] != package_id and !dependency.behavior.isPeer()) {
if (as_defined and !dep.behavior.isPeer()) {
builder.maybeReportError("Package \"{}@{}\" has a dependency loop\n Resolution: \"{}@{}\"\n Dependency: \"{}@{}\"", .{
builder.packageName(package_id),
Expand Down
188 changes: 133 additions & 55 deletions test/cli/install/registry/bun-install-registry.test.ts
Expand Up @@ -180,6 +180,87 @@ test("dependency from root satisfies range from dependency", async () => {
expect(await exited).toBe(0);
});

test("peerDependency in child npm dependency should not maintain old version when package is upgraded", async () => {
await writeFile(
join(packageDir, "package.json"),
JSON.stringify({
name: "foo",
version: "1.0.0",
dependencies: {
"peer-deps-fixed": "1.0.0",
"no-deps": "1.0.0",
},
}),
);

var { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install"],
cwd: packageDir,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});

expect(stderr).toBeDefined();
var err = await new Response(stderr).text();
expect(stdout).toBeDefined();
var out = await new Response(stdout).text();
expect(err).toContain("Saved lockfile");
expect(err).not.toContain("not found");
expect(err).not.toContain("error:");
expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
"",
" + no-deps@1.0.0",
" + peer-deps-fixed@1.0.0",
"",
" 2 packages installed",
]);
expect(await file(join(packageDir, "node_modules", "no-deps", "package.json")).json()).toEqual({
name: "no-deps",
version: "1.0.0",
} as any);
expect(await exited).toBe(0);

await writeFile(
join(packageDir, "package.json"),
JSON.stringify({
name: "foo",
version: "1.0.0",
dependencies: {
"peer-deps-fixed": "1.0.0",
"no-deps": "1.0.1", // upgrade the package
},
}),
);

({ stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install"],
cwd: packageDir,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
}));

err = await new Response(stderr).text();
out = await new Response(stdout).text();
expect(err).not.toContain("not found");
expect(err).not.toContain("error:");
expect(await file(join(packageDir, "node_modules", "no-deps", "package.json")).json()).toEqual({
name: "no-deps",
version: "1.0.1",
} as any);
expect(await exists(join(packageDir, "node_modules", "peer-deps-fixed", "node_modules"))).toBeFalse();
expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
"",
" + no-deps@1.0.1",
"",
" 1 package installed",
]);
expect(await exited).toBe(0);
});

test("package added after install", async () => {
await writeFile(
join(packageDir, "package.json"),
Expand Down Expand Up @@ -3997,48 +4078,46 @@ describe("yarn tests", () => {
expect(await exited).toBe(0);
});

test.todo(
"it should install in such a way that two identical packages with different peer dependencies are different instances",
async () => {
await writeFile(
join(packageDir, "package.json"),
JSON.stringify({
name: "foo",
version: "1.0.0",
dependencies: {
"provides-peer-deps-1-0-0": "1.0.0",
"provides-peer-deps-2-0-0": "1.0.0",
},
}),
);
test("it should install in such a way that two identical packages with different peer dependencies are different instances", async () => {
await writeFile(
join(packageDir, "package.json"),
JSON.stringify({
name: "foo",
version: "1.0.0",
dependencies: {
"provides-peer-deps-1-0-0": "1.0.0",
"provides-peer-deps-2-0-0": "1.0.0",
},
}),
);

var { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install"],
cwd: packageDir,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});
var { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install"],
cwd: packageDir,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});

var err = await new Response(stderr).text();
var out = await new Response(stdout).text();
expect(err).toContain("Saved lockfile");
expect(err).not.toContain("error:");
expect(err).not.toContain("not found");
expect(err).not.toContain("incorrect peer dependency");
expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
"",
" + provides-peer-deps-1-0-0@1.0.0",
" + provides-peer-deps-2-0-0@1.0.0",
"",
" 5 packages installed",
]);
expect(await exited).toBe(0);
var err = await new Response(stderr).text();
var out = await new Response(stdout).text();
expect(err).toContain("Saved lockfile");
expect(err).not.toContain("error:");
expect(err).not.toContain("not found");
expect(err).not.toContain("incorrect peer dependency");
expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
"",
" + provides-peer-deps-1-0-0@1.0.0",
" + provides-peer-deps-2-0-0@1.0.0",
"",
" 5 packages installed",
]);
expect(await exited).toBe(0);

await writeFile(
join(packageDir, "test.js"),
`console.log(
await writeFile(
join(packageDir, "test.js"),
`console.log(
require("provides-peer-deps-1-0-0").dependencies["peer-deps"] ===
require("provides-peer-deps-2-0-0").dependencies["peer-deps"]
);
Expand Down Expand Up @@ -4086,24 +4165,23 @@ describe("yarn tests", () => {
},
})
);`,
);
);

({ stdout, stderr, exited } = spawn({
cmd: [bunExe(), "test.js"],
cwd: packageDir,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
}));
({ stdout, stderr, exited } = spawn({
cmd: [bunExe(), "test.js"],
cwd: packageDir,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
}));

err = await new Response(stderr).text();
out = await new Response(stdout).text();
expect(out).toBe("true\ntrue\ntrue");
expect(err).toBeEmpty();
expect(await exited).toBe(0);
},
);
err = await new Response(stderr).text();
out = await new Response(stdout).text();
expect(out).toBe("true\ntrue\nfalse\n");
expect(err).toBeEmpty();
expect(await exited).toBe(0);
});

test("it should install in such a way that two identical packages with the same peer dependencies are the same instances (simple)", async () => {
await writeFile(
Expand Down

0 comments on commit 1526366

Please sign in to comment.