aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md29
-rw-r--r--src/cli/upgrade_command.zig102
-rw-r--r--src/string_immutable.zig2
3 files changed, 113 insertions, 20 deletions
diff --git a/README.md b/README.md
index 6707162fe..791364a7c 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,5 @@
# bun
+
<p align="center">
<a href="https://bun.sh"><img src="https://bun.sh/logo@2x.png" alt="Logo"></a>
</p>
@@ -540,7 +541,7 @@ You can see [Bun's Roadmap](https://github.com/oven-sh/bun/issues/159), but here
| `@jsxPragma` comments | JS Transpiler |
| Sharing `.bun` files | bun |
| Dates & timestamps | TOML parser |
-| [Hash components for Fast Refresh](https://github.com/oven-sh/bun/issues/18) | JSX Transpiler |
+| [Hash components for Fast Refresh](https://github.com/oven-sh/bun/issues/18) | JSX Transpiler |
<small>
JS Transpiler == JavaScript Transpiler
@@ -929,24 +930,29 @@ To fix this issue:
3. Try again, and if that still doesn’t fix it, open an issue
### Unzip is required
+
Unzip is required to install bun on Linux. You can use one of the following commands to install `unzip`:
#### Debian / Ubuntu / Mint
+
```sh
sudo apt install unzip
```
#### RedHat / CentOS / Fedora
+
```sh
sudo dnf install unzip
```
#### Arch / Manjaro
+
```sh
sudo pacman -S unzip
```
#### OpenSUSE
+
```sh
sudo zypper install unzip
```
@@ -1571,6 +1577,26 @@ bun is distributed as a single binary file, so you can also do this manually:
- Unzip the folder
- Move the `bun` binary to `~/.bun/bin` (or anywhere)
+### Canary builds
+
+[Canary](https://github.com/oven-sh/bun/releases/tag/canary) builds are generated on every commit. At the time of writing, only Linux x64 &amp; Linux arm64 are generated.
+
+To install a [canary](https://github.com/oven-sh/bun/releases/tag/canary) build of bun, run:
+
+```bash
+bun upgrade --canary
+```
+
+This flag is not persistent (though that might change in the future). If you want to always run the canary build of bun, set the `BUN_CANARY` environment variable to `1` in your shell's startup script.
+
+This will download the release zip from https://github.com/oven-sh/bun/releases/tag/canary.
+
+To revert to the latest stable version of bun, run:
+
+```bash
+bun upgrade
+```
+
### `bun completions`
This command installs completions for `zsh` and/or `fish`. It runs automatically on every `bun upgrade` and on install. It reads from `$SHELL` to determine which shell to install for. It tries several common shell completion directories for your shell and OS.
@@ -3243,7 +3269,6 @@ You’ll want to make sure `zig` is in `$PATH`. The specific version of Zig expe
If you're building on a macOS device, you'll need to have a valid Developer Certificate, or else the code signing step will fail. To check if you have one, open the `Keychain Access` app, go to the `login` profile and search for `Apple Development`. You should have at least one certificate with a name like `Apple Development: user@example.com (WDYABC123)`. If you don't have one, follow [this guide](https://ioscodesigning.com/generating-code-signing-files/#generate-a-code-signing-certificate-using-xcode) to get one.
-
In `bun`:
```bash
diff --git a/src/cli/upgrade_command.zig b/src/cli/upgrade_command.zig
index a28749849..8e2946a68 100644
--- a/src/cli/upgrade_command.zig
+++ b/src/cli/upgrade_command.zig
@@ -353,12 +353,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 +386,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 +422,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 +527,6 @@ pub const UpgradeCommand = struct {
Global.exit(1);
}
}
-
{
var verify_argv = [_]string{
exe_subpath,
@@ -527,17 +550,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 +583,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 {};
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;
}