diff options
Diffstat (limited to 'src/install/install.zig')
-rw-r--r-- | src/install/install.zig | 83 |
1 files changed, 68 insertions, 15 deletions
diff --git a/src/install/install.zig b/src/install/install.zig index c52b4bfa8..4a20d1b9f 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -9,6 +9,8 @@ const stringZ = bun.stringZ; const default_allocator = bun.default_allocator; const C = bun.C; const std = @import("std"); +const uws = @import("../deps/uws.zig"); +const JSC = bun.JSC; const JSLexer = bun.js_lexer; const logger = bun.logger; @@ -1635,6 +1637,51 @@ pub const CacheLevel = struct { const AsyncIO = bun.AsyncIO; const Waker = AsyncIO.Waker; +const Waiter = struct { + onWait: *const fn (this: *anyopaque) AsyncIO.Errno!usize, + onWake: *const fn (this: *anyopaque) void, + ctx: *anyopaque, + + pub fn init( + ctx: anytype, + comptime onWait: *const fn (this: @TypeOf(ctx)) AsyncIO.Errno!usize, + comptime onWake: *const fn (this: @TypeOf(ctx)) void, + ) Waiter { + return Waiter{ + .ctx = @ptrCast(ctx), + .onWait = @alignCast(@ptrCast(@as(*const anyopaque, @ptrCast(onWait)))), + .onWake = @alignCast(@ptrCast(@as(*const anyopaque, @ptrCast(onWake)))), + }; + } + + pub fn wait(this: *Waiter) AsyncIO.Errno!usize { + return this.onWait(this.ctx); + } + + pub fn wake(this: *Waiter) void { + this.onWake(this.ctx); + } + + pub fn fromUWSLoop(loop: *uws.Loop) Waiter { + const Handlers = struct { + fn onWait(uws_loop: *uws.Loop) AsyncIO.Errno!usize { + uws_loop.run(); + return 0; + } + + fn onWake(uws_loop: *uws.Loop) void { + uws_loop.wakeup(); + } + }; + + return Waiter.init( + loop, + Handlers.onWait, + Handlers.onWake, + ); + } +}; + // We can't know all the packages we need until we've downloaded all the packages // The easy way would be: // 1. Download all packages, parsing their dependencies and enqueuing all dependencies for resolution @@ -1696,7 +1743,7 @@ pub const PackageManager = struct { global_link_dir: ?std.fs.IterableDir = null, global_dir: ?std.fs.IterableDir = null, global_link_dir_path: string = "", - waiter: Waker = undefined, + waiter: Waiter = undefined, wait_count: std.atomic.Atomic(usize) = std.atomic.Atomic(usize).init(0), onWake: WakeHandler = .{}, @@ -1704,6 +1751,9 @@ pub const PackageManager = struct { peer_dependencies: std.ArrayListUnmanaged(DependencyID) = .{}, + uws_event_loop: *uws.Loop, + file_poll_store: JSC.FilePoll.Store, + const PreallocatedNetworkTasks = std.BoundedArray(NetworkTask, 1024); const NetworkTaskQueue = std.HashMapUnmanaged(u64, void, IdentityContext(u64), 80); pub var verbose_install = false; @@ -1764,7 +1814,7 @@ pub const PackageManager = struct { } _ = this.wait_count.fetchAdd(1, .Monotonic); - this.waiter.wake() catch {}; + this.waiter.wake(); } pub fn sleep(this: *PackageManager) void { @@ -3962,6 +4012,7 @@ pub const PackageManager = struct { return CacheDir{ .is_node_modules = true, .path = Fs.FileSystem.instance.abs(&fallback_parts) }; } + /// fn tick( pub fn runTasks( manager: *PackageManager, comptime ExtractCompletionContext: type, @@ -4586,6 +4637,8 @@ pub const PackageManager = struct { manager.drainDependencyList(); + manager.uws_event_loop.run(); + if (comptime log_level.showProgress()) { if (@hasField(@TypeOf(callbacks), "progress_bar") and callbacks.progress_bar == true) { const completed_items = manager.total_tasks - manager.pending_tasks; @@ -5572,6 +5625,8 @@ pub const PackageManager = struct { .waiter = try Waker.init(ctx.allocator), .workspaces = workspaces, // .progress + .uws_event_loop = uws.Loop.get(), + .file_poll_store = JSC.FilePoll.Store.init(ctx.allocator), }; manager.lockfile = try ctx.allocator.create(Lockfile); @@ -7132,7 +7187,7 @@ pub const PackageManager = struct { } } - if (resolution.tag == .workspace or this.lockfile.trusted_dependencies.contains(@as(u32, @truncate(String.Builder.stringHash(name))))) { + if (resolution.tag == .workspace or this.lockfile.hasTrustedDependency(name)) { var scripts = this.lockfile.packages.items(.scripts)[package_id]; if (scripts.hasAny()) { var path_buf: [bun.MAX_PATH_BYTES]u8 = undefined; @@ -7142,7 +7197,7 @@ pub const PackageManager = struct { .posix, ); - scripts.enqueue(this.lockfile, buf, path_str); + scripts.enqueue(this.lockfile, buf, path_str, name); } else if (!scripts.filled) { var path_buf: [bun.MAX_PATH_BYTES]u8 = undefined; const path_str = Path.joinAbsString( @@ -7157,6 +7212,7 @@ pub const PackageManager = struct { this.node_modules_folder.dir, destination_dir_subpath, path_str, + name, ) catch |err| { if (comptime log_level != .silent) { const fmt = "\n<r><red>error:<r> failed to parse life-cycle scripts for <b>{s}<r>: {s}\n"; @@ -7981,6 +8037,7 @@ pub const PackageManager = struct { manager.lockfile, lockfile.buffers.string_bytes.items, strings.withoutTrailingSlash(Fs.FileSystem.instance.top_level_dir), + maybe_root.name.slice(lockfile.buffers.string_bytes.items), ); } } @@ -8133,12 +8190,7 @@ pub const PackageManager = struct { try manager.setupGlobalDir(&ctx); } - // We don't always save the lockfile. - // This is for two reasons. - // 1. It's unnecessary work if there are no changes - // 2. There is a determinism issue in the file where alignment bytes might be garbage data - // This is a bug that needs to be fixed, however we can work around it for now - // by avoiding saving the lockfile + // It's unnecessary work to re-save the lockfile if there are no changes if (manager.options.do.save_lockfile and (did_meta_hash_change or manager.lockfile.isEmpty() or manager.options.enable.force_save_lockfile)) save: { @@ -8189,6 +8241,7 @@ pub const PackageManager = struct { manager.lockfile, manager.lockfile.buffers.string_bytes.items, strings.withoutTrailingSlash(Fs.FileSystem.instance.top_level_dir), + root.name.slice(manager.lockfile.buffers.string_bytes.items), ); } @@ -8337,15 +8390,15 @@ pub const PackageManager = struct { if (run_lifecycle_scripts and install_summary.fail == 0) { // 2. install // 3. postinstall - try manager.lockfile.scripts.run(manager.allocator, manager.env, log_level != .silent, "install"); - try manager.lockfile.scripts.run(manager.allocator, manager.env, log_level != .silent, "postinstall"); + try manager.lockfile.scripts.spawnAllPackageScripts(manager, log_level, log_level != .silent, "install"); + try manager.lockfile.scripts.spawnAllPackageScripts(manager, log_level, log_level != .silent, "postinstall"); // 4. preprepare // 5. prepare // 6. postprepare - try manager.lockfile.scripts.run(manager.allocator, manager.env, log_level != .silent, "preprepare"); - try manager.lockfile.scripts.run(manager.allocator, manager.env, log_level != .silent, "prepare"); - try manager.lockfile.scripts.run(manager.allocator, manager.env, log_level != .silent, "postprepare"); + try manager.lockfile.scripts.spawnAllPackageScripts(manager, log_level, log_level != .silent, "preprepare"); + try manager.lockfile.scripts.spawnAllPackageScripts(manager, log_level, log_level != .silent, "prepare"); + try manager.lockfile.scripts.spawnAllPackageScripts(manager, log_level, log_level != .silent, "postprepare"); } if (comptime log_level != .silent) { |