aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alex Lam S.L <alexlamsl@gmail.com> 2023-06-28 11:20:59 +0300
committerGravatar GitHub <noreply@github.com> 2023-06-28 01:20:59 -0700
commit0de5bb22af427dcad57731d7063f8678b13265e2 (patch)
tree3ae79b038bb9146e24d8d4ed1daa1ebcb3da1b7e
parentf670c0fc1866352b846f092e4f0741b51f59ec1a (diff)
downloadbun-0de5bb22af427dcad57731d7063f8678b13265e2.tar.gz
bun-0de5bb22af427dcad57731d7063f8678b13265e2.tar.zst
bun-0de5bb22af427dcad57731d7063f8678b13265e2.zip
[install] workaround run-time module loading issue (#3432)
-rw-r--r--src/bun.js/module_loader.zig6
-rw-r--r--src/install/install.zig40
-rw-r--r--src/resolver/resolver.zig27
-rw-r--r--test/cli/install/bun-run.test.ts96
-rw-r--r--test/cli/install/bunx.test.ts80
5 files changed, 143 insertions, 106 deletions
diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig
index b25bb4b10..6fd4fef99 100644
--- a/src/bun.js/module_loader.zig
+++ b/src/bun.js/module_loader.zig
@@ -271,14 +271,8 @@ pub const ModuleLoader = struct {
pub fn onPoll(this: *Queue) void {
debug("onPoll", .{});
- var pm = this.vm().packageManager();
-
this.runTasks();
- _ = pm.scheduleTasks();
- this.runTasks();
-
this.pollModules();
- _ = pm.flushDependencyQueue();
}
pub fn runTasks(this: *Queue) void {
diff --git a/src/install/install.zig b/src/install/install.zig
index 9465c4897..87f931291 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -1718,9 +1718,8 @@ pub const PackageManager = struct {
}
pub fn wake(this: *PackageManager) void {
- if (this.onWake.context != null) {
- this.onWake.getHandler()(this.onWake.context.?, this);
- return;
+ if (this.onWake.context) |ctx| {
+ this.onWake.getHandler()(ctx, this);
}
_ = this.wait_count.fetchAdd(1, .Monotonic);
@@ -1791,12 +1790,37 @@ pub const PackageManager = struct {
return .{ .failure = err };
};
- const resolution_id = this.lockfile.buffers.resolutions.items[index];
+ const resolution_id = switch (this.lockfile.buffers.resolutions.items[index]) {
+ invalid_package_id => brk: {
+ this.drainDependencyList();
+
+ switch (this.options.log_level) {
+ inline else => |log_level| {
+ if (log_level.showProgress()) this.startProgressBarIfNone();
+ while (this.pending_tasks > 0) : (this.sleep()) {
+ this.runTasks(
+ void,
+ {},
+ .{
+ .onExtract = {},
+ .onResolve = {},
+ .onPackageManifestError = {},
+ .onPackageDownloadError = {},
+ },
+ log_level,
+ ) catch |err| {
+ return .{ .failure = err };
+ };
+ }
+ },
+ }
- // check if we managed to synchronously resolve the dependency
- if (resolution_id == invalid_package_id) return .{ .pending = index };
+ break :brk this.lockfile.buffers.resolutions.items[index];
+ },
+ // we managed to synchronously resolve the dependency
+ else => |pkg_id| pkg_id,
+ };
- this.drainDependencyList();
return .{
.resolution = .{
.resolution = this.lockfile.packages.items(.resolution)[resolution_id],
@@ -5310,6 +5334,8 @@ pub const PackageManager = struct {
manager.progress.supports_ansi_escape_codes = Output.enable_ansi_colors_stderr;
manager.root_progress_node = manager.progress.start("", 0);
manager.root_download_node = manager.root_progress_node.start(ProgressStrings.download(), 0);
+ } else {
+ manager.options.log_level = .default_no_progress;
}
if (!manager.options.enable.cache) {
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index 40b106f3a..d9f4dc887 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -534,20 +534,19 @@ pub const Resolver = struct {
dir_cache: *DirInfo.HashMap,
pub fn getPackageManager(this: *Resolver) *PackageManager {
- if (this.package_manager != null) {
- return this.package_manager.?;
- }
- bun.HTTPThead.init() catch unreachable;
- this.package_manager = PackageManager.initWithRuntime(
- this.log,
- this.opts.install,
- this.allocator,
- .{},
- this.env_loader.?,
- ) catch @panic("Failed to initialize package manager");
- this.package_manager.?.onWake = this.onWakePackageManager;
-
- return this.package_manager.?;
+ return this.package_manager orelse brk: {
+ bun.HTTPThead.init() catch unreachable;
+ const pm = PackageManager.initWithRuntime(
+ this.log,
+ this.opts.install,
+ this.allocator,
+ .{},
+ this.env_loader.?,
+ ) catch @panic("Failed to initialize package manager");
+ pm.onWake = this.onWakePackageManager;
+ this.package_manager = pm;
+ break :brk pm;
+ };
}
pub inline fn usePackageManager(self: *const ThisResolver) bool {
diff --git a/test/cli/install/bun-run.test.ts b/test/cli/install/bun-run.test.ts
new file mode 100644
index 000000000..fecbfc3d5
--- /dev/null
+++ b/test/cli/install/bun-run.test.ts
@@ -0,0 +1,96 @@
+import { file, spawn } from "bun";
+import { afterEach, beforeEach, expect, it } from "bun:test";
+import { bunExe, bunEnv as env } from "harness";
+import { mkdtemp, realpath, rm, writeFile } from "fs/promises";
+import { tmpdir } from "os";
+import { join } from "path";
+import { readdirSorted } from "./dummy.registry";
+
+let run_dir: string;
+
+beforeEach(async () => {
+ run_dir = await realpath(await mkdtemp(join(tmpdir(), "bun-run.test")));
+});
+afterEach(async () => {
+ await rm(run_dir, { force: true, recursive: true });
+});
+
+it("should download dependency to run local file", async () => {
+ await writeFile(
+ join(run_dir, "test.js"),
+ `
+ const { minify } = require("uglify-js@3.17.4");
+
+ console.log(minify("print(6 * 7)").code);
+ `,
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "test.js"],
+ cwd: run_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env: {
+ ...env,
+ BUN_INSTALL_CACHE_DIR: join(run_dir, ".cache"),
+ },
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toBe("");
+ expect(stdout).toBeDefined();
+ const out = await new Response(stdout).text();
+ expect(out.split(/\r?\n/)).toEqual(["print(42);", ""]);
+ expect(await exited).toBe(0);
+ expect(await readdirSorted(run_dir)).toEqual([".cache", "test.js"]);
+});
+
+it("should download dependencies to run local file", async () => {
+ await writeFile(
+ join(run_dir, "test.js"),
+ `
+ import { file } from "bun";
+ import decompress from "decompress@4.2.1";
+
+ const buffer = await file("${join(import.meta.dir, "baz-0.0.3.tgz")}").arrayBuffer();
+ for (const entry of await decompress(Buffer.from(buffer))) {
+ console.log(\`\${entry.type}: \${entry.path}\`);
+ }
+ `,
+ );
+ const { stdout, stderr, exited } = spawn({
+ cmd: [bunExe(), "test.js"],
+ cwd: run_dir,
+ stdout: null,
+ stdin: "pipe",
+ stderr: "pipe",
+ env: {
+ ...env,
+ BUN_INSTALL_CACHE_DIR: join(run_dir, ".cache"),
+ },
+ });
+ expect(stderr).toBeDefined();
+ const err = await new Response(stderr).text();
+ expect(err).toBe("");
+ expect(await readdirSorted(run_dir)).toEqual([".cache", "test.js"]);
+ expect(await readdirSorted(join(run_dir, ".cache"))).toContain("decompress");
+ expect(await readdirSorted(join(run_dir, ".cache", "decompress"))).toEqual(["4.2.1"]);
+ expect(await readdirSorted(join(run_dir, ".cache", "decompress", "4.2.1"))).toEqual([
+ "index.js",
+ "license",
+ "package.json",
+ "readme.md",
+ ]);
+ expect(await file(join(run_dir, ".cache", "decompress", "4.2.1", "index.js")).text()).toContain(
+ "\nmodule.exports = ",
+ );
+ expect(stdout).toBeDefined();
+ const out = await new Response(stdout).text();
+ expect(out.split(/\r?\n/)).toEqual([
+ "directory: package/",
+ "file: package/index.js",
+ "file: package/package.json",
+ "",
+ ]);
+ expect(await exited).toBe(0);
+});
diff --git a/test/cli/install/bunx.test.ts b/test/cli/install/bunx.test.ts
index 3605f5b6b..70d7aac29 100644
--- a/test/cli/install/bunx.test.ts
+++ b/test/cli/install/bunx.test.ts
@@ -1,4 +1,4 @@
-import { file, spawn } from "bun";
+import { spawn } from "bun";
import { afterEach, beforeEach, expect, it } from "bun:test";
import { bunExe, bunEnv as env } from "harness";
import { mkdtemp, realpath, rm, writeFile } from "fs/promises";
@@ -109,84 +109,6 @@ it("should work for @scoped packages", async () => {
expect(await cached.exited).toBe(0);
});
-it("should download dependency to run local file", async () => {
- await writeFile(
- join(x_dir, "test.js"),
- `
-const { minify } = require("uglify-js@3.17.4");
-
-console.log(minify("print(6 * 7)").code);
-`,
- );
- const { stdout, stderr, exited } = spawn({
- cmd: [bunExe(), "test.js"],
- cwd: x_dir,
- stdout: null,
- stdin: "pipe",
- stderr: "pipe",
- env: {
- ...env,
- BUN_INSTALL_CACHE_DIR: join(x_dir, ".cache"),
- },
- });
- expect(stderr).toBeDefined();
- const err = await new Response(stderr).text();
- expect(err).toBe("");
- expect(stdout).toBeDefined();
- const out = await new Response(stdout).text();
- expect(out.split(/\r?\n/)).toEqual(["print(42);", ""]);
- expect(await exited).toBe(0);
- expect(await readdirSorted(x_dir)).toEqual([".cache", "test.js"]);
-});
-
-it("should download dependencies to run local file", async () => {
- await writeFile(
- join(x_dir, "test.js"),
- `
-import { file } from "bun";
-import decompress from "decompress@4.2.1";
-
-const buffer = await file("${join(import.meta.dir, "baz-0.0.3.tgz")}").arrayBuffer();
-for (const entry of await decompress(Buffer.from(buffer))) {
- console.log(\`\${entry.type}: \${entry.path}\`);
-}
-`,
- );
- const { stdout, stderr, exited } = spawn({
- cmd: [bunExe(), "test.js"],
- cwd: x_dir,
- stdout: null,
- stdin: "pipe",
- stderr: "pipe",
- env: {
- ...env,
- BUN_INSTALL_CACHE_DIR: join(x_dir, ".cache"),
- },
- });
- expect(stderr).toBeDefined();
- const err = await new Response(stderr).text();
- expect(err).toBe("");
- expect(await readdirSorted(x_dir)).toEqual([".cache", "test.js"]);
- expect(await readdirSorted(join(x_dir, ".cache"))).toContain("decompress");
- expect(await readdirSorted(join(x_dir, ".cache", "decompress"))).toEqual(["4.2.1"]);
- expect(await readdirSorted(join(x_dir, ".cache", "decompress", "4.2.1"))).toEqual([
- "index.js",
- "license",
- "package.json",
- "readme.md",
- ]);
- expect(await file(join(x_dir, ".cache", "decompress", "4.2.1", "index.js")).text()).toContain("\nmodule.exports = ");
- expect(stdout).toBeDefined();
- const out = await new Response(stdout).text();
- expect(out.split(/\r?\n/)).toEqual([
- "directory: package/",
- "file: package/index.js",
- "file: package/package.json",
- "",
- ]);
- expect(await exited).toBe(0);
-});
-
it("should execute from current working directory", async () => {
await writeFile(
join(x_dir, "test.js"),