{"id":15099908,"url":"https://github.com/00jciv00/cova","last_synced_at":"2025-04-06T05:16:16.965Z","repository":{"id":160716569,"uuid":"635546664","full_name":"00JCIV00/cova","owner":"00JCIV00","description":"Commands, Options, Values, Arguments. A simple yet robust cross-platform command line argument parsing library for Zig.","archived":false,"fork":false,"pushed_at":"2025-03-25T22:39:38.000Z","size":69851,"stargazers_count":120,"open_issues_count":11,"forks_count":6,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-30T03:11:04.017Z","etag":null,"topics":["clap","cli","command-line","terminal","zig","zig-package","ziglang"],"latest_commit_sha":null,"homepage":"https://00jciv00.github.io/cova/","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/00JCIV00.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-02T23:42:13.000Z","updated_at":"2025-03-25T22:39:42.000Z","dependencies_parsed_at":"2023-09-24T11:38:41.096Z","dependency_job_id":"9254ca50-d042-467e-91b0-0de3d79ffdf0","html_url":"https://github.com/00JCIV00/cova","commit_stats":{"total_commits":293,"total_committers":2,"mean_commits":146.5,"dds":"0.12627986348122866","last_synced_commit":"894173ad41095b216f6faabb161022ba5c072cf6"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/00JCIV00%2Fcova","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/00JCIV00%2Fcova/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/00JCIV00%2Fcova/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/00JCIV00%2Fcova/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/00JCIV00","download_url":"https://codeload.github.com/00JCIV00/cova/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247436286,"owners_count":20938533,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clap","cli","command-line","terminal","zig","zig-package","ziglang"],"created_at":"2024-09-25T17:40:39.471Z","updated_at":"2025-04-06T05:16:16.666Z","avatar_url":"https://github.com/00JCIV00.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"![cova_icon_v2 1](https://github.com/00JCIV00/cova/assets/68087632/0b485f6b-ddf4-4772-96eb-899d4606f9cc)\n\n# Commands **⋅** Options **⋅** Values **⋅** Arguments \nA simple yet robust cross-platform command line argument parsing library for Zig.\n\n[![Static Badge](https://img.shields.io/badge/v0.14(nightly)-orange?logo=Zig\u0026logoColor=Orange\u0026label=Zig\u0026labelColor=Orange)](https://ziglang.org/download/)\n[![Static Badge](https://img.shields.io/badge/v0.10.1b-blue?logo=GitHub\u0026label=Release)](https://github.com/00JCIV00/cova/releases/tag/v0.10.1-beta)\n[![GitHub commit activity](https://img.shields.io/github/commits-difference/00JCIV00/cova?base=v0.10.1\u0026head=main\u0026logo=Github\u0026label=Commits%20(v0.11.0b))](https://github.com/00JCIV00/cova/commits/main/)\n[![Static Badge](https://img.shields.io/badge/MIT-silver?label=License)](https://github.com/00JCIV00/cova/blob/main/LICENSE)\n\n___\n\n## Overview\n`command --option value`\n\nCova is based on the idea that Arguments will fall into one of three types: Commands, Options, or Values. These Types are assembled into a single Command struct which is then used to parse argument tokens. Whether you're looking for simple argument parsing or want to create something as complex as the [`ip`](https://www.man7.org/linux/man-pages/man8/ip.8.html) or [`git`](https://www.man7.org/linux/man-pages/man1/git.1.html) commands, Cova makes it easy.\n\n## Get Started Quickly!\n- [Quick Start Guide](https://github.com/00JCIV00/cova/wiki/Getting-Started)\n- [Full Wiki Guide](https://github.com/00JCIV00/cova/wiki/)\n- [API Docs](https://00jciv00.github.io/cova/)\n\n### Quick Example\n[Logger Example](https://github.com/00JCIV00/cova/blob/main/examples/logger.zig)\n```shell\nlogger --log-level info\n```\n#### Set up a Command\n```zig\n// ...\npub const CommandT = cova.Command.Custom(.{...});\npub const setup_cmd: CommandT = .{\n    .name = \"logger\",\n    .description = \"A small demo of using the Log Level Enum as an Option.\",\n    .examples = \u0026.{ \"logger --log-level info\" },\n    .opts = \u0026.{\n        .{\n            .name = \"log_level\",\n            .description = \"An Option using the `log.Level` Enum.\",\n            .long_name = \"log-level\",\n            .mandatory = true,\n            .val = .ofType(log.Level, .{\n                .name = \"log_level_val\",\n                .description = \" This Value will handle the Enum.\"\n            })\n        }\n    },\n};\n```\n#### Parse the Command\n```zig\npub fn main() !void {\n    // ...\n    var main_cmd = try setup_cmd.init(alloc, .{});\n    defer main_cmd.deinit();\n    var args_iter = try cova.ArgIteratorGeneric.init(alloc);\n    defer args_iter.deinit();\n\n    cova.parseArgs(\u0026args_iter, CommandT, main_cmd, stdout, .{}) catch |err| switch (err) {\n        error.UsageHelpCalled =\u003e {},\n        else =\u003e return err,\n    };\n    // ...\n```\n#### Use the Data\n```zig\n    // ...\n    const main_opts = try main_cmd.getOpts(.{});\n    const log_lvl_opt = main_opts.get(\"log_level\").?;\n    const log_lvl = log_lvl_opt.val.getAs(log.Level) catch {\n        log.err(\"The provided Log Level was invalid.\", .{});\n        return;\n    };\n    log.info(\"Provided Log Level: {s}\", .{ @tagName(log_lvl) });\n}\n```\n\n## Features\n- **[Comptime Setup](#comptime-setup). [Runtime Use](#runtime-use).**\n  - Cova is designed to have Argument Types set up at ***compile time*** so they can be validated during each compilation, thus providing you with immediate feedback.\n  - Once validated, Argument Types are initialized to memory for ***runtime*** use where end user argument tokens are parsed then made ready to be analyzed by your code.\n- **[Build-time Bonuses!](#build-time-bonuses)** Cova also provides a simple build step to generate Help Docs, Tab Completion Scripts, and Argument Templates at ***build-time***!\n- **Simple Design:**\n  - All argument tokens are parsed to Argument Types: Commands, Options, or Values.\n    - Options = _Flags_ and Values = _Positional Arguments_\n  - These Argument Types can be *created from* or *converted to* your Structs, Unions, and Functions along with their corresponding Fields and Parameters.\n  - Default Arguments such as `usage` and `help` can be automatically added to all Commands easily. \n  - This design allows for **infinitely nestable** Commands, Options, and Values in a way that's simple to parse, analyze, and use in your projects.\n- **Multiplatform.** Tested across common architectures of Linux, Mac, and Windows.\n- **Granular, Robust Customization:**\n  - [POSIX Compliant](https://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html) by default, with plenty of ways to configure to **whatever standard you'd like**.\n    - Posix: `command --option option_string \"standalone value\" subcmd -i 42 --bool`\n    - Windows: `Your-Command -StringOption \"value\" -FileOption .\\user\\file\\path`\n  - Cova offers deep customization through the Argument Types and several Config Structs. These customizations all provide simple and predictable defaults, allowing you to only configure what you need.\n- [***And much more!***](https://github.com/00JCIV00/cova/wiki/Feature-List)\n\n## Usage\nCova makes it easy to set up your Argument Types at _comptime_ and use the input provided by your end users at _runtime_!\n\n### Comptime Setup\nThere are two main ways to set up your Argument Types. You can either convert existing Zig Types within your project or create them manually. You can even mix and match these techniques to get the best of both!\n\n\u003cdetails\u003e\n\u003csummary\u003eCode Example\u003c/summary\u003e\n\n```zig\nconst std = @import(\"std\");\nconst cova = @import(\"cova\");\npub const CommandT = cova.Command.Base();\npub const OptionT = CommandT.OptionT;\npub const ValueT = CommandT.ValueT;\n\n// The root Command for your program.\npub const setup_cmd: CommandT = .{\n    .name = \"basic-app\",\n    .description = \"A basic user management application designed to highlight key features of the Cova library.\",\n    .cmd_groups = \u0026.{ \"INTERACT\", \"VIEW\" },\n    .sub_cmds = \u0026.{\n        // A Sub Command created from converting a Struct named `User`.\n        // Usage Ex: `basic-app new -f Bruce -l Wayne -a 40 -p \"555 555 5555\" -A \" 1007 Mountain Drive, Gotham\" true`\n        .from(User, .{\n            .cmd_name = \"new\",\n            .cmd_description = \"Add a new user.\",\n            .cmd_group = \"INTERACT\",\n            .sub_descriptions = \u0026.{\n                .{ \"is_admin\", \"Add this user as an admin?\" },\n                .{ \"first_name\", \"User's First Name.\" }, \n                .{ \"last_name\", \"User's Last Name.\" },\n                .{ \"age\", \"User's Age.\" },\n                .{ \"phone\", \"User's Phone #.\" },\n                .{ \"address\", \"User's Address.\" },\n            },\n        }),\n        // A Sub Command created from a Function named `open`.\n        // Usage Ex: `basic-app open users.csv`\n        .from(@TypeOf(open), .{\n            .cmd_name = \"open\",\n            .cmd_description = \"Open or create a users file.\",\n            .cmd_group = \"INTERACT\",\n        }),\n        // A manually created Sub Command, same as the root `setup_cmd`.\n        // Usage Ex: `basic-app clean` or `basic-app delete --file users.csv`\n        .{\n            .name = \"clean\",\n            .description = \"Clean (delete) the default users file (users.csv) and persistent variable file (.ba_persist).\",\n            .alias_names = \u0026.{ \"delete\", \"wipe\" },\n            .cmd_group = \"INTERACT\",\n            .opts = \u0026.{\n                .{\n                    .name = \"clean_file\",\n                    .description = \"Specify a single file to be cleaned (deleted) instead of the defaults.\",\n                    .alias_long_names = \u0026.{ \"delete_file\" },\n                    .short_name = 'f',\n                    .long_name = \"file\",\n                    .val = .ofType([]const u8, .{\n                        .name = \"clean_file\",\n                        .description = \"The file to be cleaned.\",\n                        .alias_child_type = \"filepath\",\n                        .valid_fn = cova.Value.ValidationFns.validFilepath,\n                    }),\n                },\n            },\n        },\n    }\n};\n// Continue to Runtime Use...\n```\n\u003c/details\u003e\n\n### Runtime Use\nOnce Cova has parsed input from your end users, it puts that data into the Command you set up. \nYou can call various methods on the Command to use that data however you need.\n\n\u003cdetails\u003e\n\u003csummary\u003eCode Example\u003c/summary\u003e\n\n```zig\n// ...continued from the Comptime Setup.\npub fn main() !void {\n    const gpa: std.heap.DebugAllocator(.{}) = .init;\n    const alloc = gpa.allocator();\n\n    // Initializing the `setup_cmd` with an allocator will make it available for Runtime use.\n    const main_cmd = try setup_cmd.init(alloc, .{}); \n    defer main_cmd.deinit();\n\n    // Parsing\n    var args_iter = try cova.ArgIteratorGeneric.init(alloc);\n    defer args_iter.deinit();\n    const stdout = std.io.getStdOut().writer();\n\n    cova.parseArgs(\u0026args_iter, CommandT, main_cmd, stdout, .{}) catch |err| switch (err) {\n        error.UsageHelpCalled,\n        error.TooManyValues,\n        error.UnrecognizedArgument,\n        error.UnexpectedArgument,\n        error.CouldNotParseOption =\u003e {},\n        else =\u003e return err,\n    };\n\n    // Analysis (Using the data.)\n    if (builtin.mode == .Debug) try cova.utils.displayCmdInfo(CommandT, main_cmd, alloc, \u0026stdout);\n    \n    // Glossing over some project variables here.\n\n    // Convert a Command back into a Struct.\n    if (main_cmd.matchSubCmd(\"new\")) |new_cmd| {\n        var new_user = try new_cmd.to(User, .{});\n        new_user._id = getNextID();\n        try users.append(new_user);\n        try stdout.print(\"Added:\\n{s}\\n\", .{ new_user });\n    }\n    // Convert a Command back into a Function and call it.\n    if (main_cmd.matchSubCmd(\"open\")) |open_cmd| {\n        user_file = try open_cmd.callAs(open, null, std.fs.File);\n    }\n    // Get the provided sub Command and check an Option from that sub Command.\n    if (main_cmd.matchSubCmd(\"clean\")) |clean_cmd| cleanCmd: {\n        if ((try clean_cmd.getOpts(.{})).get(\"clean_file\")) |clean_opt| {\n            if (clean_opt.val.isSet()) {\n                const filename = try clean_opt.val.getAs([]const u8);\n                try delete(filename);\n                break :cleanCmd;\n            }\n        }\n        try delete(\"users.csv\");\n        try delete(\".ba_persist\");\n    }\n}\n```\n\u003c/details\u003e\n\n### More Examples\n- [logger](./examples/logger.zig): The simple example from the top of the README.\n- [basic-app](./examples/basic_app.zig): Where the above examples come from.\n- [covademo](./examples/covademo.zig): This is the testbed for Cova, but its a good demo of virtually every feature in the library.\n\n## Build-time Bonuses\nCova's simple Meta Doc Generator build step lets you quickly and easily generate documents in the following formats based on the Commands you set up at comptime:\n- Help Docs:\n  - Manpages\n  - Markdown\n- Tab Completion Scripts:\n  - Bash\n  - Zsh\n  - Powershell\n- Argument Templates:\n  - JSON\n  - KDL\n\n \u003cdetails\u003e\n\u003csummary\u003eCode Example\u003c/summary\u003e\n   \n```zig\n// Within 'build.zig'\npub fn build(b: *std.Build) void {\n    // Set up your build variables as normal.\n\n    const cova_dep = b.dependency(\"cova\", .{ .target = target, .optimize = optimize });\n    const cova_mod = cova_dep.module(\"cova\");\n\n    // Set up your exe step as you normally would.\n\n    const cova_gen = @import(\"cova\").addCovaDocGenStep(b, cova_dep, exe, .{\n        .kinds = \u0026.{ .all },\n        .version = \"0.10.1\",\n        .ver_date = \"25 MAR 2025\",\n        .author = \"00JCIV00\",\n        .copyright = \"MIT License\",\n    });\n    const meta_doc_gen = b.step(\"gen-meta\", \"Generate Meta Docs using Cova\");\n    meta_doc_gen.dependOn(\u0026cova_gen.step);\n}\n```\n\u003c/details\u003e\n\n## Demo\n![cova_demo](./docs/cova_demo.gif)\n  \n## Alternatives\n- [flags](https://github.com/n0s4/flags)\n- [snek](https://github.com/BitlyTwiser/snek)\n- [yazap](https://github.com/PrajwalCH/yazap)\n- [zig-args](https://github.com/masterQ32/zig-args)\n- [zig-clap](https://github.com/Hejsil/zig-clap)\n- [zig-cli](https://github.com/sam701/zig-cli)\n- [zli](https://gitlab.com/nihklas/zli)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F00jciv00%2Fcova","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F00jciv00%2Fcova","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F00jciv00%2Fcova/lists"}