aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-12-21 00:58:14 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-12-21 00:58:14 -0800
commitf6bbfa7e404ec21f5aa3f60fabbd4a290a3b379d (patch)
treebef0f317d0be86246d216a314ad710af5e0b5fae
parent435fdbfddccdfe18573ab28a5ba82a8d272f31fb (diff)
downloadbun-f6bbfa7e404ec21f5aa3f60fabbd4a290a3b379d.tar.gz
bun-f6bbfa7e404ec21f5aa3f60fabbd4a290a3b379d.tar.zst
bun-f6bbfa7e404ec21f5aa3f60fabbd4a290a3b379d.zip
[bunx] Install symlink with completions
@colinhacks lmk if you have ideas where else it should attempt to isntall: 1) same dir as `bun` 2) $BUN_INSTALL/bin/bunx 3) $HOME/.bun/bin/bunx 4) $HOME/.local/bin/bunx
Diffstat (limited to '')
-rw-r--r--src/cli/install_completions_command.zig75
1 files changed, 65 insertions, 10 deletions
diff --git a/src/cli/install_completions_command.zig b/src/cli/install_completions_command.zig
index 0cbb2a744..3b8206a33 100644
--- a/src/cli/install_completions_command.zig
+++ b/src/cli/install_completions_command.zig
@@ -43,14 +43,77 @@ const ShellCompletions = @import("./shell_completions.zig");
pub const InstallCompletionsCommand = struct {
pub fn testPath(_: string) !std.fs.Dir {}
+
+ fn installBunxSymlink(allocator: std.mem.Allocator, cwd: []const u8) !void {
+ var buf: [bun.MAX_PATH_BYTES]u8 = undefined;
+ const bunx_name = if (Environment.isDebug) "bunx-debug" else "bunx";
+
+ // don't install it if it's already there
+ if (bun.which(&buf, bun.getenvZ("PATH") orelse cwd, cwd, bunx_name) != null)
+ return;
+
+ // first try installing the symlink into the same directory as the bun executable
+ var exe = try std.fs.selfExePathAlloc(allocator);
+ var target_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
+ var target = std.fmt.bufPrint(&target_buf, "{s}/" ++ bunx_name, .{std.fs.path.dirname(exe).?}) catch unreachable;
+ std.os.symlink(exe, target) catch {
+ outer: {
+ if (bun.getenvZ("BUN_INSTALL")) |install_dir| {
+ target = std.fmt.bufPrint(&target_buf, "{s}/bin/" ++ bunx_name, .{install_dir}) catch unreachable;
+ std.os.symlink(exe, target) catch break :outer;
+ return;
+ }
+ }
+
+ // if that fails, try $HOME/.bun/bin
+ outer: {
+ if (bun.getenvZ("HOME")) |home_dir| {
+ target = std.fmt.bufPrint(&target_buf, "{s}/.bun/bin/" ++ bunx_name, .{home_dir}) catch unreachable;
+ std.os.symlink(exe, target) catch break :outer;
+ return;
+ }
+ }
+
+ // if that fails, try $HOME/.local/bin
+ outer: {
+ if (bun.getenvZ("HOME")) |home_dir| {
+ target = std.fmt.bufPrint(&target_buf, "{s}/.local/bin/" ++ bunx_name, .{home_dir}) catch unreachable;
+ std.os.symlink(exe, target) catch break :outer;
+ return;
+ }
+ }
+
+ // otherwise...give up?
+
+ };
+ }
+
pub fn exec(allocator: std.mem.Allocator) !void {
+ // Fail silently on auto-update.
+ const fail_exit_code: u8 = if (bun.getenvZ("IS_BUN_AUTO_UPDATE") == null) 1 else 0;
+
+ var cwd_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
+ var stdout = std.io.getStdOut();
+
var shell = ShellCompletions.Shell.unknown;
if (bun.getenvZ("SHELL")) |shell_name| {
shell = ShellCompletions.Shell.fromEnv(@TypeOf(shell_name), shell_name);
}
- // Fail silently on auto-update.
- const fail_exit_code: u8 = if (bun.getenvZ("IS_BUN_AUTO_UPDATE") == null) 1 else 0;
+ var cwd = std.os.getcwd(&cwd_buf) catch {
+ // don't fail on this if we don't actually need to
+ if (fail_exit_code == 1) {
+ if (!stdout.isTty()) {
+ try stdout.writeAll(shell.completions());
+ Global.exit(0);
+ }
+ }
+
+ Output.prettyErrorln("<r><red>error<r>: Could not get current working directory", .{});
+ Global.exit(fail_exit_code);
+ };
+
+ installBunxSymlink(allocator, cwd) catch {};
switch (shell) {
.unknown => {
@@ -60,8 +123,6 @@ pub const InstallCompletionsCommand = struct {
else => {},
}
- var stdout = std.io.getStdOut();
-
if (bun.getenvZ("IS_BUN_AUTO_UPDATE") == null) {
if (!stdout.isTty()) {
try stdout.writeAll(shell.completions());
@@ -71,12 +132,6 @@ pub const InstallCompletionsCommand = struct {
var completions_dir: string = "";
var output_dir: std.fs.Dir = found: {
- var cwd_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
- var cwd = std.os.getcwd(&cwd_buf) catch {
- Output.prettyErrorln("<r><red>error<r>: Could not get current working directory", .{});
- Global.exit(fail_exit_code);
- };
-
for (std.os.argv) |arg, i| {
if (strings.eqlComptime(std.mem.span(arg), "completions")) {
if (std.os.argv.len > i + 1) {