| 1 | const std = @import("std"); |
| 2 | const string = []const u8; |
| 3 | const builtin = @import("builtin"); |
| 4 | pub const build_options = @import("build_options"); |
| 5 | const zigmod = @import("zigmod"); |
| 6 | const win32 = @import("win32"); |
| 7 | const nio = @import("nio"); |
| 8 | const nfs = @import("nfs"); |
| 9 | |
| 10 | // |
| 11 | // |
| 12 | |
| 13 | pub const std_options: std.Options = .{ |
| 14 | .log_level = std.log.Level.debug, |
| 15 | }; |
| 16 | |
| 17 | pub var io: std.Io = undefined; |
| 18 | pub var environ: *const std.process.Environ.Map = undefined; |
| 19 | |
| 20 | pub fn main(init: std.process.Init.Minimal) !void { |
| 21 | const gpa = std.heap.c_allocator; |
| 22 | environ = &try init.environ.createMap(gpa); |
| 23 | |
| 24 | var threaded: std.Io.Threaded = .init(gpa, .{ .environ = init.environ }); |
| 25 | defer threaded.deinit(); |
| 26 | io = threaded.io(); |
| 27 | |
| 28 | const proc_args = try init.args.toSlice(gpa); |
| 29 | const args = proc_args[1..]; |
| 30 | const self_path = try std.process.executablePathAlloc(io, gpa); |
| 31 | |
| 32 | if (args.len == 0) { |
| 33 | std.debug.print("zigmod {s} {s} {s} {s}\n", .{ |
| 34 | build_options.version, |
| 35 | @tagName(builtin.os.tag), |
| 36 | @tagName(builtin.cpu.arch), |
| 37 | @tagName(builtin.abi), |
| 38 | }); |
| 39 | std.debug.print("\n", .{}); |
| 40 | std.debug.print("The commands available are:\n", .{}); |
| 41 | inline for (comptime std.meta.declarations(zigmod.commands)) |decl| { |
| 42 | std.debug.print(" - {s}\n", .{decl.name}); |
| 43 | } |
| 44 | return; |
| 45 | } |
| 46 | |
| 47 | if (builtin.os.tag == .windows) { |
| 48 | const console = win32.system.console; |
| 49 | const h_out = console.GetStdHandle(console.STD_OUTPUT_HANDLE); |
| 50 | _ = console.SetConsoleMode(h_out, console.CONSOLE_MODE{ |
| 51 | .ENABLE_PROCESSED_INPUT = 1, //ENABLE_PROCESSED_OUTPUT |
| 52 | .ENABLE_LINE_INPUT = 1, //ENABLE_WRAP_AT_EOL_OUTPUT |
| 53 | .ENABLE_ECHO_INPUT = 1, //ENABLE_VIRTUAL_TERMINAL_PROCESSING |
| 54 | }); |
| 55 | } |
| 56 | |
| 57 | try zigmod.init(); |
| 58 | defer zigmod.deinit(); |
| 59 | |
| 60 | inline for (comptime std.meta.declarations(zigmod.commands)) |decl| { |
| 61 | if (std.mem.eql(u8, args[0], decl.name)) { |
| 62 | const cmd = @field(zigmod.commands, decl.name); |
| 63 | try cmd.execute(self_path, args[1..]); |
| 64 | return; |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | var sub_cmd_args = std.array_list.Managed(string).init(gpa); |
| 69 | try sub_cmd_args.append(try nio.fmt.allocPrint(gpa, "zigmod-{s}", .{args[0]})); |
| 70 | for (args[1..]) |item| { |
| 71 | try sub_cmd_args.append(item); |
| 72 | } |
| 73 | const result = std.process.run(gpa, io, .{ .argv = sub_cmd_args.items }) catch |e| switch (e) { |
| 74 | else => |ee| return ee, |
| 75 | error.FileNotFound => { |
| 76 | fail("unknown command \"{s}\" for \"zigmod\"", .{args[0]}); |
| 77 | }, |
| 78 | }; |
| 79 | try nfs.stdout().writeAll(result.stdout); |
| 80 | try nfs.stderr().writeAll(result.stderr); |
| 81 | } |
| 82 | |
| 83 | // |
| 84 | // |
| 85 | |
| 86 | const ansi_red = "\x1B[31m"; |
| 87 | const ansi_reset = "\x1B[39m"; |
| 88 | |
| 89 | pub fn assert(ok: bool, comptime fmt: string, args: anytype) void { |
| 90 | if (!ok) { |
| 91 | std.debug.print(ansi_red ++ fmt ++ ansi_reset ++ "\n", args); |
| 92 | std.process.exit(1); |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | pub fn fail(comptime fmt: string, args: anytype) noreturn { |
| 97 | assert(false, fmt, args); |
| 98 | unreachable; |
| 99 | } |