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