storage and config: sqlite wrapper, migrations, querylog policy, repositories, zon config with import/export/check cli
This commit is contained in:
+41
-47
@@ -1,57 +1,51 @@
|
||||
//! The process shell: build the writers, collect `argv`, dispatch, return an
|
||||
//! exit code. Every command body lives in `cli.zig`, which takes its writers as
|
||||
//! parameters and is therefore testable without a process.
|
||||
|
||||
const std = @import("std");
|
||||
const version = @import("version.zig");
|
||||
const cli = @import("cli.zig");
|
||||
|
||||
const usage =
|
||||
\\usage: nxdns <command>
|
||||
\\
|
||||
\\commands:
|
||||
\\ run serve DNS
|
||||
\\ check validate the configuration
|
||||
\\ export write local records to stdout
|
||||
\\ import read local records from stdin
|
||||
\\ version print version information
|
||||
\\
|
||||
;
|
||||
|
||||
const exit_ok = 0;
|
||||
const exit_not_implemented = 2;
|
||||
const exit_usage = 64;
|
||||
// `src/tests.zig` imports this file, and this is how `cli.zig`'s tests reach
|
||||
// the same runner. `src/tests.zig` is the orchestrator's file, not this
|
||||
// session's.
|
||||
comptime {
|
||||
_ = @import("cli.zig");
|
||||
}
|
||||
|
||||
pub fn main(init: std.process.Init) u8 {
|
||||
// Both `File.Writer` values are self-referential and must not move, so they
|
||||
// stay in these `var` slots for the whole of `main`.
|
||||
var out_buffer: [4096]u8 = undefined;
|
||||
var err_buffer: [4096]u8 = undefined;
|
||||
var out = std.Io.File.stdout().writer(init.io, &out_buffer);
|
||||
var err = std.Io.File.stderr().writer(init.io, &err_buffer);
|
||||
|
||||
const runner: cli.Runner = .{
|
||||
.io = init.io,
|
||||
.gpa = init.gpa,
|
||||
.out = &out.interface,
|
||||
.err = &err.interface,
|
||||
};
|
||||
|
||||
var argv: std.ArrayList([]const u8) = .empty;
|
||||
defer argv.deinit(init.gpa);
|
||||
|
||||
var args = init.minimal.args.iterate();
|
||||
_ = args.skip();
|
||||
const command = args.next() orelse return fail(init.io, usage);
|
||||
|
||||
if (std.mem.eql(u8, command, "version")) {
|
||||
return print(init.io, "nxdns {s} ({s})\nzig {s}\n", .{
|
||||
version.string,
|
||||
version.git_commit,
|
||||
version.zig_version_string,
|
||||
});
|
||||
while (args.next()) |arg| {
|
||||
argv.append(init.gpa, arg) catch return cli.exit_runtime;
|
||||
}
|
||||
|
||||
for ([_][]const u8{ "run", "check", "export", "import" }) |known| {
|
||||
if (std.mem.eql(u8, command, known)) {
|
||||
_ = print(init.io, "not implemented\n", .{});
|
||||
return exit_not_implemented;
|
||||
}
|
||||
}
|
||||
const command = cli.parseArgs(argv.items) catch |e| return cli.runUsageError(runner, e);
|
||||
|
||||
return fail(init.io, usage);
|
||||
}
|
||||
|
||||
fn print(io: std.Io, comptime format: []const u8, arguments: anytype) u8 {
|
||||
var buffer: [512]u8 = undefined;
|
||||
var file_writer = std.Io.File.stdout().writer(io, &buffer);
|
||||
file_writer.interface.print(format, arguments) catch return 1;
|
||||
file_writer.interface.flush() catch return 1;
|
||||
return exit_ok;
|
||||
}
|
||||
|
||||
fn fail(io: std.Io, message: []const u8) u8 {
|
||||
var buffer: [512]u8 = undefined;
|
||||
var file_writer = std.Io.File.stderr().writer(io, &buffer);
|
||||
file_writer.interface.writeAll(message) catch {};
|
||||
file_writer.interface.flush() catch {};
|
||||
return exit_usage;
|
||||
return switch (command) {
|
||||
.run => |paths| cli.runRun(runner, paths),
|
||||
// `true`: the probe leaves the machine, which is right for an operator
|
||||
// running `nxdns check` and wrong for a test.
|
||||
.check => |args_| cli.runCheck(runner, args_, true),
|
||||
.export_ => |args_| cli.runExport(runner, args_),
|
||||
.import_ => |args_| cli.runImport(runner, args_),
|
||||
.version => cli.runVersion(runner),
|
||||
.help => cli.runHelp(runner),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user