aboutsummaryrefslogtreecommitdiff
path: root/src/cli.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli.zig')
-rw-r--r--src/cli.zig260
1 files changed, 1 insertions, 259 deletions
diff --git a/src/cli.zig b/src/cli.zig
index 371e443af..51d22db45 100644
--- a/src/cli.zig
+++ b/src/cli.zig
@@ -36,6 +36,7 @@ const CreateCommand = @import("./cli/create_command.zig").CreateCommand;
const CreateListExamplesCommand = @import("./cli/create_command.zig").CreateListExamplesCommand;
const RunCommand = @import("./cli/run_command.zig").RunCommand;
const UpgradeCommand = @import("./cli/upgrade_command.zig").UpgradeCommand;
+const InstallCompletionsCommand = @import("./cli/install_completions_command.zig").InstallCompletionsCommand;
const ShellCompletions = @import("./cli/shell_completions.zig");
var start_time: i128 = undefined;
@@ -612,265 +613,6 @@ pub const Command = struct {
}
}
- pub const InstallCompletionsCommand = struct {
- pub fn testPath(completions_dir: string) !std.fs.Dir {}
- pub fn exec(allocator: *std.mem.Allocator) !void {
- var shell = ShellCompletions.Shell.unknown;
- if (std.os.getenv("SHELL")) |shell_name| {
- shell = ShellCompletions.Shell.fromEnv(@TypeOf(shell_name), shell_name);
- }
-
- switch (shell) {
- .bash => {
- Output.prettyErrorln("<r><red>error:<r> Bash completions aren't implemented yet, just zsh & fish. A PR is welcome!", .{});
- std.os.exit(1);
- },
- .unknown => {
- Output.prettyErrorln("<r><red>error:<r> Unknown or unsupported shell. Please set $SHELL to one of zsh, fish, or bash. To manually output completions, run this:\n bun getcompletes", .{});
- std.os.exit(1);
- },
- else => {},
- }
-
- var stdout = std.io.getStdOut();
-
- if (std.os.getenvZ("IS_BUN_AUTO_UPDATE") == null) {
- if (!stdout.isTty()) {
- try stdout.writeAll(shell.completions());
- std.os.exit(0);
- }
- }
-
- var completions_dir: string = "";
- var output_dir: std.fs.Dir = found: {
- var cwd_buf: [std.fs.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", .{});
- Output.flush();
- std.os.exit(1);
- };
-
- for (std.os.argv) |arg, i| {
- if (strings.eqlComptime(std.mem.span(arg), "completions")) {
- if (std.os.argv.len > i + 1) {
- const input = std.mem.span(std.os.argv[i + 1]);
-
- if (!std.fs.path.isAbsolute(input)) {
- completions_dir = resolve_path.joinAbs(
- cwd,
- .auto,
- input,
- );
- } else {
- completions_dir = input;
- }
-
- if (!std.fs.path.isAbsolute(completions_dir)) {
- Output.prettyErrorln("<r><red>error:<r> Please pass an absolute path. {s} is invalid", .{completions_dir});
- Output.flush();
- std.os.exit(1);
- }
-
- break :found std.fs.openDirAbsolute(completions_dir, .{
- .iterate = true,
- }) catch |err| {
- Output.prettyErrorln("<r><red>error:<r> accessing {s} errored {s}", .{ completions_dir, @errorName(err) });
- Output.flush();
- std.os.exit(1);
- };
- }
-
- break;
- }
- }
-
- switch (shell) {
- .fish => {
- if (std.os.getenvZ("XDG_CONFIG_HOME")) |config_dir| {
- outer: {
- var paths = [_]string{ std.mem.span(config_dir), "./fish/completions" };
- completions_dir = resolve_path.joinAbsString(cwd, &paths, .auto);
- break :found std.fs.openDirAbsolute(completions_dir, .{ .iterate = true }) catch |err| {
- break :outer;
- };
- }
- }
-
- if (std.os.getenvZ("XDG_DATA_HOME")) |data_dir| {
- outer: {
- var paths = [_]string{ std.mem.span(data_dir), "./fish/completions" };
- completions_dir = resolve_path.joinAbsString(cwd, &paths, .auto);
-
- break :found std.fs.openDirAbsolute(completions_dir, .{ .iterate = true }) catch |err| {
- break :outer;
- };
- }
- }
-
- if (std.os.getenvZ("HOME")) |home_dir| {
- outer: {
- var paths = [_]string{ std.mem.span(home_dir), "./.config/fish/completions" };
- completions_dir = resolve_path.joinAbsString(cwd, &paths, .auto);
- break :found std.fs.openDirAbsolute(completions_dir, .{ .iterate = true }) catch |err| {
- break :outer;
- };
- }
- }
-
- outer: {
- if (Environment.isMac) {
- if (!Environment.isAarch64) {
- // homebrew fish
- completions_dir = "/usr/local/share/fish/completions";
- break :found std.fs.openDirAbsoluteZ("/usr/local/share/fish/completions", .{ .iterate = true }) catch |err| {
- break :outer;
- };
- } else {
- // homebrew fish
- completions_dir = "/opt/homebrew/share/fish/completions";
- break :found std.fs.openDirAbsoluteZ("/opt/homebrew/share/fish/completions", .{ .iterate = true }) catch |err| {
- break :outer;
- };
- }
- }
- }
-
- outer: {
- completions_dir = "/etc/fish/completions";
- break :found std.fs.openDirAbsoluteZ("/etc/fish/completions", .{ .iterate = true }) catch break :outer;
- }
- },
- .zsh => {
- if (std.os.getenvZ("fpath")) |fpath| {
- var splitter = std.mem.split(u8, std.mem.span(fpath), " ");
-
- while (splitter.next()) |dir| {
- completions_dir = dir;
- break :found std.fs.openDirAbsolute(dir, .{ .iterate = true }) catch continue;
- }
- }
-
- if (std.os.getenvZ("XDG_DATA_HOME")) |data_dir| {
- outer: {
- var paths = [_]string{ std.mem.span(data_dir), "./zsh-completions" };
- completions_dir = resolve_path.joinAbsString(cwd, &paths, .auto);
-
- break :found std.fs.openDirAbsolute(completions_dir, .{ .iterate = true }) catch |err| {
- break :outer;
- };
- }
- }
-
- outer: {
- completions_dir = "/usr/local/share/zsh-completions";
- break :found std.fs.openDirAbsolute("/usr/local/share/zsh-completions", .{ .iterate = true }) catch |err| {
- break :outer;
- };
- }
-
- if (std.os.getenvZ("HOME")) |home_dir| {
- {
- outer: {
- var paths = [_]string{ std.mem.span(home_dir), "./.oh-my-zsh/completions" };
- completions_dir = resolve_path.joinAbsString(cwd, &paths, .auto);
- break :found std.fs.openDirAbsolute(completions_dir, .{ .iterate = true }) catch |err| {
- break :outer;
- };
- }
- }
- }
-
- {
- outer: {
- completions_dir = "/usr/local/share/zsh/site-functions";
- break :found std.fs.openDirAbsolute("/usr/local/share/zsh/site-functions", .{ .iterate = true }) catch |err| {
- break :outer;
- };
- }
- }
-
- outer: {
- if (Environment.isMac) {
- if (!Environment.isAarch64) {
- // homebrew zsh
- completions_dir = "/usr/local/share/zsh/completions";
- break :found std.fs.openDirAbsoluteZ("/usr/local/share/zsh/completions", .{ .iterate = true }) catch |err| {
- break :outer;
- };
- } else {
- // homebrew zsh
- completions_dir = "/opt/homebrew/share/zsh/completions";
- break :found std.fs.openDirAbsoluteZ("/opt/homebrew/share/zsh/completions", .{ .iterate = true }) catch |err| {
- break :outer;
- };
- }
- }
- }
- },
- .bash => {},
- else => unreachable,
- }
-
- Output.prettyErrorln(
- "<r><red>error:<r> Could not find a directory to install completions in.\n",
- .{},
- );
-
- if (shell == .zsh) {
- Output.prettyErrorln(
- "\nzsh tip: One of the directories in $fpath might work. If you use oh-my-zsh, try mkdir $HOME/.oh-my-zsh/completions; and bun completions again\n.",
- .{},
- );
- }
-
- Output.errorLn(
- "Please either pipe it:\n bun completions > /to/a/file\n\n Or pass a directory:\n\n bun completions /my/completions/dir\n",
- .{},
- );
- Output.flush();
- std.os.exit(1);
- };
-
- const filename = switch (shell) {
- .fish => "bun.fish",
- .zsh => "_bun",
- .bash => "_bun.bash",
- else => unreachable,
- };
-
- std.debug.assert(completions_dir.len > 0);
-
- var output_file = output_dir.createFileZ(filename, .{
- .truncate = true,
- }) catch |err| {
- Output.prettyErrorln("<r><red>error:<r> Could not open {s} for writing: {s}", .{
- filename,
- @errorName(err),
- });
- Output.flush();
- std.os.exit(1);
- };
-
- output_file.writeAll(shell.completions()) catch |err| {
- Output.prettyErrorln("<r><red>error:<r> Could not write to {s}: {s}", .{
- filename,
- @errorName(err),
- });
- Output.flush();
- std.os.exit(1);
- };
-
- output_file.close();
- output_dir.close();
-
- Output.prettyErrorln("<r><d>Installed completions to {s}/{s}<r>", .{
- completions_dir,
- filename,
- });
- Output.flush();
- }
- };
-
const default_completions_list = [_]string{
// "build",
"run",