mirror of
https://github.com/oven-sh/bun
synced 2026-02-25 19:17:20 +01:00
Compare commits
8 Commits
jarred/hea
...
jarred/aut
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
394701e3dc | ||
|
|
73efb97de9 | ||
|
|
7d76db8752 | ||
|
|
2d7b163b3c | ||
|
|
def017a4b4 | ||
|
|
25c321031c | ||
|
|
6904d7d526 | ||
|
|
daefcd310d |
@@ -47,14 +47,7 @@ pub fn buildCommand(ctx: bun.CLI.Command.Context) !void {
|
||||
vm.argv = ctx.passthrough;
|
||||
vm.arena = &arena;
|
||||
vm.allocator = arena.allocator();
|
||||
b.options.install = ctx.install;
|
||||
b.resolver.opts.install = ctx.install;
|
||||
b.resolver.opts.global_cache = ctx.debug.global_cache;
|
||||
b.resolver.opts.prefer_offline_install = (ctx.debug.offline_mode_setting orelse .online) == .offline;
|
||||
b.resolver.opts.prefer_latest_install = (ctx.debug.offline_mode_setting orelse .online) == .latest;
|
||||
b.options.global_cache = b.resolver.opts.global_cache;
|
||||
b.options.prefer_offline_install = b.resolver.opts.prefer_offline_install;
|
||||
b.options.prefer_latest_install = b.resolver.opts.prefer_latest_install;
|
||||
b.configureAutoInstall(ctx.install, &ctx.debug);
|
||||
b.resolver.env_loader = b.env;
|
||||
b.options.minify_identifiers = ctx.bundler_options.minify_identifiers;
|
||||
b.options.minify_whitespace = ctx.bundler_options.minify_whitespace;
|
||||
|
||||
@@ -2126,6 +2126,24 @@ pub const EventLoopHandle = union(enum) {
|
||||
js: *JSC.EventLoop,
|
||||
mini: *MiniEventLoop,
|
||||
|
||||
pub fn tick(
|
||||
this: EventLoopHandle,
|
||||
context: anytype,
|
||||
comptime isDone: *const fn (@TypeOf(context)) bool,
|
||||
) void {
|
||||
switch (this) {
|
||||
.js => |js_loop| {
|
||||
while (!isDone(context)) {
|
||||
js_loop.tick();
|
||||
js_loop.autoTick();
|
||||
}
|
||||
},
|
||||
.mini => |mini| {
|
||||
mini.tick(context, @ptrCast(isDone));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn globalObject(this: EventLoopHandle) ?*JSC.JSGlobalObject {
|
||||
return switch (this) {
|
||||
.js => this.js.global,
|
||||
@@ -2266,6 +2284,28 @@ pub const EventLoopHandle = union(enum) {
|
||||
.mini => this.mini.env.?,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn wakeup(this: EventLoopHandle) void {
|
||||
switch (this) {
|
||||
.js => this.js.wakeup(),
|
||||
.mini => this.mini.loop.wakeup(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tickOnce(
|
||||
this: EventLoopHandle,
|
||||
context: anytype,
|
||||
) void {
|
||||
switch (this) {
|
||||
.js => |js_loop| {
|
||||
js_loop.tick();
|
||||
js_loop.autoTickActive();
|
||||
},
|
||||
.mini => |mini| {
|
||||
mini.tickWithoutIdle(context);
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const EventLoopTask = union {
|
||||
|
||||
@@ -812,7 +812,7 @@ pub const ModuleLoader = struct {
|
||||
this.vm().packageManager().drainDependencyList();
|
||||
}
|
||||
|
||||
pub fn onDependencyError(ctx: *anyopaque, dependency: Dependency, root_dependency_id: Install.DependencyID, err: anyerror) void {
|
||||
pub fn onDependencyError(ctx: *anyopaque, dependency: *const Dependency, root_dependency_id: Install.DependencyID, err: anyerror) void {
|
||||
var this = bun.cast(*Queue, ctx);
|
||||
debug("onDependencyError: {s}", .{this.vm().packageManager().lockfile.str(&dependency.name)});
|
||||
|
||||
@@ -1016,7 +1016,7 @@ pub const ModuleLoader = struct {
|
||||
continue;
|
||||
}
|
||||
|
||||
const package = pm.lockfile.packages.get(package_id);
|
||||
const package = &pm.lockfile.packages.get(package_id);
|
||||
bun.assert(package.resolution.tag != .root);
|
||||
|
||||
var name_and_version_hash: ?u64 = null;
|
||||
|
||||
@@ -77,14 +77,7 @@ pub const Run = struct {
|
||||
vm.arena = &run.arena;
|
||||
vm.allocator = arena.allocator();
|
||||
|
||||
b.options.install = ctx.install;
|
||||
b.resolver.opts.install = ctx.install;
|
||||
b.resolver.opts.global_cache = ctx.debug.global_cache;
|
||||
b.resolver.opts.prefer_offline_install = (ctx.debug.offline_mode_setting orelse .online) == .offline;
|
||||
b.resolver.opts.prefer_latest_install = (ctx.debug.offline_mode_setting orelse .online) == .latest;
|
||||
b.options.global_cache = b.resolver.opts.global_cache;
|
||||
b.options.prefer_offline_install = b.resolver.opts.prefer_offline_install;
|
||||
b.options.prefer_latest_install = b.resolver.opts.prefer_latest_install;
|
||||
b.configureAutoInstall(ctx.install, &ctx.debug);
|
||||
b.resolver.env_loader = b.env;
|
||||
|
||||
b.options.minify_identifiers = ctx.bundler_options.minify_identifiers;
|
||||
@@ -222,14 +215,7 @@ pub const Run = struct {
|
||||
}
|
||||
}
|
||||
|
||||
b.options.install = ctx.install;
|
||||
b.resolver.opts.install = ctx.install;
|
||||
b.resolver.opts.global_cache = ctx.debug.global_cache;
|
||||
b.resolver.opts.prefer_offline_install = (ctx.debug.offline_mode_setting orelse .online) == .offline;
|
||||
b.resolver.opts.prefer_latest_install = (ctx.debug.offline_mode_setting orelse .online) == .latest;
|
||||
b.options.global_cache = b.resolver.opts.global_cache;
|
||||
b.options.prefer_offline_install = b.resolver.opts.prefer_offline_install;
|
||||
b.options.prefer_latest_install = b.resolver.opts.prefer_latest_install;
|
||||
b.configureAutoInstall(ctx.install, &ctx.debug);
|
||||
b.resolver.env_loader = b.env;
|
||||
|
||||
b.options.minify_identifiers = ctx.bundler_options.minify_identifiers;
|
||||
|
||||
@@ -395,6 +395,17 @@ pub const Bundler = struct {
|
||||
this.resolver.allocator = allocator;
|
||||
}
|
||||
|
||||
pub fn configureAutoInstall(this: *Bundler, install: ?*Api.BunInstall, debug: *const DebugOptions) void {
|
||||
this.options.install = install;
|
||||
this.resolver.opts.install = install;
|
||||
this.resolver.opts.global_cache = debug.global_cache;
|
||||
this.resolver.opts.prefer_offline_install = (debug.offline_mode_setting orelse .online) == .offline;
|
||||
this.resolver.opts.prefer_latest_install = (debug.offline_mode_setting orelse .online) == .latest;
|
||||
this.options.global_cache = this.resolver.opts.global_cache;
|
||||
this.options.prefer_offline_install = this.resolver.opts.prefer_offline_install;
|
||||
this.options.prefer_latest_install = this.resolver.opts.prefer_latest_install;
|
||||
}
|
||||
|
||||
fn _resolveEntryPoint(bundler: *Bundler, entry_point: string) !_resolver.Result {
|
||||
return bundler.resolver.resolveWithFramework(bundler.fs.top_level_dir, entry_point, .entry_point) catch |err| {
|
||||
// Relative entry points that were not resolved to a node_modules package are
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
23
src/cli.zig
23
src/cli.zig
@@ -284,6 +284,9 @@ pub const Arguments = struct {
|
||||
clap.parseParam("--minify-identifiers Minify identifiers") catch unreachable,
|
||||
clap.parseParam("--experimental-css Enabled experimental CSS bundling") catch unreachable,
|
||||
clap.parseParam("--experimental-css-chunking Chunk CSS files together to reduce duplicated CSS loaded in a browser. Only has an affect when multiple entrypoints import CSS") catch unreachable,
|
||||
clap.parseParam("--no-install Disable auto install in the Bun runtime") catch unreachable,
|
||||
clap.parseParam("--auto-install <STR>? Configure auto-install behavior. One of \"auto\" (auto-installs when no node_modules), \"fallback\" (missing packages only), \"force\" (always), \"disable\" (default, no auto-installs).") catch unreachable,
|
||||
clap.parseParam("-i Auto-install dependencies during execution. Equivalent to --install=fallback.") catch unreachable,
|
||||
clap.parseParam("--dump-environment-variables") catch unreachable,
|
||||
clap.parseParam("--conditions <STR>... Pass custom conditions to resolve") catch unreachable,
|
||||
clap.parseParam("--app (EXPERIMENTAL) Build a web app for production using Bun Bake.") catch unreachable,
|
||||
@@ -291,6 +294,7 @@ pub const Arguments = struct {
|
||||
} ++ if (FeatureFlags.bake_debugging_features) [_]ParamType{
|
||||
clap.parseParam("--debug-dump-server-files When --app is set, dump all server files to disk even when building statically") catch unreachable,
|
||||
} else .{};
|
||||
|
||||
pub const build_params = build_only_params ++ transpiler_params_ ++ base_params_;
|
||||
|
||||
// TODO: update test completions
|
||||
@@ -784,7 +788,7 @@ pub const Arguments = struct {
|
||||
|
||||
ctx.bundler_options.ignore_dce_annotations = args.flag("--ignore-dce-annotations");
|
||||
|
||||
if (cmd == .BuildCommand) {
|
||||
if (comptime cmd == .BuildCommand) {
|
||||
ctx.bundler_options.transform_only = args.flag("--no-bundle");
|
||||
ctx.bundler_options.bytecode = args.flag("--bytecode");
|
||||
|
||||
@@ -829,6 +833,23 @@ pub const Arguments = struct {
|
||||
ctx.bundler_options.emit_dce_annotations = args.flag("--emit-dce-annotations") or
|
||||
!ctx.bundler_options.minify_whitespace;
|
||||
|
||||
if (args.flag("-i")) {
|
||||
ctx.debug.global_cache = .fallback;
|
||||
} else if (args.option("--auto-install")) |enum_value| {
|
||||
// -i=auto --auto-install=force, --auto-install=disable
|
||||
if (options.GlobalCache.Map.get(enum_value)) |result| {
|
||||
ctx.debug.global_cache = result;
|
||||
// -i, --auto-install
|
||||
} else if (enum_value.len == 0) {
|
||||
ctx.debug.global_cache = options.GlobalCache.force;
|
||||
} else {
|
||||
Output.errGeneric("Invalid value for --auto-install: \"{s}\". Must be either \"auto\", \"fallback\", \"force\", or \"disable\"\n", .{enum_value});
|
||||
Global.exit(1);
|
||||
}
|
||||
} else {
|
||||
ctx.debug.global_cache = .disable;
|
||||
}
|
||||
|
||||
if (args.options("--external").len > 0) {
|
||||
var externals = try allocator.alloc([]const u8, args.options("--external").len);
|
||||
for (args.options("--external"), 0..) |external, i| {
|
||||
|
||||
@@ -271,6 +271,8 @@ pub const BuildCommand = struct {
|
||||
var minify_duration: u64 = 0;
|
||||
var input_code_length: u64 = 0;
|
||||
|
||||
this_bundler.configureAutoInstall(ctx.install, &ctx.debug);
|
||||
|
||||
const output_files: []options.OutputFile = brk: {
|
||||
if (ctx.bundler_options.transform_only) {
|
||||
this_bundler.options.import_path_format = .relative;
|
||||
|
||||
@@ -2730,7 +2730,7 @@ pub const PackageManager = struct {
|
||||
// name hash from alias package name -> aliased package dependency version info
|
||||
known_npm_aliases: NpmAliasMap = .{},
|
||||
|
||||
event_loop: JSC.AnyEventLoop,
|
||||
event_loop: JSC.EventLoopHandle,
|
||||
|
||||
// During `installPackages` we learn exactly what dependencies from --trust
|
||||
// actually have scripts to run, and we add them to this list
|
||||
@@ -3082,8 +3082,8 @@ pub const PackageManager = struct {
|
||||
return bun.cast(*const fn (ctx: *anyopaque, pm: *PackageManager) void, t.handler);
|
||||
}
|
||||
|
||||
pub inline fn getonDependencyError(t: @This()) *const fn (ctx: *anyopaque, Dependency, DependencyID, anyerror) void {
|
||||
return bun.cast(*const fn (ctx: *anyopaque, Dependency, DependencyID, anyerror) void, t.handler);
|
||||
pub inline fn getonDependencyError(t: @This()) *const fn (ctx: *anyopaque, *const Dependency, DependencyID, anyerror) void {
|
||||
return bun.cast(*const fn (ctx: *anyopaque, *const Dependency, DependencyID, anyerror) void, t.handler);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3091,7 +3091,7 @@ pub const PackageManager = struct {
|
||||
if (this.onWake.context) |ctx| {
|
||||
this.onWake.getonDependencyError()(
|
||||
ctx,
|
||||
dependency.*,
|
||||
dependency,
|
||||
dependency_id,
|
||||
err,
|
||||
);
|
||||
@@ -3139,12 +3139,12 @@ pub const PackageManager = struct {
|
||||
version_buf: []const u8,
|
||||
behavior: Dependency.Behavior,
|
||||
) DependencyToEnqueue {
|
||||
const dep_id = @as(DependencyID, @truncate(brk: {
|
||||
const dep_id: u32, const is_newly_added = brk: {
|
||||
const str_buf = this.lockfile.buffers.string_bytes.items;
|
||||
for (this.lockfile.buffers.dependencies.items, 0..) |dep, id| {
|
||||
if (!strings.eqlLong(dep.name.slice(str_buf), name, true)) continue;
|
||||
if (!dep.version.eql(version, str_buf, version_buf)) continue;
|
||||
break :brk id;
|
||||
break :brk .{ @truncate(id), true };
|
||||
}
|
||||
|
||||
var builder = this.lockfile.stringBuilder();
|
||||
@@ -3164,100 +3164,50 @@ pub const PackageManager = struct {
|
||||
this.lockfile.buffers.dependencies.append(this.allocator, dep) catch unreachable;
|
||||
this.lockfile.buffers.resolutions.append(this.allocator, invalid_package_id) catch unreachable;
|
||||
if (comptime Environment.allow_assert) bun.assert(this.lockfile.buffers.dependencies.items.len == this.lockfile.buffers.resolutions.items.len);
|
||||
break :brk index;
|
||||
}));
|
||||
break :brk .{ @truncate(index), false };
|
||||
};
|
||||
_ = is_newly_added; // autofix
|
||||
|
||||
if (this.lockfile.buffers.resolutions.items[dep_id] == invalid_package_id) {
|
||||
const initial_pending_task_count = this.pendingTaskCount();
|
||||
_ = initial_pending_task_count; // autofix
|
||||
|
||||
var resolution_id = this.lockfile.buffers.resolutions.items[dep_id];
|
||||
if (resolution_id == invalid_package_id) {
|
||||
this.enqueueDependencyWithMainAndSuccessFn(
|
||||
dep_id,
|
||||
&this.lockfile.buffers.dependencies.items[dep_id],
|
||||
invalid_package_id,
|
||||
resolution_id,
|
||||
false,
|
||||
assignRootResolution,
|
||||
failRootResolution,
|
||||
) catch |err| {
|
||||
return .{ .failure = err };
|
||||
};
|
||||
// We might immediately resolve it.
|
||||
resolution_id = this.lockfile.buffers.resolutions.items[dep_id];
|
||||
}
|
||||
|
||||
const resolution_id = switch (this.lockfile.buffers.resolutions.items[dep_id]) {
|
||||
invalid_package_id => brk: {
|
||||
this.drainDependencyList();
|
||||
this.drainDependencyList();
|
||||
|
||||
switch (this.options.log_level) {
|
||||
inline else => |log_levela| {
|
||||
const Closure = struct {
|
||||
// https://github.com/ziglang/zig/issues/19586
|
||||
pub fn issue_19586_workaround(comptime log_level: Options.LogLevel) type {
|
||||
return struct {
|
||||
err: ?anyerror = null,
|
||||
manager: *PackageManager,
|
||||
pub fn isDone(closure: *@This()) bool {
|
||||
const manager = closure.manager;
|
||||
if (manager.pendingTaskCount() > 0) {
|
||||
manager.runTasks(
|
||||
void,
|
||||
{},
|
||||
.{
|
||||
.onExtract = {},
|
||||
.onResolve = {},
|
||||
.onPackageManifestError = {},
|
||||
.onPackageDownloadError = {},
|
||||
},
|
||||
false,
|
||||
log_level,
|
||||
) catch |err| {
|
||||
closure.err = err;
|
||||
return true;
|
||||
};
|
||||
|
||||
if (PackageManager.verbose_install and manager.pendingTaskCount() > 0) {
|
||||
if (PackageManager.hasEnoughTimePassedBetweenWaitingMessages()) Output.prettyErrorln("<d>[PackageManager]<r> waiting for {d} tasks\n", .{closure.manager.pendingTaskCount()});
|
||||
}
|
||||
}
|
||||
|
||||
return manager.pendingTaskCount() == 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
}.issue_19586_workaround(log_levela);
|
||||
|
||||
if (comptime log_levela.showProgress()) {
|
||||
this.startProgressBarIfNone();
|
||||
}
|
||||
|
||||
var closure = Closure{ .manager = this };
|
||||
this.sleepUntil(&closure, &Closure.isDone);
|
||||
|
||||
if (comptime log_levela.showProgress()) {
|
||||
this.endProgressBar();
|
||||
Output.flush();
|
||||
}
|
||||
|
||||
if (closure.err) |err| {
|
||||
return .{ .failure = err };
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
break :brk this.lockfile.buffers.resolutions.items[dep_id];
|
||||
},
|
||||
// we managed to synchronously resolve the dependency
|
||||
else => |pkg_id| pkg_id,
|
||||
};
|
||||
|
||||
if (resolution_id == invalid_package_id) {
|
||||
return .{
|
||||
.not_found = {},
|
||||
};
|
||||
var out_name_and_version_hash: ?u64 = null;
|
||||
var out_patchfile_hash: ?u64 = null;
|
||||
if (resolution_id != invalid_package_id) {
|
||||
switch (this.determinePreinstallStateAndPossiblyDownloadPackageIntoCache(&this.lockfile.packages.get(resolution_id), dep_id, this.lockfile, &out_name_and_version_hash, &out_patchfile_hash)) {
|
||||
.extract, .extracting => {
|
||||
return .{ .pending = dep_id };
|
||||
},
|
||||
else => {
|
||||
return .{
|
||||
.resolution = .{
|
||||
.resolution = this.lockfile.packages.items(.resolution)[resolution_id],
|
||||
.package_id = resolution_id,
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return .{
|
||||
.resolution = .{
|
||||
.resolution = this.lockfile.packages.items(.resolution)[resolution_id],
|
||||
.package_id = resolution_id,
|
||||
},
|
||||
};
|
||||
return .{ .pending = dep_id };
|
||||
}
|
||||
|
||||
pub fn globalLinkDir(this: *PackageManager) !std.fs.Dir {
|
||||
@@ -3336,7 +3286,7 @@ pub const PackageManager = struct {
|
||||
|
||||
pub fn determinePreinstallState(
|
||||
manager: *PackageManager,
|
||||
this: Package,
|
||||
this: *const Package,
|
||||
lockfile: *Lockfile,
|
||||
out_name_and_version_hash: *?u64,
|
||||
out_patchfile_hash: *?u64,
|
||||
@@ -3421,6 +3371,94 @@ pub const PackageManager = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn determinePreinstallStateAndPossiblyDownloadPackageIntoCache(
|
||||
manager: *PackageManager,
|
||||
this: *const Package,
|
||||
dependency_id: DependencyID,
|
||||
lockfile: *Lockfile,
|
||||
out_name_and_version_hash: *?u64,
|
||||
out_patchfile_hash: *?u64,
|
||||
) PreinstallState {
|
||||
switch (manager.getPreinstallState(this.meta.id)) {
|
||||
.unknown => switch (manager.determinePreinstallState(this, lockfile, out_name_and_version_hash, out_patchfile_hash)) {
|
||||
.extract => {
|
||||
if (this.resolution.tag.canEnqueueInstallTask()) {
|
||||
switch (this.resolution.tag) {
|
||||
.git => {
|
||||
manager.enqueueGitForCheckout(
|
||||
dependency_id,
|
||||
"",
|
||||
&this.resolution,
|
||||
.{ .root_dependency = dependency_id },
|
||||
out_name_and_version_hash.*,
|
||||
);
|
||||
},
|
||||
.github => {
|
||||
const url = manager.allocGitHubURL(&this.resolution.value.github);
|
||||
defer manager.allocator.free(url);
|
||||
manager.enqueueTarballForDownload(
|
||||
dependency_id,
|
||||
this.meta.id,
|
||||
url,
|
||||
.{ .root_dependency = dependency_id },
|
||||
out_name_and_version_hash.*,
|
||||
);
|
||||
},
|
||||
.local_tarball => {
|
||||
manager.enqueueTarballForReading(
|
||||
dependency_id,
|
||||
"",
|
||||
&this.resolution,
|
||||
.{ .root_dependency = dependency_id },
|
||||
);
|
||||
},
|
||||
.remote_tarball => {
|
||||
manager.enqueueTarballForDownload(
|
||||
dependency_id,
|
||||
this.meta.id,
|
||||
manager.lockfile.str(&this.resolution.value.remote_tarball),
|
||||
.{ .root_dependency = dependency_id },
|
||||
out_name_and_version_hash.*,
|
||||
);
|
||||
},
|
||||
.npm => {
|
||||
if (comptime Environment.isDebug) {
|
||||
// Very old versions of Bun didn't store the tarball url when it didn't seem necessary
|
||||
// This caused bugs. We can't assert on it because they could come from old lockfiles
|
||||
if (this.resolution.value.npm.url.isEmpty()) {
|
||||
Output.debugWarn("package {s}@{} missing tarball_url", .{ manager.lockfile.str(&this.name), this.resolution.fmt(manager.lockfile.buffers.string_bytes.items, .posix) });
|
||||
}
|
||||
}
|
||||
|
||||
manager.enqueuePackageForDownload(
|
||||
manager.lockfile.str(&this.name),
|
||||
dependency_id,
|
||||
this.meta.id,
|
||||
this.resolution.value.npm.version,
|
||||
manager.lockfile.str(&this.resolution.value.npm.url),
|
||||
.{ .root_dependency = dependency_id },
|
||||
out_name_and_version_hash.*,
|
||||
);
|
||||
},
|
||||
else => {
|
||||
if (comptime Environment.allow_assert) {
|
||||
@panic("unreachable, handled above");
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
manager.setPreinstallState(this.meta.id, lockfile, .extracting);
|
||||
return .extracting;
|
||||
}
|
||||
|
||||
return .extract;
|
||||
},
|
||||
else => |val| return val,
|
||||
},
|
||||
else => |val| return val,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scopeForPackageName(this: *const PackageManager, name: string) *const Npm.Registry.Scope {
|
||||
if (name.len == 0 or name[0] != '@') return &this.options.scope;
|
||||
return this.options.registries.getPtr(
|
||||
@@ -3975,6 +4013,7 @@ pub const PackageManager = struct {
|
||||
|
||||
return this.pathForCachedNPMPath(buf, package_name, npm.version);
|
||||
},
|
||||
|
||||
else => return "",
|
||||
}
|
||||
}
|
||||
@@ -4262,7 +4301,7 @@ pub const PackageManager = struct {
|
||||
var patchfile_hash: ?u64 = null;
|
||||
|
||||
return switch (this.determinePreinstallState(
|
||||
package,
|
||||
&package,
|
||||
this.lockfile,
|
||||
&name_and_version_hash,
|
||||
&patchfile_hash,
|
||||
@@ -4571,33 +4610,14 @@ pub const PackageManager = struct {
|
||||
|
||||
switch (version.tag) {
|
||||
.npm, .dist_tag => {
|
||||
resolve_from_workspace: {
|
||||
if (version.tag == .npm) {
|
||||
const workspace_path = if (this.lockfile.workspace_paths.count() > 0) this.lockfile.workspace_paths.get(name_hash) else null;
|
||||
const workspace_version = this.lockfile.workspace_versions.get(name_hash);
|
||||
const buf = this.lockfile.buffers.string_bytes.items;
|
||||
if ((workspace_version != null and version.value.npm.version.satisfies(workspace_version.?, buf, buf)) or
|
||||
|
||||
// https://github.com/oven-sh/bun/pull/10899#issuecomment-2099609419
|
||||
// if the workspace doesn't have a version, it can still be used if
|
||||
// dependency version is wildcard
|
||||
(workspace_path != null and version.value.npm.version.@"is *"()))
|
||||
{
|
||||
const root_package = this.lockfile.rootPackage() orelse break :resolve_from_workspace;
|
||||
const root_dependencies = root_package.dependencies.get(this.lockfile.buffers.dependencies.items);
|
||||
const root_resolutions = root_package.resolutions.get(this.lockfile.buffers.resolutions.items);
|
||||
|
||||
for (root_dependencies, root_resolutions) |root_dep, workspace_package_id| {
|
||||
if (workspace_package_id != invalid_package_id and root_dep.version.tag == .workspace and root_dep.name_hash == name_hash) {
|
||||
// make sure verifyResolutions sees this resolution as a valid package id
|
||||
successFn(this, dependency_id, workspace_package_id);
|
||||
return .{
|
||||
.package = this.lockfile.packages.get(workspace_package_id),
|
||||
.is_first_time = false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (version.tag == .npm) {
|
||||
if (this.lockfile.resolveWorkspaceFromNpmVersion(name_hash, &version)) |workspace_package_id| {
|
||||
// make sure verifyResolutions sees this resolution as a valid package id
|
||||
successFn(this, dependency_id, workspace_package_id);
|
||||
return .{
|
||||
.package = this.lockfile.packages.get(workspace_package_id),
|
||||
.is_first_time = false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4614,26 +4634,14 @@ pub const PackageManager = struct {
|
||||
.npm => manifest.findBestVersion(version.value.npm.version, this.lockfile.buffers.string_bytes.items),
|
||||
else => unreachable,
|
||||
} orelse {
|
||||
resolve_workspace_from_dist_tag: {
|
||||
// choose a workspace for a dist_tag only if a version was not found
|
||||
if (version.tag == .dist_tag) {
|
||||
const workspace_path = if (this.lockfile.workspace_paths.count() > 0) this.lockfile.workspace_paths.get(name_hash) else null;
|
||||
if (workspace_path != null) {
|
||||
const root_package = this.lockfile.rootPackage() orelse break :resolve_workspace_from_dist_tag;
|
||||
const root_dependencies = root_package.dependencies.get(this.lockfile.buffers.dependencies.items);
|
||||
const root_resolutions = root_package.resolutions.get(this.lockfile.buffers.resolutions.items);
|
||||
|
||||
for (root_dependencies, root_resolutions) |root_dep, workspace_package_id| {
|
||||
if (workspace_package_id != invalid_package_id and root_dep.version.tag == .workspace and root_dep.name_hash == name_hash) {
|
||||
// make sure verifyResolutions sees this resolution as a valid package id
|
||||
successFn(this, dependency_id, workspace_package_id);
|
||||
return .{
|
||||
.package = this.lockfile.packages.get(workspace_package_id),
|
||||
.is_first_time = false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
// choose a workspace for a dist_tag only if a version was not found
|
||||
if (version.tag == .dist_tag) {
|
||||
if (this.lockfile.resolveWorkspaceFromNpmDistTag(name_hash)) |workspace_package_id| {
|
||||
return .{
|
||||
.package = this.lockfile.packages.get(workspace_package_id),
|
||||
.is_first_time = false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6208,6 +6216,24 @@ pub const PackageManager = struct {
|
||||
|
||||
var timestamp_this_tick: ?u32 = null;
|
||||
|
||||
defer {
|
||||
manager.drainDependencyList();
|
||||
|
||||
if (comptime log_level.showProgress()) {
|
||||
manager.startProgressBarIfNone();
|
||||
|
||||
if (@hasField(@TypeOf(callbacks), "progress_bar") and callbacks.progress_bar == true) {
|
||||
const completed_items = manager.total_tasks - manager.pendingTaskCount();
|
||||
if (completed_items != manager.downloads_node.?.unprotected_completed_items or has_updated_this_run) {
|
||||
manager.downloads_node.?.setCompletedItems(completed_items);
|
||||
manager.downloads_node.?.setEstimatedTotalItems(manager.total_tasks);
|
||||
}
|
||||
}
|
||||
manager.downloads_node.?.activate();
|
||||
manager.progress.maybeRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
var patch_tasks_batch = manager.patch_task_queue.popBatch();
|
||||
var patch_tasks_iter = patch_tasks_batch.iterator();
|
||||
while (patch_tasks_iter.next()) |ptask| {
|
||||
@@ -6259,6 +6285,7 @@ pub const PackageManager = struct {
|
||||
const name = manifest_req.name;
|
||||
if (comptime log_level.showProgress()) {
|
||||
if (!has_updated_this_run) {
|
||||
manager.startProgressBarIfNone();
|
||||
manager.setNodeName(manager.downloads_node.?, name.slice(), ProgressStrings.download_emoji, true);
|
||||
has_updated_this_run = true;
|
||||
}
|
||||
@@ -6606,6 +6633,7 @@ pub const PackageManager = struct {
|
||||
|
||||
if (comptime log_level.showProgress()) {
|
||||
if (!has_updated_this_run) {
|
||||
manager.startProgressBarIfNone();
|
||||
manager.setNodeName(manager.downloads_node.?, extract.name.slice(), ProgressStrings.extract_emoji, true);
|
||||
has_updated_this_run = true;
|
||||
}
|
||||
@@ -6673,6 +6701,7 @@ pub const PackageManager = struct {
|
||||
|
||||
if (comptime log_level.showProgress()) {
|
||||
if (!has_updated_this_run) {
|
||||
manager.startProgressBarIfNone();
|
||||
manager.setNodeName(manager.downloads_node.?, manifest.name(), ProgressStrings.download_emoji, true);
|
||||
has_updated_this_run = true;
|
||||
}
|
||||
@@ -6800,6 +6829,7 @@ pub const PackageManager = struct {
|
||||
|
||||
if (comptime log_level.showProgress()) {
|
||||
if (!has_updated_this_run) {
|
||||
manager.startProgressBarIfNone();
|
||||
manager.setNodeName(manager.downloads_node.?, alias, ProgressStrings.extract_emoji, true);
|
||||
has_updated_this_run = true;
|
||||
}
|
||||
@@ -6845,6 +6875,7 @@ pub const PackageManager = struct {
|
||||
|
||||
if (comptime log_level.showProgress()) {
|
||||
if (!has_updated_this_run) {
|
||||
manager.startProgressBarIfNone();
|
||||
manager.setNodeName(manager.downloads_node.?, name, ProgressStrings.download_emoji, true);
|
||||
has_updated_this_run = true;
|
||||
}
|
||||
@@ -6924,6 +6955,7 @@ pub const PackageManager = struct {
|
||||
|
||||
if (comptime log_level.showProgress()) {
|
||||
if (!has_updated_this_run) {
|
||||
manager.startProgressBarIfNone();
|
||||
manager.setNodeName(manager.downloads_node.?, alias.slice(), ProgressStrings.download_emoji, true);
|
||||
has_updated_this_run = true;
|
||||
}
|
||||
@@ -6931,20 +6963,6 @@ pub const PackageManager = struct {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
manager.drainDependencyList();
|
||||
|
||||
if (comptime log_level.showProgress()) {
|
||||
if (@hasField(@TypeOf(callbacks), "progress_bar") and callbacks.progress_bar == true) {
|
||||
const completed_items = manager.total_tasks - manager.pendingTaskCount();
|
||||
if (completed_items != manager.downloads_node.?.unprotected_completed_items or has_updated_this_run) {
|
||||
manager.downloads_node.?.setCompletedItems(completed_items);
|
||||
manager.downloads_node.?.setEstimatedTotalItems(manager.total_tasks);
|
||||
}
|
||||
}
|
||||
manager.downloads_node.?.activate();
|
||||
manager.progress.maybeRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
pub const Options = struct {
|
||||
@@ -8736,16 +8754,16 @@ pub const PackageManager = struct {
|
||||
.root_package_json_file = root_package_json_file,
|
||||
// .progress
|
||||
.event_loop = .{
|
||||
.mini = JSC.MiniEventLoop.init(bun.default_allocator),
|
||||
.mini = bun.create(bun.default_allocator, JSC.MiniEventLoop, JSC.MiniEventLoop.init(bun.default_allocator)),
|
||||
},
|
||||
.original_package_json_path = original_package_json_path,
|
||||
.workspace_package_json_cache = workspace_package_json_cache,
|
||||
.workspace_name_hash = workspace_name_hash,
|
||||
.subcommand = subcommand,
|
||||
};
|
||||
manager.event_loop.loop().internal_loop_data.setParentEventLoop(bun.JSC.EventLoopHandle.init(&manager.event_loop));
|
||||
manager.event_loop.loop().internal_loop_data.setParentEventLoop(manager.event_loop);
|
||||
manager.lockfile = try ctx.allocator.create(Lockfile);
|
||||
JSC.MiniEventLoop.global = &manager.event_loop.mini;
|
||||
JSC.MiniEventLoop.global = manager.event_loop.mini;
|
||||
if (!manager.options.enable.cache) {
|
||||
manager.options.enable.manifest_cache = false;
|
||||
manager.options.enable.manifest_cache_control = false;
|
||||
@@ -8840,7 +8858,10 @@ pub const PackageManager = struct {
|
||||
cli: CommandLineArguments,
|
||||
env: *DotEnv.Loader,
|
||||
) *PackageManager {
|
||||
init_with_runtime_once.call(.{
|
||||
init_with_event_loop_once.call(.{
|
||||
.{
|
||||
.js = JSC.VirtualMachine.get().eventLoop(),
|
||||
},
|
||||
log,
|
||||
bun_install,
|
||||
allocator,
|
||||
@@ -8850,9 +8871,22 @@ pub const PackageManager = struct {
|
||||
return PackageManager.get();
|
||||
}
|
||||
|
||||
var init_with_runtime_once = bun.once(initWithRuntimeOnce);
|
||||
var init_with_event_loop_once = bun.once(initWithEventLoopOnce);
|
||||
|
||||
pub fn initWithRuntimeOnce(
|
||||
pub fn initWithEventLoop(
|
||||
loop: JSC.EventLoopHandle,
|
||||
log: *logger.Log,
|
||||
bun_install: ?*Api.BunInstall,
|
||||
allocator: std.mem.Allocator,
|
||||
cli: CommandLineArguments,
|
||||
env: *DotEnv.Loader,
|
||||
) *PackageManager {
|
||||
init_with_event_loop_once.call(.{ loop, log, bun_install, allocator, cli, env });
|
||||
return PackageManager.get();
|
||||
}
|
||||
|
||||
fn initWithEventLoopOnce(
|
||||
loop: JSC.EventLoopHandle,
|
||||
log: *logger.Log,
|
||||
bun_install: ?*Api.BunInstall,
|
||||
allocator: std.mem.Allocator,
|
||||
@@ -8898,9 +8932,7 @@ pub const PackageManager = struct {
|
||||
}),
|
||||
.lockfile = undefined,
|
||||
.root_package_json_file = undefined,
|
||||
.event_loop = .{
|
||||
.js = JSC.VirtualMachine.get().eventLoop(),
|
||||
},
|
||||
.event_loop = loop,
|
||||
.original_package_json_path = original_package_json_path[0..original_package_json_path.len :0],
|
||||
.subcommand = .install,
|
||||
};
|
||||
@@ -11770,7 +11802,7 @@ pub const PackageManager = struct {
|
||||
Global.crash();
|
||||
};
|
||||
const paths = bun.patch.gitDiffPreprocessPaths(bun.default_allocator, old_folder, new_folder, false);
|
||||
const opts = bun.patch.spawnOpts(paths[0], paths[1], cwd, git, &manager.event_loop);
|
||||
const opts = bun.patch.spawnOpts(paths[0], paths[1], cwd, git, manager.event_loop);
|
||||
|
||||
var spawn_result = switch (bun.spawnSync(&opts) catch |e| {
|
||||
Output.prettyError(
|
||||
|
||||
@@ -48,8 +48,8 @@ pub const LifecycleScriptSubprocess = struct {
|
||||
return this.manager.event_loop.loop();
|
||||
}
|
||||
|
||||
pub fn eventLoop(this: *const LifecycleScriptSubprocess) *JSC.AnyEventLoop {
|
||||
return &this.manager.event_loop;
|
||||
pub fn eventLoop(this: *const LifecycleScriptSubprocess) JSC.EventLoopHandle {
|
||||
return this.manager.event_loop;
|
||||
}
|
||||
|
||||
pub fn scriptName(this: *const LifecycleScriptSubprocess) []const u8 {
|
||||
@@ -187,7 +187,7 @@ pub const LifecycleScriptSubprocess = struct {
|
||||
|
||||
.windows = if (Environment.isWindows)
|
||||
.{
|
||||
.loop = JSC.EventLoopHandle.init(&manager.event_loop),
|
||||
.loop = this.eventLoop(),
|
||||
}
|
||||
else {},
|
||||
|
||||
@@ -233,7 +233,7 @@ pub const LifecycleScriptSubprocess = struct {
|
||||
}
|
||||
}
|
||||
|
||||
const event_loop = &this.manager.event_loop;
|
||||
const event_loop = this.manager.event_loop;
|
||||
var process = spawned.toProcess(
|
||||
event_loop,
|
||||
false,
|
||||
|
||||
@@ -1073,6 +1073,45 @@ pub fn cleanWithLogger(
|
||||
return new;
|
||||
}
|
||||
|
||||
pub fn resolveWorkspaceFromNpmVersion(this: *const Lockfile, name_hash: PackageNameHash, version: *const Dependency.Version) ?PackageID {
|
||||
const workspace_path = if (this.workspace_paths.count() > 0) this.workspace_paths.get(name_hash) else null;
|
||||
const workspace_version = this.workspace_versions.get(name_hash);
|
||||
const buf = this.buffers.string_bytes.items;
|
||||
if ((workspace_version != null and version.value.npm.version.satisfies(workspace_version.?, buf, buf)) or
|
||||
// https://github.com/oven-sh/bun/pull/10899#issuecomment-2099609419
|
||||
// if the workspace doesn't have a version, it can still be used if
|
||||
// dependency version is wildcard
|
||||
(workspace_path != null and version.value.npm.version.@"is *"()))
|
||||
{
|
||||
const root_package = this.rootPackage() orelse return null;
|
||||
const root_dependencies = root_package.dependencies.get(this.buffers.dependencies.items);
|
||||
const root_resolutions = root_package.resolutions.get(this.buffers.resolutions.items);
|
||||
|
||||
for (root_dependencies, root_resolutions) |root_dep, workspace_package_id| {
|
||||
if (workspace_package_id != invalid_package_id and root_dep.version.tag == .workspace and root_dep.name_hash == name_hash) {
|
||||
return workspace_package_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn resolveWorkspaceFromNpmDistTag(this: *const Lockfile, name_hash: PackageNameHash) ?PackageID {
|
||||
const workspace_path = if (this.workspace_paths.count() > 0) this.workspace_paths.get(name_hash) else null;
|
||||
if (workspace_path != null) {
|
||||
const root_package = this.rootPackage() orelse return null;
|
||||
const root_dependencies = root_package.dependencies.get(this.buffers.dependencies.items);
|
||||
const root_resolutions = root_package.resolutions.get(this.buffers.resolutions.items);
|
||||
|
||||
for (root_dependencies, root_resolutions) |root_dep, workspace_package_id| {
|
||||
if (workspace_package_id != invalid_package_id and root_dep.version.tag == .workspace and root_dep.name_hash == name_hash) {
|
||||
return workspace_package_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub const MetaHashFormatter = struct {
|
||||
meta_hash: *const MetaHash,
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ pub const PatchTask = struct {
|
||||
var out_name_and_version_hash: ?u64 = null;
|
||||
var out_patchfile_hash: ?u64 = null;
|
||||
manager.setPreinstallState(pkg.meta.id, manager.lockfile, .unknown);
|
||||
switch (manager.determinePreinstallState(pkg, manager.lockfile, &out_name_and_version_hash, &out_patchfile_hash)) {
|
||||
switch (manager.determinePreinstallState(&pkg, manager.lockfile, &out_name_and_version_hash, &out_patchfile_hash)) {
|
||||
.done => {
|
||||
// patched pkg in folder path, should now be handled by PackageInstall.install()
|
||||
debug("pkg: {s} done", .{pkg.name.slice(manager.lockfile.buffers.string_bytes.items)});
|
||||
|
||||
@@ -342,7 +342,10 @@ pub const Resolution = extern struct {
|
||||
}
|
||||
|
||||
pub fn canEnqueueInstallTask(this: Tag) bool {
|
||||
return this == .npm or this == .local_tarball or this == .remote_tarball or this == .git or this == .github;
|
||||
return switch (this) {
|
||||
.npm, .local_tarball, .remote_tarball, .git, .github, .gitlab => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -626,16 +626,21 @@ const BufferedReaderVTable = struct {
|
||||
}
|
||||
}.loop_fn;
|
||||
|
||||
const eventLoop_fn = &struct {
|
||||
pub fn eventLoop_fn(this: *anyopaque) JSC.EventLoopHandle {
|
||||
return JSC.EventLoopHandle.init(Type.eventLoop(@alignCast(@ptrCast(this))));
|
||||
const event_loop_fn = &struct {
|
||||
pub fn event_loop_fn(this: *anyopaque) JSC.EventLoopHandle {
|
||||
const result = Type.eventLoop(@alignCast(@ptrCast(this)));
|
||||
if (@TypeOf(result) == JSC.EventLoopHandle) {
|
||||
return result;
|
||||
}
|
||||
return JSC.EventLoopHandle.init(result);
|
||||
}
|
||||
}.eventLoop_fn;
|
||||
}.event_loop_fn;
|
||||
|
||||
return comptime &BufferedReaderVTable.Fn{
|
||||
.onReadChunk = if (@hasDecl(Type, "onReadChunk")) @ptrCast(&Type.onReadChunk) else null,
|
||||
.onReaderDone = @ptrCast(&Type.onReaderDone),
|
||||
.onReaderError = @ptrCast(&Type.onReaderError),
|
||||
.eventLoop = eventLoop_fn,
|
||||
.eventLoop = event_loop_fn,
|
||||
.loop = loop_fn,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1238,7 +1238,7 @@ pub fn spawnOpts(
|
||||
new_folder: []const u8,
|
||||
cwd: [:0]const u8,
|
||||
git: [:0]const u8,
|
||||
loop: *JSC.AnyEventLoop,
|
||||
loop: JSC.EventLoopHandle,
|
||||
) bun.spawn.sync.Options {
|
||||
const argv: []const []const u8 = brk: {
|
||||
const ARGV = &[_][:0]const u8{
|
||||
@@ -1287,10 +1287,7 @@ pub fn spawnOpts(
|
||||
.cwd = cwd,
|
||||
.envp = envp,
|
||||
.argv = argv,
|
||||
.windows = if (bun.Environment.isWindows) .{ .loop = switch (loop.*) {
|
||||
.js => |x| .{ .js = x },
|
||||
.mini => |*x| .{ .mini = x },
|
||||
} } else {},
|
||||
.windows = if (bun.Environment.isWindows) .{ .loop = loop } else {},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -399,7 +399,10 @@ pub const PendingResolution = struct {
|
||||
string_buf: []u8 = "",
|
||||
tag: Tag,
|
||||
|
||||
pub const List = std.MultiArrayList(PendingResolution);
|
||||
/// Only used for auto-install in bun.bundle_v2
|
||||
user_data: *anyopaque = undefined,
|
||||
|
||||
pub const List = bun.MultiArrayList(PendingResolution);
|
||||
|
||||
pub fn deinitListItems(list_: List, allocator: std.mem.Allocator) void {
|
||||
var list = list_;
|
||||
@@ -416,6 +419,7 @@ pub const PendingResolution = struct {
|
||||
|
||||
pub fn deinit(this: *PendingResolution, allocator: std.mem.Allocator) void {
|
||||
this.dependency.deinit();
|
||||
this.parse_tasks.deinit(allocator);
|
||||
allocator.free(this.string_buf);
|
||||
}
|
||||
|
||||
@@ -934,6 +938,30 @@ pub const Resolver = struct {
|
||||
return r.resolve(source_dir, import_path, kind);
|
||||
}
|
||||
|
||||
pub fn resolveWithFrameworkAndAutoInstall(r: *ThisResolver, source_dir: string, import_path: string, kind: ast.ImportKind) Result.Union {
|
||||
if (r.opts.framework) |f| {
|
||||
if (f.built_in_modules.get(import_path)) |mod| {
|
||||
switch (mod) {
|
||||
.code => {
|
||||
return .{
|
||||
.success = .{
|
||||
.import_kind = kind,
|
||||
.path_pair = .{ .primary = Fs.Path.initWithNamespace(import_path, "node") },
|
||||
.is_external = false,
|
||||
.module_type = .esm,
|
||||
.primary_side_effects_data = .no_side_effects__pure_data,
|
||||
},
|
||||
};
|
||||
},
|
||||
.import => |path| return r.resolveAndAutoInstall(r.fs.top_level_dir, path, .entry_point, r.opts.global_cache),
|
||||
}
|
||||
return .{};
|
||||
}
|
||||
}
|
||||
|
||||
return r.resolveAndAutoInstall(source_dir, import_path, kind, r.opts.global_cache);
|
||||
}
|
||||
|
||||
const ModuleTypeMap = bun.ComptimeStringMap(options.ModuleType, .{
|
||||
.{ ".mjs", options.ModuleType.esm },
|
||||
.{ ".mts", options.ModuleType.esm },
|
||||
|
||||
Reference in New Issue
Block a user