diff options
| author | 2022-12-21 00:58:14 -0800 | |
|---|---|---|
| committer | 2022-12-21 00:58:14 -0800 | |
| commit | f6bbfa7e404ec21f5aa3f60fabbd4a290a3b379d (patch) | |
| tree | bef0f317d0be86246d216a314ad710af5e0b5fae | |
| parent | 435fdbfddccdfe18573ab28a5ba82a8d272f31fb (diff) | |
| download | bun-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.zig | 75 |
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) { |
