Argzon: Command-line argument parsing library using ZON

,

It might seem like yet another CLI argument parsing library in Zig, but this one comes with a twist – it works based on a ZON struct of your CLI definition. And the inspiration behind it is @MasonRemaley’s amazing work on the compiler’s ZON implementation as well as structopt.

Long story short, I’ve rewritten structopt to support ZON-like structs. No fancy parsing, but pretty nice to use (will be even nicer once we’re able to import ZON files without result types).

See the example’s code and build step in the repo:

Also, here’s how zq uses it:

12 Likes

Nice, I’m looking forward to checking this out when I have a chance!

1 Like

I’ve added excludes for named arguments to indicate that they cannot be specified together.

See how zq uses it:

1 Like

1) Dependencies feature

Added dependencies feature for named arguments to depend on each other. Basically, the opposite of excludes, although dependencies are declared one-way, whereas excludes are mutually exclusive (two-way).

2) Enum option values for dependencies and excludes

Now you can declare a dependency on or an exclude of specific enum option values, like this: "option value1 value2".

3) Zig CLI example

Started porting Zig CLI to see how feature-complete argzon is.

Still WIP, but here’s a close comparison (minor edits aside) for zig fetch subcommand’s help output showcasing the new dependencies feature.

Original

Usage: zig fetch [options] <url>
Usage: zig fetch [options] <path>

    Copy a package into the global cache and print its hash.
    <url> must point to one of the following:
      - A git+http / git+https server for the package
      - A tarball file (with or without compression) containing
        package source
      - A git bundle file containing package source

Examples:

  zig fetch --save git+https://example.com/andrewrk/fun-example-tool.git
  zig fetch --save https://example.com/andrewrk/fun-example-tool/archive/refs/heads/master.tar.gz

Options:
  -h, --help                    Print this help and exit
  --global-cache-dir [path]     Override path to global Zig cache directory
  --debug-hash                  Print verbose hash information to stdout
  --save                        Add the fetched package to build.zig.zon
  --save=[name]                 Add the fetched package to build.zig.zon as name
  --save-exact                  Add the fetched package to build.zig.zon, storing the URL verbatim
  --save-exact=[name]           Add the fetched package to build.zig.zon as name, storing the URL verbatim

argzon

Usage snippet

├── fetch [-n <string>] [-G <string>] [-s] [-x] [-H] <string>

Help snippet

fetch                                 Copy package into global cache and print its hash.
  Examples:
    zig fetch --save git+https://example.com/user/repo.git
    zig fetch --save https://example.com/user/repo/archive/refs/heads/main.tar.gz

  Options:
    -n, --save-name <string>          Add fetched package to build.zig.zon with name.
    -G, --global-cache-dir <string>   Override path to global cache directory.

  Flags:
    -s, --save                        Add fetched package to build.zig.zon.
    -x, --exact                       Store URL verbatim.
      Dependencies:
        --save
        --save-name
    -H, --hash                        Print verbose hash information for debugging.

  Positionals:
    URL_OR_PATH <string>              URL or local directory path.
      URL must point to one of the following:
        - Git bundle file containing package source
        - Git HTTP package server (git+http / git+https)
        - Tarball file (with or without compression) containing package source

P.S. I’ve discovered that zig detect-cpu works in release builds even though it’s listed in zig -h output among debug subcommands, which you won’t see unless you’re using a debug build of the compiler.

4 Likes