SarthakMakhija/cli-craft
Command-line craftsmanship in Zig.
6527e132c2097a8044fc3679ad2dfbe14370ce7e.tar.gz
CliCraft is a a robust framework for building command-line interface (CLI) applications in Zig. It provides a structured and idiomatic way to define commands, subcommands, flags, and arguments, ensuring a robust and user-friendly experience.
Add cli-craft to your project's build.zig.zon
file via zig fetch
. You can specify a particular version or commit hash, for example, using the provided example which pins to a specific commit:
zig fetch https://github.com/SarthakMakhija/cli-craft/archive/7121ebb4f33ba2a471a46a0a41679c2f7b2ac0f6.tar.gz --save
In your project's build.zig
, you need to declare cli-craft as a dependency and then import its module into your executable, library, or test modules.
First, inside your build function load the dependency:
// Load the cli-craft dependency
const clicraft_dependency = b.dependency("cli_craft", .{});
const clicraft_module = clicraft_dependency.module("cli_craft");
Then, add cli_craft_module
as an import to your respective modules (e.g., for your executable and unit tests):
// For your executable (replace 'exe_module' with your actual module variable)
exe_module.addImport("cli_craft", clicraft_module);
// Similarly for your unit tests (replace 'lib_unit_tests' with your actual test runner variable)
lib_unit_tests.root_module.addImport("cli_craft", clicraft_module);
After these steps, you can use
const CliCraft = @import("cli_craft").CliCraft;
in your Zig source files.
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
var cliCraft = try CliCraft.init(.{ .allocator = gpa.allocator(), .error_options = .{
.writer = std.io.getStdErr().writer().any(),
}, .output_options = .{
.writer = std.io.getStdOut().writer().any(),
} });
defer cliCraft.deinit();
var command = try cliCraft.newParentCommand("arithmetic", "Performs arithmetic operations");
try command.setAliases(&[_]CommandAlias{"math"});
try registerSubCommandAdd(cliCraft, &command);
try cliCraft.addCommand(&command);
cliCraft.execute() catch {};
}
fn registerSubCommandAdd(cliCraft: CliCraft, command: *Command) !void {
const runnable = struct {
pub fn run(_: ParsedFlags, arguments: CommandFnArguments) anyerror!void {
var sum: u8 = 0;
for (arguments) |arg| {
sum += try std.fmt.parseInt(u8, arg, 10);
}
std.debug.print("Sum = {d} \n", .{sum});
return;
}
}.run;
var subcommand = try cliCraft.newExecutableCommand("add", "Adds N arguments", runnable);
try subcommand.setAliases(&[_]CommandAlias{"plus"});
try command.addSubcommand(&subcommand);
}
The examples are available here.
This project is built with Zig version 0.14.1.
cli-craft
performs early detection of potential flag conflicts between parent and child commands, ensuring a well-defined CLI structure.int64
, bool
, and string
types.-v
for --verbose
).--verbose
) and explicit (--verbose true
) boolean flag values.--verbose
) and explicit (--verbose true
) boolean flag values.--help
or -h
flag for each command and subcommand.--flag=value
syntax; only space-separated values (--flag value
) are accepted.-vpf
); each flag must be written separately (-v -p -f
).Contributions are welcome! Please feel free to open issues or submit pull requests.
This project is licensed under the MIT License - see the LICENSE file for details.