aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cli.zig2
-rw-r--r--src/cli/install.sh10
-rw-r--r--src/cli/upgrade_command.zig169
-rw-r--r--src/http.zig6
-rw-r--r--src/http_client_async.zig2
-rw-r--r--src/install/install.zig56
-rw-r--r--src/runtime.footer.bun.js1
-rw-r--r--src/string_immutable.zig2
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;
}