mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 02:18:47 +00:00
Compare commits
4 Commits
dylan/pyth
...
jarred/fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fd748449b | ||
|
|
bf7638eb42 | ||
|
|
dfcf200c82 | ||
|
|
f669eda3db |
@@ -1 +1 @@
|
||||
2
|
||||
3
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
123
src/js_ast.zig
123
src/js_ast.zig
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user