diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cli.zig | 2 | ||||
-rw-r--r-- | src/cli/install.sh | 10 | ||||
-rw-r--r-- | src/cli/upgrade_command.zig | 169 | ||||
-rw-r--r-- | src/http.zig | 6 | ||||
-rw-r--r-- | src/http_client_async.zig | 2 | ||||
-rw-r--r-- | src/install/install.zig | 56 | ||||
-rw-r--r-- | src/runtime.footer.bun.js | 1 | ||||
-rw-r--r-- | src/string_immutable.zig | 2 |
8 files changed, 215 insertions, 33 deletions
diff --git a/src/cli.zig b/src/cli.zig index 7bdf75dbb..e849d258f 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -55,7 +55,7 @@ const UpgradeCommand = @import("./cli/upgrade_command.zig").UpgradeCommand; const MacroMap = @import("./resolver/package_json.zig").MacroMap; const Reporter = @import("./report.zig"); -var start_time: i128 = undefined; +pub var start_time: i128 = undefined; const Bunfig = @import("./bunfig.zig").Bunfig; pub const Cli = struct { diff --git a/src/cli/install.sh b/src/cli/install.sh index 48ec15660..43f63264c 100644 --- a/src/cli/install.sh +++ b/src/cli/install.sh @@ -29,7 +29,7 @@ if [[ -t 1 ]]; then # Bold Bold_Green='\033[1;32m' # Bold Green - Bold_White='\033[1;37m' # Bold White + Bold_White='\033[1m' # Bold White fi error() { @@ -205,10 +205,12 @@ zsh) esac echo -echo -e "To get started, run:$Bold_White" +echo -e "To get started, run:" +echo if [[ $refresh_command ]]; then - echo -e " $refresh_command" + echo -e "$Bold_White $refresh_command$Color_Off" fi -echo -e " bun --help$Color_Off" +echo -e " $Bold_White bun --help$Color_Off" + diff --git a/src/cli/upgrade_command.zig b/src/cli/upgrade_command.zig index a28749849..fd101d775 100644 --- a/src/cli/upgrade_command.zig +++ b/src/cli/upgrade_command.zig @@ -56,11 +56,28 @@ pub const Version = struct { size: u32 = 0, pub fn name(this: Version) ?string { - if (this.tag.len > "bun-v".len and strings.eqlComptime(this.tag[0.."bun-v".len], "bun-v")) { - return this.tag[("bun-v".len)..]; - } else { - return null; + if (this.tag.len <= "bun-v".len or !strings.hasPrefixComptime(this.tag, "bun-v")) { + if (strings.eqlComptime(this.tag, "canary")) { + const Cli = @import("../cli.zig"); + + return std.fmt.allocPrint( + bun.default_allocator, + "bun-canary-timestamp-{any}", + .{ + std.fmt.fmtSliceHexLower( + std.mem.asBytes( + &bun.hash( + std.mem.asBytes(&Cli.start_time), + ), + ), + ), + }, + ) catch unreachable; + } + return this.tag; } + + return this.tag["bun-v".len..]; } pub const platform_label = if (Environment.isMac) "darwin" else "linux"; @@ -80,7 +97,10 @@ pub const Version = struct { pub const UpgradeCheckerThread = struct { var update_checker_thread: std.Thread = undefined; pub fn spawn(env_loader: *DotEnv.Loader) void { - if (env_loader.map.get("BUN_DISABLE_UPGRADE_CHECK") != null or env_loader.map.get("CI") != null) return; + if (env_loader.map.get("BUN_DISABLE_UPGRADE_CHECK") != null or + env_loader.map.get("CI") != null or + strings.eqlComptime(env_loader.get("BUN_CANARY") orelse "0", "1")) + return; update_checker_thread = std.Thread.spawn(.{}, run, .{env_loader}) catch return; update_checker_thread.detach(); } @@ -353,12 +373,14 @@ pub const UpgradeCommand = struct { break :brk DotEnv.Loader.init(map, ctx.allocator); }; - env_loader.loadProcess(); var version: Version = undefined; + const use_canary = strings.eqlComptime(env_loader.map.get("BUN_CANARY") orelse "0", "1") or + // TODO: add separate args just for "bun upgrade"? + strings.containsAny(bun.span(std.os.argv), "--canary"); - { + if (!use_canary) { var refresher = std.Progress{}; var progress = refresher.start("Fetching version tags", 0); @@ -384,12 +406,19 @@ pub const UpgradeCommand = struct { ); Global.exit(1); } - } - { Output.prettyErrorln("<r><b>bun <cyan>v{s}<r> is out<r>! You're on <blue>{s}<r>\n", .{ version.name().?, Global.package_json_version }); Output.flush(); + } else { + version = Version{ + .tag = "canary", + .zip_url = "https://github.com/oven-sh/bun/releases/download/canary/" ++ Version.zip_filename, + .size = 0, + .buf = MutableString.initEmpty(bun.default_allocator), + }; + } + { var refresher = std.Progress{}; var progress = refresher.start("Downloading", version.size); refresher.refresh(); @@ -413,7 +442,22 @@ pub const UpgradeCommand = struct { const response = try async_http.sendSync(true); switch (response.status_code) { - 404 => return error.HTTP404, + 404 => { + if (use_canary) { + Output.prettyErrorln( + \\<r><red>error:<r> Canary builds are not available for this platform yet + \\ + \\ Release: <cyan>https://github.com/oven-sh/bun/releases/tag/canary<r> + \\ Filename: <b>{s}<r> + \\ + , .{ + Version.zip_filename, + }); + Global.exit(1); + } + + return error.HTTP404; + }, 403 => return error.HTTPForbidden, 429 => return error.HTTPTooManyRequests, 499...599 => return error.GitHubIsDown, @@ -503,7 +547,6 @@ pub const UpgradeCommand = struct { Global.exit(1); } } - { var verify_argv = [_]string{ exe_subpath, @@ -527,17 +570,21 @@ pub const UpgradeCommand = struct { Global.exit(1); } - if (!strings.eql(std.mem.trim(u8, result.stdout, " \n\r\t"), version_name)) { - save_dir_.deleteTree(version_name) catch {}; - - Output.prettyErrorln( - "<r><red>error<r>: The downloaded version of bun (<red>{s}<r>) doesn't match the expected version (<b>{s}<r>)<r>. Cancelled upgrade", - .{ - result.stdout[0..@minimum(result.stdout.len, 128)], - version_name, - }, - ); - Global.exit(1); + // It should run successfully + // but we don't care about the version number if we're doing a canary build + if (!use_canary) { + if (!strings.eql(std.mem.trim(u8, result.stdout, " \n\r\t"), version_name)) { + save_dir_.deleteTree(version_name) catch {}; + + Output.prettyErrorln( + "<r><red>error<r>: The downloaded version of bun (<red>{s}<r>) doesn't match the expected version (<b>{s}<r>)<r>. Cancelled upgrade", + .{ + result.stdout[0..@minimum(result.stdout.len, 128)], + version_name, + }, + ); + Global.exit(1); + } } } @@ -556,6 +603,47 @@ pub const UpgradeCommand = struct { Global.exit(1); }; + if (use_canary) { + + // Check if the versions are the same + const target_stat = target_dir.statFile(target_filename) catch |err| { + save_dir_.deleteTree(version_name) catch {}; + Output.prettyErrorln("<r><red>error:<r> Failed to stat target bun {s}", .{@errorName(err)}); + Global.exit(1); + }; + + const dest_stat = save_dir.statFile(exe_subpath) catch |err| { + save_dir_.deleteTree(version_name) catch {}; + Output.prettyErrorln("<r><red>error:<r> Failed to stat source bun {s}", .{@errorName(err)}); + Global.exit(1); + }; + + if (target_stat.size == dest_stat.size and target_stat.size > 0) { + var input_buf = try ctx.allocator.alloc(u8, target_stat.size); + + const target_hash = std.hash.Wyhash.hash(0, target_dir.readFile(target_filename, input_buf) catch |err| { + save_dir_.deleteTree(version_name) catch {}; + Output.prettyErrorln("<r><red>error:<r> Failed to read target bun {s}", .{@errorName(err)}); + Global.exit(1); + }); + + const source_hash = std.hash.Wyhash.hash(0, save_dir.readFile(exe_subpath, input_buf) catch |err| { + save_dir_.deleteTree(version_name) catch {}; + Output.prettyErrorln("<r><red>error:<r> Failed to read source bun {s}", .{@errorName(err)}); + Global.exit(1); + }); + + if (target_hash == source_hash) { + save_dir_.deleteTree(version_name) catch {}; + Output.prettyErrorln( + "<r><green>Congrats!<r> You're already on the latest canary build of bun", + .{}, + ); + Global.exit(0); + } + } + } + if (env_loader.map.get("BUN_DRY_RUN") == null) { C.moveFileZ(save_dir.fd, exe_subpath, target_dir.fd, target_filename) catch |err| { save_dir_.deleteTree(version_name) catch {}; @@ -584,7 +672,42 @@ pub const UpgradeCommand = struct { Output.printStartEnd(ctx.start_time, std.time.nanoTimestamp()); - Output.prettyErrorln("<r> Upgraded.\n\n<b><green>Welcome to bun v{s}!<r>\n\n Report any bugs:\n https://github.com/oven-sh/bun/issues\n\n What's new:\n https://github.com/oven-sh/bun/releases/tag/{s}<r>", .{ version_name, version.tag }); + if (use_canary) { + Output.prettyErrorln( + \\<r> Upgraded. + \\ + \\<b><green>Welcome to bun's latest canary build!<r> + \\ + \\Report any bugs: + \\ + \\ https://github.com/oven-sh/bun/issues + \\ + \\What's new: + \\ + \\ <cyan>https://github.com/oven-sh/bun/releases/tag/{s}<r> + \\ + , + .{version.tag}, + ); + } else { + Output.prettyErrorln( + \\<r> Upgraded. + \\ + \\<b><green>Welcome to bun v{s}!<r> + \\ + \\Report any bugs: + \\ + \\ https://github.com/oven-sh/bun/issues + \\ + \\What's new: + \\ + \\ <cyan>https://github.com/oven-sh/bun/releases/tag/{s}<r> + \\ + , + .{ version_name, version.tag }, + ); + } + Output.flush(); return; } diff --git a/src/http.zig b/src/http.zig index 1515f976f..605bd1840 100644 --- a/src/http.zig +++ b/src/http.zig @@ -1881,9 +1881,9 @@ pub const RequestContext = struct { var reloader = Api.Reloader.disable; if (ctx.bundler.options.hot_module_reloading) { reloader = Api.Reloader.live; - // if (ctx.bundler.options.jsx.supports_fast_refresh) { - // reloader = Api.Reloader.fast_refresh; - // } + if (ctx.bundler.options.jsx.supports_fast_refresh and ctx.bundler.env.get("BUN_FORCE_HMR") != null) { + reloader = Api.Reloader.fast_refresh; + } } const welcome_message = Api.WebsocketMessageWelcome{ diff --git a/src/http_client_async.zig b/src/http_client_async.zig index 2da75b652..7b376c986 100644 --- a/src/http_client_async.zig +++ b/src/http_client_async.zig @@ -56,6 +56,8 @@ pub fn onThreadStart(_: ?*anyopaque) ?*anyopaque { \\ <cyan>wsl --update<r> \\ <cyan>wsl --shutdown<r> \\ + \\ Please make sure you're using WSL version 2 (not WSL 1). + \\ \\If that doesn't work (and you're on a Windows machine), try this: \\ 1. Open Windows Update \\ 2. Download any updates to Windows Subsystem for Linux diff --git a/src/install/install.zig b/src/install/install.zig index 8ae032022..7373cf90d 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -199,7 +199,61 @@ const NetworkTask = struct { scope: *const Npm.Registry.Scope, loaded_manifest: ?Npm.PackageManifest, ) !void { - this.url_buf = try std.fmt.allocPrint(allocator, "{s}://{s}/{s}/{s}", .{ scope.url.displayProtocol(), scope.url.displayHostname(), strings.trim(scope.url.path, "/"), name }); + const pathname: string = if (!strings.eqlComptime(scope.url.pathname, "/")) + scope.url.pathname + else + @as(string, ""); + + if (pathname.len > 0) { + if (scope.url.getPort()) |port_number| { + this.url_buf = try std.fmt.allocPrint( + allocator, + "{s}://{s}:{d}/{s}/{s}", + .{ + scope.url.displayProtocol(), + scope.url.displayHostname(), + port_number, + pathname, + name, + }, + ); + } else { + this.url_buf = try std.fmt.allocPrint( + allocator, + "{s}://{s}/{s}/{s}", + .{ + scope.url.displayProtocol(), + scope.url.displayHostname(), + pathname, + name, + }, + ); + } + } else { + if (scope.url.getPort()) |port_number| { + this.url_buf = try std.fmt.allocPrint( + allocator, + "{s}://{s}:{d}/{s}", + .{ + scope.url.displayProtocol(), + scope.url.displayHostname(), + port_number, + name, + }, + ); + } else { + this.url_buf = try std.fmt.allocPrint( + allocator, + "{s}://{s}/{s}", + .{ + scope.url.displayProtocol(), + scope.url.displayHostname(), + name, + }, + ); + } + } + var last_modified: string = ""; var etag: string = ""; if (loaded_manifest) |manifest| { diff --git a/src/runtime.footer.bun.js b/src/runtime.footer.bun.js index 72a2703e9..a5466f53a 100644 --- a/src/runtime.footer.bun.js +++ b/src/runtime.footer.bun.js @@ -22,5 +22,6 @@ export var __require = (globalThis.require ||= function (moduleId) { return BUN_RUNTIME.__require(moduleId); }); +__require.d ||= BUN_RUNTIME.__require.d; globalThis.__internalIsCommonJSNamespace ||= BUN_RUNTIME.__internalIsCommonJSNamespace; diff --git a/src/string_immutable.zig b/src/string_immutable.zig index ec3a2ecbe..801eacd51 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -78,7 +78,7 @@ pub inline fn containsComptime(self: string, comptime str: string) bool { pub const includes = contains; pub inline fn containsAny(in: anytype, target: string) bool { - for (in) |str| if (contains(str, target)) return true; + for (in) |str| if (contains(bun.span(str), target)) return true; return false; } |