mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 10:58:56 +00:00
### What does this PR do? Makes isolated installs the default install strategy for projects with workspaces in Bun v1.3. Also fixes creating patches with `bun patch` and `--linker isolated` Fixes #22693 ### How did you verify your code works? Added tests for node_modules renaming `bun patch` with isolated install. --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude <noreply@anthropic.com>
153 lines
3.3 KiB
TypeScript
153 lines
3.3 KiB
TypeScript
import { afterAll, afterEach, beforeAll, beforeEach, expect, test } from "bun:test";
|
|
import { bunEnv, bunExe } from "harness";
|
|
import {
|
|
dummyAfterAll,
|
|
dummyAfterEach,
|
|
dummyBeforeAll,
|
|
dummyBeforeEach,
|
|
dummyRegistry,
|
|
package_dir,
|
|
setHandler,
|
|
write,
|
|
} from "./dummy.registry.js";
|
|
|
|
beforeAll(dummyBeforeAll);
|
|
afterAll(dummyAfterAll);
|
|
beforeEach(async () => {
|
|
await dummyBeforeEach();
|
|
});
|
|
afterEach(dummyAfterEach);
|
|
|
|
test("security scanner blocks bun update on fatal advisory", async () => {
|
|
const urls: string[] = [];
|
|
setHandler(
|
|
dummyRegistry(urls, {
|
|
"0.1.0": {},
|
|
"0.2.0": {},
|
|
}),
|
|
);
|
|
|
|
const scannerCode = `
|
|
export const scanner = {
|
|
version: "1",
|
|
scan: async ({ packages }) => {
|
|
if (packages.length === 0) return [];
|
|
return [
|
|
{
|
|
package: "moo",
|
|
description: "Fatal security issue detected",
|
|
level: "fatal",
|
|
url: "https://example.com/critical",
|
|
},
|
|
];
|
|
},
|
|
};
|
|
`;
|
|
|
|
await write("./scanner.ts", scannerCode);
|
|
await write("package.json", {
|
|
name: "my-app",
|
|
version: "1.0.0",
|
|
dependencies: {
|
|
moo: "0.1.0",
|
|
},
|
|
});
|
|
|
|
// First install without security scanning (to have something to update)
|
|
await using installProc = Bun.spawn({
|
|
cmd: [bunExe(), "install", "--no-summary"],
|
|
env: bunEnv,
|
|
cwd: package_dir,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
await installProc.stdout.text();
|
|
await installProc.stderr.text();
|
|
await installProc.exited;
|
|
|
|
await write(
|
|
"./bunfig.toml",
|
|
`
|
|
[install]
|
|
saveTextLockfile = false
|
|
|
|
[install.security]
|
|
scanner = "./scanner.ts"
|
|
`,
|
|
);
|
|
|
|
await using updateProc = Bun.spawn({
|
|
cmd: [bunExe(), "update", "moo"],
|
|
env: bunEnv,
|
|
cwd: package_dir,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [updateOut, updateErr, updateExitCode] = await Promise.all([
|
|
updateProc.stdout.text(),
|
|
updateProc.stderr.text(),
|
|
updateProc.exited,
|
|
]);
|
|
|
|
expect(updateOut).toContain("FATAL: moo");
|
|
expect(updateOut).toContain("Fatal security issue detected");
|
|
expect(updateOut).toContain("Installation aborted due to fatal security advisories");
|
|
|
|
expect(updateExitCode).toBe(1);
|
|
});
|
|
|
|
test("security scanner does not run on bun update when disabled", async () => {
|
|
const urls: string[] = [];
|
|
setHandler(
|
|
dummyRegistry(urls, {
|
|
"0.1.0": {},
|
|
"0.2.0": {},
|
|
}),
|
|
);
|
|
|
|
await write("package.json", {
|
|
name: "my-app",
|
|
version: "1.0.0",
|
|
dependencies: {
|
|
moo: "0.1.0",
|
|
},
|
|
});
|
|
|
|
// Remove bunfig.toml to ensure no security scanner
|
|
await write("bunfig.toml", "");
|
|
|
|
await using installProc = Bun.spawn({
|
|
cmd: [bunExe(), "install", "--no-summary"],
|
|
env: bunEnv,
|
|
cwd: package_dir,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
await installProc.stdout.text();
|
|
await installProc.stderr.text();
|
|
await installProc.exited;
|
|
|
|
await using updateProc = Bun.spawn({
|
|
cmd: [bunExe(), "update", "moo"],
|
|
env: bunEnv,
|
|
cwd: package_dir,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [updateOut, updateErr, updateExitCode] = await Promise.all([
|
|
updateProc.stdout.text(),
|
|
updateProc.stderr.text(),
|
|
updateProc.exited,
|
|
]);
|
|
|
|
expect(updateOut).not.toContain("Security scanner");
|
|
expect(updateOut).not.toContain("WARN:");
|
|
expect(updateOut).not.toContain("FATAL:");
|
|
|
|
expect(updateExitCode).toBe(0);
|
|
});
|