const std = @import("std");
const fs = std.fs;
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 (std.io.getStdIn().isTty()) {
return null;
}
const input = try std.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();
}