Files
bun.sh/test/cli/install/bun-update-security-provider.test.ts
Dylan Conway 0601eb0007 Make --linker=isolated the default for bun install (#23311)
### 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>
2025-10-08 18:00:38 -07:00

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);
});