Compare commits

...

4 Commits

Author SHA1 Message Date
Jarred Sumner
1fd748449b Update build-id 2023-01-30 23:12:54 -08:00
Jarred Sumner
bf7638eb42 Add test 2023-01-30 23:11:03 -08:00
Jarred Sumner
dfcf200c82 Prettier 2023-01-30 23:10:56 -08:00
Jarred Sumner
f669eda3db Fix crash in bun install <package-name> when <package-name> already exists 2023-01-30 22:53:24 -08:00
4 changed files with 508 additions and 155 deletions

View File

@@ -1 +1 @@
2
3

View File

@@ -4270,17 +4270,25 @@ pub const PackageManager = struct {
// 3. There is a "dependencies" (or equivalent list), and the package name exists in multiple lists
ast_modifier: {
// Try to use the existing spot in the dependencies list if possible
for (updates) |update, i| {
for (updates) |*update| {
outer: for (dependency_lists_to_check) |list| {
if (current_package_json.asProperty(list)) |query| {
if (query.expr.data == .e_object) {
if (query.expr.asProperty(update.name)) |value| {
if (value.expr.data == .e_string) {
if (update.resolved_name.isEmpty()) {
updates[i].e_string = value.expr.data.e_string;
update.e_string = value.expr.data.e_string;
remaining -= 1;
} else {
replacing += 1;
update.e_string = (try JSAst.Expr.init(
JSAst.E.String,
JSAst.E.String{
// we set it later
.data = "",
},
logger.Loc.Empty,
).clone(allocator)).data.e_string;
}
}
break :outer;
@@ -4290,13 +4298,16 @@ pub const PackageManager = struct {
}
}
if (remaining == 0)
if (remaining == 0 and replacing == 0)
break :ast_modifier;
var dependencies: []G.Property = &[_]G.Property{};
var dependencies_obj: ?*JSAst.E.Object = null;
if (current_package_json.asProperty(dependency_list)) |query| {
if (query.expr.data == .e_object) {
dependencies = query.expr.data.e_object.properties.slice();
dependencies_obj = query.expr.data.e_object;
dependencies = dependencies_obj.?.properties.slice();
}
}
@@ -4304,32 +4315,25 @@ pub const PackageManager = struct {
std.mem.copy(G.Property, new_dependencies, dependencies);
std.mem.set(G.Property, new_dependencies[dependencies.len..], G.Property{});
outer: for (updates) |update, j| {
outer: for (updates) |*update| {
if (update.e_string != null) continue;
defer std.debug.assert(update.e_string != null);
var k: usize = 0;
while (k < new_dependencies.len) : (k += 1) {
if (new_dependencies[k].key) |key| {
if (key.data.e_string.eql(string, update.name)) {
if (update.resolved_name.isEmpty()) {
// This actually is a duplicate
// like "react" appearing in both "dependencies" and "optionalDependencies"
// For this case, we'll just swap remove it
if (new_dependencies.len > 1) {
new_dependencies[k] = new_dependencies[new_dependencies.len - 1];
new_dependencies = new_dependencies[0 .. new_dependencies.len - 1];
} else {
new_dependencies = &[_]G.Property{};
}
continue;
if (dependencies_obj) |obj| {
if (obj.asProperty(update.name)) |prop| {
if (prop.expr.data == .e_string) {
var str = try prop.expr.clone(allocator);
str.data.e_string.* = try str.data.e_string.clone(allocator);
update.e_string = str.data.e_string;
continue :outer;
}
new_dependencies[k].key = null;
}
}
if (new_dependencies[k].key == null) {
new_dependencies[k].key = JSAst.Expr.init(
new_dependencies[k].key = try JSAst.Expr.init(
JSAst.E.String,
JSAst.E.String{
.data = try allocator.dupe(u8, if (update.is_aliased or update.resolved_name.isEmpty())
@@ -4338,17 +4342,17 @@ pub const PackageManager = struct {
update.resolved_name.slice(update.version_buf)),
},
logger.Loc.Empty,
);
).clone(allocator);
new_dependencies[k].value = JSAst.Expr.init(
new_dependencies[k].value = try JSAst.Expr.init(
JSAst.E.String,
JSAst.E.String{
// we set it later
.data = "",
},
logger.Loc.Empty,
);
updates[j].e_string = new_dependencies[k].value.?.data.e_string;
).clone(allocator);
update.e_string = new_dependencies[k].value.?.data.e_string;
continue :outer;
}
}

View File

@@ -2228,6 +2228,13 @@ pub const Expr = struct {
loc: logger.Loc,
data: Data,
pub fn clone(this: Expr, allocator: std.mem.Allocator) !Expr {
return .{
.loc = this.loc,
.data = try this.data.clone(allocator),
};
}
pub fn wrapInArrow(this: Expr, allocator: std.mem.Allocator) !Expr {
var stmts = try allocator.alloc(Stmt, 1);
stmts[0] = Stmt.alloc(S.Return, S.Return{ .value = this }, this.loc);
@@ -3608,6 +3615,122 @@ pub const Expr = struct {
// If it ends up in JSParser or JSPrinter, it is a bug.
inline_identifier: i32,
pub fn clone(this: Expr.Data, allocator: std.mem.Allocator) !Data {
return switch (this) {
.e_array => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_array)));
item.* = el.*;
return .{ .e_array = item };
},
.e_unary => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_unary)));
item.* = el.*;
return .{ .e_unary = item };
},
.e_binary => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_binary)));
item.* = el.*;
return .{ .e_binary = item };
},
.e_class => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_class)));
item.* = el.*;
return .{ .e_class = item };
},
.e_new => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_new)));
item.* = el.*;
return .{ .e_new = item };
},
.e_function => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_function)));
item.* = el.*;
return .{ .e_function = item };
},
.e_call => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_call)));
item.* = el.*;
return .{ .e_call = item };
},
.e_dot => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_dot)));
item.* = el.*;
return .{ .e_dot = item };
},
.e_index => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_index)));
item.* = el.*;
return .{ .e_index = item };
},
.e_arrow => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_arrow)));
item.* = el.*;
return .{ .e_arrow = item };
},
.e_jsx_element => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_jsx_element)));
item.* = el.*;
return .{ .e_jsx_element = item };
},
.e_object => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_object)));
item.* = el.*;
return .{ .e_object = item };
},
.e_spread => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_spread)));
item.* = el.*;
return .{ .e_spread = item };
},
.e_template_part => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_template_part)));
item.* = el.*;
return .{ .e_template_part = item };
},
.e_template => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_template)));
item.* = el.*;
return .{ .e_template = item };
},
.e_reg_exp => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_reg_exp)));
item.* = el.*;
return .{ .e_reg_exp = item };
},
.e_await => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_await)));
item.* = el.*;
return .{ .e_await = item };
},
.e_yield => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_yield)));
item.* = el.*;
return .{ .e_yield = item };
},
.e_if => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_if)));
item.* = el.*;
return .{ .e_if = item };
},
.e_import => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_import)));
item.* = el.*;
return .{ .e_import = item };
},
.e_big_int => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_big_int)));
item.* = el.*;
return .{ .e_big_int = item };
},
.e_string => |el| {
var item = try allocator.create(std.meta.Child(@TypeOf(this.e_string)));
item.* = el.*;
return .{ .e_string = item };
},
else => this,
};
}
pub fn canBeConstValue(this: Expr.Data) bool {
return switch (this) {
.e_number, .e_boolean, .e_null, .e_undefined => true,

View File

@@ -9,12 +9,7 @@ import {
} from "bun:test";
import { bunExe } from "bunExe";
import { bunEnv as env } from "bunEnv";
import {
access,
mkdir,
readlink,
writeFile,
} from "fs/promises";
import { access, mkdir, readlink, writeFile } from "fs/promises";
import { join } from "path";
import {
dummyAfterAll,
@@ -28,6 +23,7 @@ import {
root_url,
setHandler,
} from "./dummy.registry";
import { rmSync } from "fs";
beforeAll(dummyBeforeAll);
afterAll(dummyAfterAll);
@@ -161,10 +157,7 @@ it("should handle empty string in dependencies", async () => {
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([
`${root_url}/bar`,
`${root_url}/bar.tgz`,
]);
expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".cache",
@@ -575,10 +568,7 @@ it("should handle ^0 in dependencies", async () => {
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([
`${root_url}/bar`,
`${root_url}/bar.tgz`,
]);
expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".cache",
@@ -667,10 +657,7 @@ it("should handle ^0.0 in dependencies", async () => {
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([
`${root_url}/bar`,
`${root_url}/bar.tgz`,
]);
expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".cache",
@@ -798,10 +785,7 @@ it("should handle ^0.0.2 in dependencies", async () => {
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([
`${root_url}/bar`,
`${root_url}/bar.tgz`,
]);
expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".cache",
@@ -851,10 +835,7 @@ it("should handle ^0.0.2-rc in dependencies", async () => {
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([
`${root_url}/bar`,
`${root_url}/bar.tgz`,
]);
expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".cache",
@@ -904,10 +885,7 @@ it("should handle ^0.0.2-alpha.3+b4d in dependencies", async () => {
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([
`${root_url}/bar`,
`${root_url}/bar.tgz`,
]);
expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".cache",
@@ -927,11 +905,13 @@ it("should handle ^0.0.2-alpha.3+b4d in dependencies", async () => {
it("should handle dependency aliasing", async () => {
const urls = [];
setHandler(dummyRegistry(urls, "0.0.3", {
bin: {
"baz-run": "index.js",
},
}));
setHandler(
dummyRegistry(urls, "0.0.3", {
bin: {
"baz-run": "index.js",
},
}),
);
await writeFile(
join(package_dir, "package.json"),
JSON.stringify({
@@ -961,25 +941,25 @@ it("should handle dependency aliasing", async () => {
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([
`${root_url}/baz`,
`${root_url}/baz.tgz`,
]);
expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".bin",
".cache",
"Bar",
]);
expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([
"baz-run",
]);
expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual([
"index.js",
"package.json",
]);
expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({
expect(
await readdirSorted(join(package_dir, "node_modules", ".bin")),
).toEqual(["baz-run"]);
expect(
await readlink(join(package_dir, "node_modules", ".bin", "baz-run")),
).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual(
["index.js", "package.json"],
);
expect(
await file(join(package_dir, "node_modules", "Bar", "package.json")).json(),
).toEqual({
name: "baz",
version: "0.0.3",
bin: {
@@ -991,11 +971,13 @@ it("should handle dependency aliasing", async () => {
it("should handle dependency aliasing (versioned)", async () => {
const urls: string[] = [];
setHandler(dummyRegistry(urls, "0.0.3", {
bin: {
"baz-run": "index.js",
},
}));
setHandler(
dummyRegistry(urls, "0.0.3", {
bin: {
"baz-run": "index.js",
},
}),
);
await writeFile(
join(package_dir, "package.json"),
JSON.stringify({
@@ -1025,25 +1007,25 @@ it("should handle dependency aliasing (versioned)", async () => {
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([
`${root_url}/baz`,
`${root_url}/baz.tgz`,
]);
expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".bin",
".cache",
"Bar",
]);
expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([
"baz-run",
]);
expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual([
"index.js",
"package.json",
]);
expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({
expect(
await readdirSorted(join(package_dir, "node_modules", ".bin")),
).toEqual(["baz-run"]);
expect(
await readlink(join(package_dir, "node_modules", ".bin", "baz-run")),
).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual(
["index.js", "package.json"],
);
expect(
await file(join(package_dir, "node_modules", "Bar", "package.json")).json(),
).toEqual({
name: "baz",
version: "0.0.3",
bin: {
@@ -1053,13 +1035,241 @@ it("should handle dependency aliasing (versioned)", async () => {
await access(join(package_dir, "bun.lockb"));
});
it("should handle dependency aliasing (dist-tagged)", async () => {
it("should handle ^0.0.2-rc in dependencies", async () => {
const urls: string[] = [];
setHandler(dummyRegistry(urls, "0.0.3", {
setHandler(dummyRegistry(urls, "0.0.2-rc"));
await writeFile(
join(package_dir, "package.json"),
JSON.stringify({
name: "foo",
version: "0.0.1",
dependencies: {
bar: "^0.0.2-rc",
},
}),
);
const { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
cwd: package_dir,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});
expect(stderr).toBeDefined();
const err = await new Response(stderr).text();
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([
" + bar@0.0.2-rc",
"",
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.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",
});
await access(join(package_dir, "bun.lockb"));
});
it("should handle ^0.0.2-alpha.3+b4d in dependencies", async () => {
const urls: string[] = [];
setHandler(dummyRegistry(urls, "0.0.2-alpha.3"));
await writeFile(
join(package_dir, "package.json"),
JSON.stringify({
name: "foo",
version: "0.0.1",
dependencies: {
bar: "^0.0.2-alpha.3+b4d",
},
}),
);
const { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
cwd: package_dir,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});
expect(stderr).toBeDefined();
const err = await new Response(stderr).text();
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([
" + bar@0.0.2-alpha.3",
"",
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([`${root_url}/bar`, `${root_url}/bar.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",
});
await access(join(package_dir, "bun.lockb"));
});
it("should handle dependency aliasing", async () => {
const urls = [];
setHandler(
dummyRegistry(urls, "0.0.3", {
bin: {
"baz-run": "index.js",
},
}),
);
await writeFile(
join(package_dir, "package.json"),
JSON.stringify({
name: "Foo",
version: "0.0.1",
dependencies: {
Bar: "npm:baz",
},
}),
);
const { stdout, stderr, exited } = spawn({
cmd: [bunExe(), "install", "--config", import.meta.dir + "/basic.toml"],
cwd: package_dir,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});
expect(stderr).toBeDefined();
const err = await new Response(stderr).text();
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([
" + Bar@0.0.3",
"",
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".bin",
".cache",
"Bar",
]);
expect(
await readdirSorted(join(package_dir, "node_modules", ".bin")),
).toEqual(["baz-run"]);
expect(
await readlink(join(package_dir, "node_modules", ".bin", "baz-run")),
).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual(
["index.js", "package.json"],
);
expect(
await file(join(package_dir, "node_modules", "Bar", "package.json")).json(),
).toEqual({
name: "baz",
version: "0.0.3",
bin: {
"baz-run": "index.js",
},
}));
});
await access(join(package_dir, "bun.lockb"));
});
it("should let you add the same package twice", async () => {
const urls: string[] = [];
setHandler(dummyRegistry(urls, "0.0.3", {}));
await writeFile(
join(package_dir, "package.json"),
JSON.stringify({
name: "Foo",
version: "0.0.1",
dependencies: {},
}),
);
rmSync(`${root_url}/baz`, { recursive: true, force: true });
for (let i = 0; i < 2; i++) {
const { stdout, stderr, exited } = spawn({
cmd: [
bunExe(),
"install",
"baz@0.0.3",
"--config",
import.meta.dir + "/basic.toml",
],
cwd: package_dir,
stdout: null,
stdin: "pipe",
stderr: "pipe",
env,
});
expect(stderr).toBeDefined();
const err = await new Response(stderr).text();
expect(err).toContain("Saved lockfile");
expect(stdout).toBeDefined();
const out = await new Response(stdout).text();
expect(out).toContain("installed baz@0.0.3");
if (i === 0) {
expect(out).toContain("1 packages installed");
} else {
expect(out).not.toContain("1 packages installed");
}
expect(await exited).toBe(0);
expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".cache",
"baz",
]);
expect(
await file(
join(package_dir, "node_modules", "baz", "package.json"),
).json(),
).toEqual({
name: "baz",
version: "0.0.3",
bin: {
"baz-run": "index.js",
},
});
await access(join(package_dir, "bun.lockb"));
}
});
it("should handle dependency aliasing (dist-tagged)", async () => {
const urls: string[] = [];
setHandler(
dummyRegistry(urls, "0.0.3", {
bin: {
"baz-run": "index.js",
},
}),
);
await writeFile(
join(package_dir, "package.json"),
JSON.stringify({
@@ -1089,25 +1299,25 @@ it("should handle dependency aliasing (dist-tagged)", async () => {
" 1 packages installed",
]);
expect(await exited).toBe(0);
expect(urls).toEqual([
`${root_url}/baz`,
`${root_url}/baz.tgz`,
]);
expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".bin",
".cache",
"Bar",
]);
expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([
"baz-run",
]);
expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual([
"index.js",
"package.json",
]);
expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({
expect(
await readdirSorted(join(package_dir, "node_modules", ".bin")),
).toEqual(["baz-run"]);
expect(
await readlink(join(package_dir, "node_modules", ".bin", "baz-run")),
).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual(
["index.js", "package.json"],
);
expect(
await file(join(package_dir, "node_modules", "Bar", "package.json")).json(),
).toEqual({
name: "baz",
version: "0.0.3",
bin: {
@@ -1119,11 +1329,13 @@ it("should handle dependency aliasing (dist-tagged)", async () => {
it("should not reinstall aliased dependencies", async () => {
const urls = [];
setHandler(dummyRegistry(urls, "0.0.3", {
bin: {
"baz-run": "index.js",
},
}));
setHandler(
dummyRegistry(urls, "0.0.3", {
bin: {
"baz-run": "index.js",
},
}),
);
await writeFile(
join(package_dir, "package.json"),
JSON.stringify({
@@ -1157,25 +1369,25 @@ it("should not reinstall aliased dependencies", async () => {
" 1 packages installed",
]);
expect(await exited1).toBe(0);
expect(urls).toEqual([
`${root_url}/baz`,
`${root_url}/baz.tgz`,
]);
expect(urls).toEqual([`${root_url}/baz`, `${root_url}/baz.tgz`]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([
".bin",
".cache",
"Bar",
]);
expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([
"baz-run",
]);
expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual([
"index.js",
"package.json",
]);
expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({
expect(
await readdirSorted(join(package_dir, "node_modules", ".bin")),
).toEqual(["baz-run"]);
expect(
await readlink(join(package_dir, "node_modules", ".bin", "baz-run")),
).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual(
["index.js", "package.json"],
);
expect(
await file(join(package_dir, "node_modules", "Bar", "package.json")).json(),
).toEqual({
name: "baz",
version: "0.0.3",
bin: {
@@ -1214,15 +1426,18 @@ it("should not reinstall aliased dependencies", async () => {
".cache",
"Bar",
]);
expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual([
"baz-run",
]);
expect(await readlink(join(package_dir, "node_modules", ".bin", "baz-run"))).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual([
"index.js",
"package.json",
]);
expect(await file(join(package_dir, "node_modules", "Bar", "package.json")).json()).toEqual({
expect(
await readdirSorted(join(package_dir, "node_modules", ".bin")),
).toEqual(["baz-run"]);
expect(
await readlink(join(package_dir, "node_modules", ".bin", "baz-run")),
).toBe(join("..", "Bar", "index.js"));
expect(await readdirSorted(join(package_dir, "node_modules", "Bar"))).toEqual(
["index.js", "package.json"],
);
expect(
await file(join(package_dir, "node_modules", "Bar", "package.json")).json(),
).toEqual({
name: "baz",
version: "0.0.3",
bin: {
@@ -1511,25 +1726,28 @@ it("should handle GitHub URL in dependencies (github:user/repo#tag)", async () =
expect(
await readdirSorted(join(package_dir, "node_modules", ".bin")),
).toEqual(["uglifyjs"]);
expect(await readlink(join(package_dir, "node_modules", ".bin", "uglifyjs"))).toBe(join(
"..",
"uglify",
"bin",
"uglifyjs",
));
expect(
await readlink(join(package_dir, "node_modules", ".bin", "uglifyjs")),
).toBe(join("..", "uglify", "bin", "uglifyjs"));
expect(
await readdirSorted(join(package_dir, "node_modules", ".cache")),
).toEqual(["@GH@mishoo-UglifyJS-e219a9a", "uglify"]);
expect(await readdirSorted(join(package_dir, "node_modules", ".cache", "uglify"))).toEqual([
"mishoo-UglifyJS-e219a9a",
]);
expect(await readlink(join(
package_dir,
"node_modules",
".cache",
"uglify",
"mishoo-UglifyJS-e219a9a",
))).toBe(join(package_dir, "node_modules", ".cache", "@GH@mishoo-UglifyJS-e219a9a"));
expect(
await readdirSorted(join(package_dir, "node_modules", ".cache", "uglify")),
).toEqual(["mishoo-UglifyJS-e219a9a"]);
expect(
await readlink(
join(
package_dir,
"node_modules",
".cache",
"uglify",
"mishoo-UglifyJS-e219a9a",
),
),
).toBe(
join(package_dir, "node_modules", ".cache", "@GH@mishoo-UglifyJS-e219a9a"),
);
expect(
await readdirSorted(join(package_dir, "node_modules", "uglify")),
).toEqual([
@@ -1595,8 +1813,12 @@ it("should handle GitHub URL in dependencies (https://github.com/user/repo.git)"
".cache",
"uglify",
]);
expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual(["uglifyjs"]);
expect(await readdirSorted(join(package_dir, "node_modules", "uglify"))).toEqual([
expect(
await readdirSorted(join(package_dir, "node_modules", ".bin")),
).toEqual(["uglifyjs"]);
expect(
await readdirSorted(join(package_dir, "node_modules", "uglify")),
).toEqual([
".bun-tag",
".gitattributes",
".github",
@@ -1658,8 +1880,12 @@ it("should handle GitHub URL in dependencies (git+https://github.com/user/repo.g
".cache",
"uglify",
]);
expect(await readdirSorted(join(package_dir, "node_modules", ".bin"))).toEqual(["uglifyjs"]);
expect(await readdirSorted(join(package_dir, "node_modules", "uglify"))).toEqual([
expect(
await readdirSorted(join(package_dir, "node_modules", ".bin")),
).toEqual(["uglifyjs"]);
expect(
await readdirSorted(join(package_dir, "node_modules", "uglify")),
).toEqual([
".bun-tag",
".gitattributes",
".github",