╭ main.zig ─────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
1 const std = @import("std"); 2 const builtin = @import("builtin"); 3 const xit = @import("xit"); 4 const rp = xit.repo; 5 const cmd = @import("./command.zig"); 6 const srv = @import("./serve.zig"); 7 const ssh = @import("./ssh_git.zig"); 8 const ssh_tui = @import("./ssh_tui.zig"); 9 10 pub const RunOpts = struct { 11 out: *std.Io.Writer, 12 err: *std.Io.Writer, 13 environ_map: *std.process.Environ.Map, 14 }; 15 16 pub fn main(init: std.process.Init) !u8 { 17 var debug_allocator: std.heap.DebugAllocator(.{}) = .init; 18 const allocator = if (builtin.mode == .Debug) debug_allocator.allocator() else std.heap.smp_allocator; 19 defer if (builtin.mode == .Debug) { 20 _ = debug_allocator.deinit(); 21 }; 22 23 var threaded = std.Io.Threaded.init(allocator, .{ 24 .environ = init.minimal.environ, 25 }); 26 defer threaded.deinit(); 27 const io = threaded.io(); 28 29 var args: std.ArrayList([]const u8) = .empty; 30 defer args.deinit(allocator); 31 32 var arg_it = try init.minimal.args.iterateAllocator(allocator); 33 defer arg_it.deinit(); 34 _ = arg_it.skip(); 35 while (arg_it.next()) |arg| { 36 try args.append(allocator, arg); 37 } 38 39 var stdout_writer = std.Io.File.stdout().writer(io, &.{}); 40 var stderr_writer = std.Io.File.stderr().writer(io, &.{}); 41 const run_opts = RunOpts{ .out = &stdout_writer.interface, .err = &stderr_writer.interface, .environ_map = init.environ_map }; 42 43 const cwd_path = try std.process.currentPathAlloc(io, allocator); 44 defer allocator.free(cwd_path); 45 46 run(.xit, .{}, io, allocator, args.items, cwd_path, run_opts) catch |err| switch (err) { 47 error.HandledError => return 1, 48 else => |e| return e, 49 }; 50 51 return 0; 52 } 53 54 pub fn run( 55 comptime repo_kind: rp.RepoKind, 56 comptime any_repo_opts: rp.AnyRepoOpts(repo_kind), 57 io: std.Io, 58 allocator: std.mem.Allocator, 59 args: []const []const u8, 60 cwd_path: []const u8, 61 run_opts: RunOpts, 62 ) !void { 63 var cmd_args = try cmd.CommandArgs.init(allocator, args); 64 defer cmd_args.deinit(); 65 66 switch (try cmd.CommandDispatch.init(&cmd_args)) { 67 .invalid => |invalid| switch (invalid) { 68 .command => |command| { 69 try run_opts.err.print("\"{s}\" is not a valid command\n\n", .{command}); 70 try cmd.printHelp(null, run_opts.err); 71 return error.HandledError; 72 }, 73 .argument => |argument| { 74 try run_opts.err.print("\"{s}\" is not a valid argument\n\n", .{argument.value}); 75 try cmd.printHelp(argument.command, run_opts.err); 76 return error.HandledError; 77 }, 78 }, 79 .help => |cmd_kind_maybe| try cmd.printHelp(cmd_kind_maybe, run_opts.out), 80 .cli => |cli_cmd| switch (cli_cmd) { 81 .serve => |options| try srv.run(repo_kind, any_repo_opts, io, allocator, cwd_path, options, run_opts.err, {}), 82 .ssh_git => |options| try ssh.run(io, allocator, options, run_opts.environ_map), 83 .ssh_tui => |options| try ssh_tui.run(io, allocator, options, run_opts.environ_map), 84 }, 85 } 86 } 87