aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/install/dependency.zig2
-rw-r--r--src/install/resolution.zig12
-rw-r--r--test/bun.js/install/bun-install.test.ts374
3 files changed, 238 insertions, 150 deletions
diff --git a/src/install/dependency.zig b/src/install/dependency.zig
index b03d49e4a..af28c99ba 100644
--- a/src/install/dependency.zig
+++ b/src/install/dependency.zig
@@ -413,7 +413,7 @@ pub const Version = struct {
return .dist_tag;
},
- // link://
+ // link:
'l' => {
if (isTarball(dependency))
return .tarball;
diff --git a/src/install/resolution.zig b/src/install/resolution.zig
index 12fb53449..a6861b825 100644
--- a/src/install/resolution.zig
+++ b/src/install/resolution.zig
@@ -189,9 +189,9 @@ pub const Resolution = extern struct {
.remote_tarball => try writer.writeAll(formatter.resolution.value.remote_tarball.slice(formatter.buf)),
.github => try formatter.resolution.value.github.formatAs("github", formatter.buf, layout, opts, writer),
.gitlab => try formatter.resolution.value.gitlab.formatAs("gitlab", formatter.buf, layout, opts, writer),
- .workspace => try std.fmt.format(writer, "workspace://{s}", .{formatter.resolution.value.workspace.slice(formatter.buf)}),
- .symlink => try std.fmt.format(writer, "link://{s}", .{formatter.resolution.value.symlink.slice(formatter.buf)}),
- .single_file_module => try std.fmt.format(writer, "module://{s}", .{formatter.resolution.value.single_file_module.slice(formatter.buf)}),
+ .workspace => try std.fmt.format(writer, "workspace:{s}", .{formatter.resolution.value.workspace.slice(formatter.buf)}),
+ .symlink => try std.fmt.format(writer, "link:{s}", .{formatter.resolution.value.symlink.slice(formatter.buf)}),
+ .single_file_module => try std.fmt.format(writer, "module:{s}", .{formatter.resolution.value.single_file_module.slice(formatter.buf)}),
else => {},
}
}
@@ -211,9 +211,9 @@ pub const Resolution = extern struct {
.remote_tarball => try writer.writeAll(formatter.resolution.value.remote_tarball.slice(formatter.buf)),
.github => try formatter.resolution.value.github.formatAs("github", formatter.buf, layout, opts, writer),
.gitlab => try formatter.resolution.value.gitlab.formatAs("gitlab", formatter.buf, layout, opts, writer),
- .workspace => try std.fmt.format(writer, "workspace://{s}", .{formatter.resolution.value.workspace.slice(formatter.buf)}),
- .symlink => try std.fmt.format(writer, "link://{s}", .{formatter.resolution.value.symlink.slice(formatter.buf)}),
- .single_file_module => try std.fmt.format(writer, "module://{s}", .{formatter.resolution.value.single_file_module.slice(formatter.buf)}),
+ .workspace => try std.fmt.format(writer, "workspace:{s}", .{formatter.resolution.value.workspace.slice(formatter.buf)}),
+ .symlink => try std.fmt.format(writer, "link:{s}", .{formatter.resolution.value.symlink.slice(formatter.buf)}),
+ .single_file_module => try std.fmt.format(writer, "module:{s}", .{formatter.resolution.value.single_file_module.slice(formatter.buf)}),
else => {},
}
}
diff --git a/test/bun.js/install/bun-install.test.ts b/test/bun.js/install/bun-install.test.ts
index a9b62e9e4..b7413cde3 100644
--- a/test/bun.js/install/bun-install.test.ts
+++ b/test/bun.js/install/bun-install.test.ts
@@ -1,5 +1,12 @@
import { spawn } from "bun";
-import { afterAll, afterEach, beforeAll, beforeEach, expect, it } from "bun:test";
+import {
+ afterAll,
+ afterEach,
+ beforeAll,
+ beforeEach,
+ expect,
+ it,
+} from "bun:test";
import { bunExe } from "bunExe";
import { mkdir, mkdtemp, readdir, readlink, rm, writeFile } from "fs/promises";
import { join } from "path";
@@ -8,7 +15,7 @@ import { tmpdir } from "os";
let handler, package_dir, requested, server;
function resetHanlder() {
- handler = function() {
+ handler = function () {
return new Response("Tea Break~", { status: 418 });
};
}
@@ -37,16 +44,24 @@ afterEach(async () => {
it("should handle missing package", async () => {
const urls: string[] = [];
- handler = async(request) => {
+ handler = async (request) => {
expect(request.method).toBe("GET");
- expect(request.headers.get("accept")).toBe("application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*");
+ expect(request.headers.get("accept")).toBe(
+ "application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*",
+ );
expect(request.headers.get("npm-auth-type")).toBe(null);
expect(await request.text()).toBe("");
urls.push(request.url);
return new Response("bar", { status: 404 });
};
const { stdout, stderr, exited } = spawn({
- cmd: [bunExe(), "install", "foo", "--config", import.meta.dir + "/basic.toml"],
+ cmd: [
+ bunExe(),
+ "install",
+ "foo",
+ "--config",
+ import.meta.dir + "/basic.toml",
+ ],
cwd: package_dir,
stdout: null,
stdin: "pipe",
@@ -58,7 +73,9 @@ it("should handle missing package", async () => {
});
expect(stderr).toBeDefined();
const err = await new Response(stderr).text();
- expect(err.split(/\r?\n/)).toContain('error: package "foo" not found localhost/foo 404');
+ expect(err.split(/\r?\n/)).toContain(
+ 'error: package "foo" not found localhost/foo 404',
+ );
expect(stdout).toBeDefined();
expect(await new Response(stdout).text()).toBe("");
expect(urls).toContain("http://localhost:54321/foo");
@@ -70,9 +87,11 @@ it("should handle @scoped authentication", async () => {
let seen_token = false;
const url = "http://localhost:54321/@foo/bar";
const urls: string[] = [];
- handler = async(request) => {
+ handler = async (request) => {
expect(request.method).toBe("GET");
- expect(request.headers.get("accept")).toBe("application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*");
+ expect(request.headers.get("accept")).toBe(
+ "application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*",
+ );
if (request.url === url) {
expect(request.headers.get("authorization")).toBe("Bearer bar");
expect(request.headers.get("npm-auth-type")).toBe("legacy");
@@ -85,7 +104,13 @@ it("should handle @scoped authentication", async () => {
return new Response("Feeling lucky?", { status: 555 });
};
const { stdout, stderr, exited } = spawn({
- cmd: [bunExe(), "install", "@foo/bar", "--config", import.meta.dir + "/basic.toml"],
+ cmd: [
+ bunExe(),
+ "install",
+ "@foo/bar",
+ "--config",
+ import.meta.dir + "/basic.toml",
+ ],
cwd: package_dir,
stdout: null,
stdin: "pipe",
@@ -107,18 +132,22 @@ it("should handle @scoped authentication", async () => {
});
it("should handle workspaces", async () => {
- await writeFile(join(package_dir, "package.json"), JSON.stringify({
- name: "Foo",
- version: "0.0.1",
- workspaces: [
- "bar",
- ],
- }));
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "Foo",
+ version: "0.0.1",
+ workspaces: ["bar"],
+ }),
+ );
await mkdir(join(package_dir, "bar"));
- await writeFile(join(package_dir, "bar", "package.json"), JSON.stringify({
- name: "Bar",
- version: "0.0.2",
- }));
+ await writeFile(
+ join(package_dir, "bar", "package.json"),
+ JSON.stringify({
+ name: "Bar",
+ version: "0.0.2",
+ }),
+ );
const { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
cwd: package_dir,
@@ -136,41 +165,49 @@ it("should handle workspaces", async () => {
expect(stdout).toBeDefined();
const out = await new Response(stdout).text();
expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
- " + Bar@workspace://bar",
+ " + Bar@workspace:bar",
"",
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(requested).toBe(0);
expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Bar"]);
- expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar"));
+ expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(
+ join("..", "bar"),
+ );
});
it("should handle inter-dependency between workspaces", async () => {
- await writeFile(join(package_dir, "package.json"), JSON.stringify({
- name: "Foo",
- version: "0.0.1",
- workspaces: [
- "bar",
- "packages/baz",
- ],
- }));
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "Foo",
+ version: "0.0.1",
+ workspaces: ["bar", "packages/baz"],
+ }),
+ );
await mkdir(join(package_dir, "bar"));
- await writeFile(join(package_dir, "bar", "package.json"), JSON.stringify({
- name: "Bar",
- version: "0.0.2",
- dependencies: {
- "Baz": "0.0.3",
- },
- }));
+ await writeFile(
+ join(package_dir, "bar", "package.json"),
+ JSON.stringify({
+ name: "Bar",
+ version: "0.0.2",
+ dependencies: {
+ Baz: "0.0.3",
+ },
+ }),
+ );
await mkdir(join(package_dir, "packages", "baz"), { recursive: true });
- await writeFile(join(package_dir, "packages", "baz", "package.json"), JSON.stringify({
- name: "Baz",
- version: "0.0.3",
- dependencies: {
- "Bar": "0.0.2",
- },
- }));
+ await writeFile(
+ join(package_dir, "packages", "baz", "package.json"),
+ JSON.stringify({
+ name: "Baz",
+ version: "0.0.3",
+ dependencies: {
+ Bar: "0.0.2",
+ },
+ }),
+ );
const { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
cwd: package_dir,
@@ -188,43 +225,56 @@ it("should handle inter-dependency between workspaces", async () => {
expect(stdout).toBeDefined();
const out = await new Response(stdout).text();
expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
- " + Bar@workspace://bar",
- " + Baz@workspace://packages/baz",
+ " + Bar@workspace:bar",
+ " + Baz@workspace:packages/baz",
"",
" 2 packages installed",
]);
expect(await exited).toBe(0);
expect(requested).toBe(0);
- expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Bar", "Baz"]);
- expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar"));
- expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(join("..", "packages", "baz"));
+ expect(await readdir(join(package_dir, "node_modules"))).toEqual([
+ "Bar",
+ "Baz",
+ ]);
+ expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(
+ join("..", "bar"),
+ );
+ expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(
+ join("..", "packages", "baz"),
+ );
});
it("should handle inter-dependency between workspaces (devDependencies)", async () => {
- await writeFile(join(package_dir, "package.json"), JSON.stringify({
- name: "Foo",
- version: "0.0.1",
- workspaces: [
- "bar",
- "packages/baz",
- ],
- }));
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "Foo",
+ version: "0.0.1",
+ workspaces: ["bar", "packages/baz"],
+ }),
+ );
await mkdir(join(package_dir, "bar"));
- await writeFile(join(package_dir, "bar", "package.json"), JSON.stringify({
- name: "Bar",
- version: "0.0.2",
- devDependencies: {
- "Baz": "0.0.3",
- },
- }));
+ await writeFile(
+ join(package_dir, "bar", "package.json"),
+ JSON.stringify({
+ name: "Bar",
+ version: "0.0.2",
+ devDependencies: {
+ Baz: "0.0.3",
+ },
+ }),
+ );
await mkdir(join(package_dir, "packages", "baz"), { recursive: true });
- await writeFile(join(package_dir, "packages", "baz", "package.json"), JSON.stringify({
- name: "Baz",
- version: "0.0.3",
- devDependencies: {
- "Bar": "0.0.2",
- },
- }));
+ await writeFile(
+ join(package_dir, "packages", "baz", "package.json"),
+ JSON.stringify({
+ name: "Baz",
+ version: "0.0.3",
+ devDependencies: {
+ Bar: "0.0.2",
+ },
+ }),
+ );
const { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
cwd: package_dir,
@@ -242,43 +292,56 @@ it("should handle inter-dependency between workspaces (devDependencies)", async
expect(stdout).toBeDefined();
const out = await new Response(stdout).text();
expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
- " + Bar@workspace://bar",
- " + Baz@workspace://packages/baz",
+ " + Bar@workspace:bar",
+ " + Baz@workspace:packages/baz",
"",
" 2 packages installed",
]);
expect(await exited).toBe(0);
expect(requested).toBe(0);
- expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Bar", "Baz"]);
- expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar"));
- expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(join("..", "packages", "baz"));
+ expect(await readdir(join(package_dir, "node_modules"))).toEqual([
+ "Bar",
+ "Baz",
+ ]);
+ expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(
+ join("..", "bar"),
+ );
+ expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(
+ join("..", "packages", "baz"),
+ );
});
it("should handle inter-dependency between workspaces (optionalDependencies)", async () => {
- await writeFile(join(package_dir, "package.json"), JSON.stringify({
- name: "Foo",
- version: "0.0.1",
- workspaces: [
- "bar",
- "packages/baz",
- ],
- }));
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "Foo",
+ version: "0.0.1",
+ workspaces: ["bar", "packages/baz"],
+ }),
+ );
await mkdir(join(package_dir, "bar"));
- await writeFile(join(package_dir, "bar", "package.json"), JSON.stringify({
- name: "Bar",
- version: "0.0.2",
- optionalDependencies: {
- "Baz": "0.0.3",
- },
- }));
+ await writeFile(
+ join(package_dir, "bar", "package.json"),
+ JSON.stringify({
+ name: "Bar",
+ version: "0.0.2",
+ optionalDependencies: {
+ Baz: "0.0.3",
+ },
+ }),
+ );
await mkdir(join(package_dir, "packages", "baz"), { recursive: true });
- await writeFile(join(package_dir, "packages", "baz", "package.json"), JSON.stringify({
- name: "Baz",
- version: "0.0.3",
- optionalDependencies: {
- "Bar": "0.0.2",
- },
- }));
+ await writeFile(
+ join(package_dir, "packages", "baz", "package.json"),
+ JSON.stringify({
+ name: "Baz",
+ version: "0.0.3",
+ optionalDependencies: {
+ Bar: "0.0.2",
+ },
+ }),
+ );
const { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
cwd: package_dir,
@@ -296,37 +359,48 @@ it("should handle inter-dependency between workspaces (optionalDependencies)", a
expect(stdout).toBeDefined();
const out = await new Response(stdout).text();
expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
- " + Bar@workspace://bar",
- " + Baz@workspace://packages/baz",
+ " + Bar@workspace:bar",
+ " + Baz@workspace:packages/baz",
"",
" 2 packages installed",
]);
expect(await exited).toBe(0);
expect(requested).toBe(0);
- expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Bar", "Baz"]);
- expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar"));
- expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(join("..", "packages", "baz"));
+ expect(await readdir(join(package_dir, "node_modules"))).toEqual([
+ "Bar",
+ "Baz",
+ ]);
+ expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(
+ join("..", "bar"),
+ );
+ expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(
+ join("..", "packages", "baz"),
+ );
});
it("should ignore peerDependencies within workspaces", async () => {
- await writeFile(join(package_dir, "package.json"), JSON.stringify({
- name: "Foo",
- version: "0.0.1",
- workspaces: [
- "packages/baz",
- ],
- peerDependencies: {
- "Bar": ">=0.0.2",
- },
- }));
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "Foo",
+ version: "0.0.1",
+ workspaces: ["packages/baz"],
+ peerDependencies: {
+ Bar: ">=0.0.2",
+ },
+ }),
+ );
await mkdir(join(package_dir, "packages", "baz"), { recursive: true });
- await writeFile(join(package_dir, "packages", "baz", "package.json"), JSON.stringify({
- name: "Baz",
- version: "0.0.3",
- peerDependencies: {
- "Moo": ">=0.0.4",
- },
- }));
+ await writeFile(
+ join(package_dir, "packages", "baz", "package.json"),
+ JSON.stringify({
+ name: "Baz",
+ version: "0.0.3",
+ peerDependencies: {
+ Moo: ">=0.0.4",
+ },
+ }),
+ );
const { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
cwd: package_dir,
@@ -344,37 +418,49 @@ it("should ignore peerDependencies within workspaces", async () => {
expect(stdout).toBeDefined();
const out = await new Response(stdout).text();
expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
- " + Baz@workspace://packages/baz",
+ " + Baz@workspace:packages/baz",
"",
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(requested).toBe(0);
expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Baz"]);
- expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(join("..", "packages", "baz"));
+ expect(await readlink(join(package_dir, "node_modules", "Baz"))).toBe(
+ join("..", "packages", "baz"),
+ );
});
it("should handle life-cycle scripts within workspaces", async () => {
- await writeFile(join(package_dir, "package.json"), JSON.stringify({
- name: "Foo",
- version: "0.0.1",
- scripts: {
- install: [bunExe(), "index.js"].join(" "),
- },
- workspaces: [
- "bar",
- ],
- }));
- await writeFile(join(package_dir, "index.js"), 'console.log("[scripts:run] Foo");');
+ await writeFile(
+ join(package_dir, "package.json"),
+ JSON.stringify({
+ name: "Foo",
+ version: "0.0.1",
+ scripts: {
+ install: [bunExe(), "index.js"].join(" "),
+ },
+ workspaces: ["bar"],
+ }),
+ );
+ await writeFile(
+ join(package_dir, "index.js"),
+ 'console.log("[scripts:run] Foo");',
+ );
await mkdir(join(package_dir, "bar"));
- await writeFile(join(package_dir, "bar", "package.json"), JSON.stringify({
- name: "Bar",
- version: "0.0.2",
- scripts: {
- preinstall: [bunExe(), "index.js"].join(" "),
- },
- }));
- await writeFile(join(package_dir, "bar", "index.js"), 'console.log("[scripts:run] Bar");');
+ await writeFile(
+ join(package_dir, "bar", "package.json"),
+ JSON.stringify({
+ name: "Bar",
+ version: "0.0.2",
+ scripts: {
+ preinstall: [bunExe(), "index.js"].join(" "),
+ },
+ }),
+ );
+ await writeFile(
+ join(package_dir, "bar", "index.js"),
+ 'console.log("[scripts:run] Bar");',
+ );
const { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
cwd: package_dir,
@@ -393,7 +479,7 @@ it("should handle life-cycle scripts within workspaces", async () => {
const out = await new Response(stdout).text();
expect(out.replace(/\s*\[[0-9\.]+ms\]\s*$/, "").split(/\r?\n/)).toEqual([
"[scripts:run] Bar",
- " + Bar@workspace://bar",
+ " + Bar@workspace:bar",
"[scripts:run] Foo",
"",
" 1 packages installed",
@@ -401,5 +487,7 @@ it("should handle life-cycle scripts within workspaces", async () => {
expect(await exited).toBe(0);
expect(requested).toBe(0);
expect(await readdir(join(package_dir, "node_modules"))).toEqual(["Bar"]);
- expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar"));
+ expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(
+ join("..", "bar"),
+ );
});