Changes
5 changed files (+173/-3)
-
-
@@ -26,6 +26,12 @@ pub fn build(b: *std.Build) void {const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const clap = clap: { const dep = b.dependency("clap", .{}); break :clap dep.module("clap"); }; const core = core: { const dep = b.dependency("plac_core", .{ .target = target,
-
@@ -47,6 +53,7 @@ }),}); exe.root_module.addImport("core", core); exe.root_module.addImport("clap", clap); b.installArtifact(exe); }
-
-
-
@@ -22,6 +22,10 @@ .dependencies = .{.plac_core = .{ .path = "../core", }, .clap = .{ .url = "https://github.com/Hejsil/zig-clap/archive/refs/tags/0.10.0.tar.gz", .hash = "clap-0.10.0-oBajB434AQBDh-Ei3YtoKIRxZacVPF1iSwp3IX_ZB8f0", }, }, .paths = .{ "build.zig",
-
-
-
@@ -0,0 +1,70 @@// Copyright 2025 Shota FUJI // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 const std = @import("std"); const clap = @import("clap"); const core = @import("core"); const exit = @import("../exit.zig").exit; const Commands = enum { list, }; const parser = .{ .command = clap.parsers.enumeration(Commands), .sec = clap.parsers.int(u32, 10), }; const params = clap.parseParamsComptime( \\-h, --help Prints this message to stdout and exits. \\-r, --retry <sec> Retry interval for sending request. \\-t, --timeout <sec> Exits after <sec>. \\<command> \\Available commands: \\* list ... List available Roon Server on network \\ ); pub fn run(allocator: std.mem.Allocator, iter: *std.process.ArgIterator) !void { var diag = clap.Diagnostic{}; var res = clap.parseEx(clap.Help, ¶ms, parser, iter, .{ .diagnostic = &diag, .allocator = allocator, .terminating_positional = 0, }) catch |err| { diag.report(std.io.getStdErr().writer(), err) catch {}; return err; }; defer res.deinit(); if (res.args.help > 0) { clap.help(std.io.getStdOut().writer(), clap.Help, ¶ms, .{}) catch {}; exit(.ok); } const command = res.positionals[0] orelse { clap.help(std.io.getStdErr().writer(), clap.Help, ¶ms, .{}) catch {}; exit(.incorrect_usage); }; switch (command) { .list => { std.debug.print("Not implemented (adder={})\n", .{core.adder(1, 2)}); exit(.not_ok); }, } }
-
-
cli/src/exit.zig (new)
-
@@ -0,0 +1,27 @@// Copyright 2025 Shota FUJI // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 const std = @import("std"); pub const ExitCode = enum(u8) { ok = 0, not_ok = 1, incorrect_usage = 2, }; pub fn exit(code: ExitCode) noreturn { std.process.exit(@intFromEnum(code)); }
-
-
-
@@ -15,8 +15,70 @@ //// SPDX-License-Identifier: Apache-2.0 const std = @import("std"); const core = @import("core"); const clap = @import("clap"); const exit = @import("./exit.zig").exit; const server = @import("./commands/server.zig"); const version = "0.0.0"; const Commands = enum { server, version, }; pub fn main() void { std.debug.print("Hello, {}!\n", .{core.adder(1, 2)}); const global_parser = .{ .command = clap.parsers.enumeration(Commands), }; const global_params = clap.parseParamsComptime( \\-h, --help Prints this message to stdout and exits. \\-v, --verbose Enables debug logging. \\<command> \\Available commands: \\* version ... Prints version to stdout and exits. \\* server ... Lists or gets information of Roon Server on network \\ ); pub fn main() !void { var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); const allocator = arena.allocator(); var iter = try std.process.ArgIterator.initWithAllocator(allocator); defer iter.deinit(); // Skip process name. _ = iter.next(); var diag = clap.Diagnostic{}; var res = clap.parseEx(clap.Help, &global_params, global_parser, &iter, .{ .diagnostic = &diag, .allocator = allocator, .terminating_positional = 0, }) catch |err| { diag.report(std.io.getStdErr().writer(), err) catch {}; exit(.incorrect_usage); }; defer res.deinit(); if (res.args.help > 0) { clap.help(std.io.getStdOut().writer(), clap.Help, &global_params, .{}) catch {}; exit(.ok); } const command = res.positionals[0] orelse { clap.help(std.io.getStdErr().writer(), clap.Help, &global_params, .{}) catch {}; exit(.incorrect_usage); }; switch (command) { .server => try server.run(allocator, &iter), .version => { try std.fmt.format(std.io.getStdOut().writer(), "{s}\n", .{version}); exit(.ok); }, } }
-