~gpanders/wk

wk/src/main.zig -rw-r--r-- 2.2 KiB
4f358b1aGregory Anders Import std.io in main.zig a month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
const std = @import("std");
const fs = std.fs;
const io = std.io;
const mem = std.mem;
const os = std.os;
const warn = std.debug.warn;

const cmd = @import("cmd.zig");

pub fn main() anyerror!void {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();

    var allocator = &arena.allocator;

    const arglist = try std.process.argsAlloc(allocator);
    defer std.process.argsFree(allocator, arglist);

    if (arglist.len == 1) {
        cmd.printUsage(null);
        return;
    }

    const dir = if (os.getenv("WIKI_DIR")) |dir|
        try mem.dupe(allocator, u8, dir)
    else if (os.getenv("XDG_DATA_HOME")) |xdg_data_home|
        try fs.path.join(allocator, &[_][]const u8{ xdg_data_home, "wk" })
    else if (os.getenv("HOME")) |home|
        try fs.path.join(allocator, &[_][]const u8{ home, ".local", "share", "wk" })
    else
        unreachable; // $HOME should always be defined

    try fs.cwd().makePath(dir);
    try std.process.changeCurDir(dir);

    const command = arglist[1];
    var args: ?[]const []const u8 = if (arglist.len > 2 and !mem.eql(u8, arglist[2], "-"))
        arglist[2..]
    else
        try readFromStdin(allocator);

    cmd.handleCommand(allocator, command, args) catch |err| return switch (err) {
        error.UnknownCommand => {
            warn("Use \"wk help\" for usage.\n", .{});
            std.process.exit(1);
        },
        error.MissingRequiredArgument => {
            warn("Error: missing required argument\n\n", .{});
            warn("Use \"wk help\" for usage.\n", .{});
            std.process.exit(1);
        },
        error.CommandFailed, error.NoMatches => {
            std.process.exit(1);
        },
        else => return err,
    };
}

fn readFromStdin(allocator: *mem.Allocator) !?[]const []const u8 {
    if (io.getStdIn().isTty()) {
        return null;
    }

    const input = try io.getStdIn().inStream().readAllAlloc(allocator, 1 * 1024 * 1024);

    var args = std.ArrayList([]const u8).init(allocator);

    var it = mem.split(input, "\n");
    while (it.next()) |line| {
        if (line.len == 0) continue;
        const arg = try mem.dupe(allocator, u8, line);
        try args.append(arg);
    }

    return args.toOwnedSlice();
}