An open API service indexing awesome lists of open source software.

https://github.com/d4c7/zarg

[WIP] zarg is a minimalist and efficient command-line parsing library written in Zig
https://github.com/d4c7/zarg

cli command-line command-line-parser zig zig-package

Last synced: 5 months ago
JSON representation

[WIP] zarg is a minimalist and efficient command-line parsing library written in Zig

Awesome Lists containing this project

README

          

# zarg

zarg (former zig-argueando) is a minimalist and efficient command-line parsing library written in Zig. It is designed to offer a convenient way of parsing command-line arguments in a simple yet powerful manner. With zarg, you can easily set options, flags, and positional arguments for your command-line applications.

Version 0.0.1 for zig 0.3.0

```
WARNING: THIS IS A WORK IN PROGRESS, YOU SHOULD EXPECT BREAKING CHANGES AND BUGS
```

## Features

- Parses command-line arguments into an autogenerated struct
- Automatic generation of usage and help text including headers, footers, types...
- Support for flags, options, and positional arguments
- Support for multi-option arguments
- You can define the separator between options and arguments
- Provides built-in support for basic and complex argument types, including enums and JSON
- Offers the ability to define and use custom argument types
- Includes default validators for arguments, reducing the boilerplate code
- Enables users to define and use custom validation rules for arguments
- Choose between halting at the first encountered problem or collecting all problems
- Highly customizable and easy to use
- Lightweight with no dependencies
- Leverages Zig's powerful compile-time feature **as much as possible**
- Autocomplete support

## Documentation

[Un analizador de línea de comandos en Zig 🔧 (Parte I)](https://d4c7.github.io/zig-zagueando/posts/un-analizador-de-linea-de-comandos-en-zig-1/)

[Un analizador de línea de comandos en Zig 🔧 (Parte II)](https://d4c7.github.io/zig-zagueando/posts/un-analizador-de-linea-de-comandos-en-zig-2/)

## Install

To use zarg in your project, you need to add the dependency to your `build.zig.zon`:

```bash
$ zig fetch --save git+https://github.com/d4c7/zarg
```

Then you could add the module to to your `build.zig` file:

```zig
const zarg = b.dependency("zarg", .{
.target = target,
.optimize = optimize,
});

exe.root_module.addImport("zarg", zarg.module("zarg"));

```

## Usage

Define a struct that defines the command-line arguments, help texts, headers and types you want to parse:

```zig
const clp = comptime zarg.CommandLineParser.init(.{
.header=
\\ ______ _ _ __ __ _
\\ |_ / _` | '__/ _` |
\\ / / (_| | | | (_| |
\\ /___\__,_|_| \__, |
\\ |___/
,.params = &[_]zarg.Param{
help(.{ .long = "help", .short = "h", .help = "Shows this help." }),
flag(.{ .long = "version", .help = "Output version information and exit." }),
flag(.{ .long = "verbose", .short = "v", .help = "Enable verbose output." }),
option(.{ .long = "port", .short = "p", .parser = "TCP_PORT", .default = "1234", .help = "Listening Port." }),
option(.{ .long = "host", .short = "H", .parser = "TCP_HOST", .default = "localhost", .help = "Host name" }),
positional(.{ .parser = "DIR", .default = ".", .check = &Check.Dir(.{ .mode = .read_only }).f }),
},
.desc = "This command starts an HTTP Server and serves static content from directory DIR.",
.footer = "More info: .",
});
```

The field `params` in the struct defines the option and positional arguments.

Then, in your `main` function, use the `parse` function to parse the command-line arguments:

```zig
var s = clp.parseArgs(allocator);
defer s.deinit();

if (s.helpRequested()) {
try s.printHelp(std.io.getStdErr().writer());
return;
}

if (s.hasProblems()) {
try s.printProblems(std.io.getStdErr().writer(), .all_problems);
return;
}

std.debug.print("dir: {s}\n", .{s.arg.positional});
std.debug.print("port: {d}\n", .{s.arg.port});
std.debug.print("host: {s}\n", .{s.arg.host});

```

Output sample

```txt
$ sample --help
______ _ _ __ __ _
|_ / _` | '__/ _` |
/ / (_| | | | (_| |
/___\__,_|_| \__, |
|___/
Usage: sample [(-h|--help)] [--version] [(-v|--verbose)] [(-p|--port)=TCP_PORT] [(-H|--host)=TCP_HOST] [DIR]

This command starts an HTTP Server and serves static content from directory DIR.

-h, --help Shows this help.
--version Output version information and exit.
-v, --verbose Enable verbose output.
-p, --port=TCP_PORT Listening Port.
Default value: 1234
-H, --host=TCP_HOST Host name
Default value: localhost

TCP_PORT TCP port value between 0 and 65535. Use port 0 to dynamically assign a port
Can use base prefix (0x,0o,0b).
TCP_HOST TCP host name or IP.
DIR Directory

More info: .
```

Detailed error reporting with `all_problems` mode:

```txt
$ zig-out/bin/sample_complete -c=black -k -p 70000 -vv
sample_complete:
* Unsupported value 'black' of type COLOR for option 'c': InvalidEnum (-c=black) at arg #1
* Unrecognized option 'k' (-k) at arg #2
* Unsupported value '70000' of type TCP_PORT for option 'p': Overflow (70000) at arg #4
* Unexpected repeated flag 'v' (-vv) at arg #5
* Expected between 1 and 5 Directory's, but found 0
* Expected --alloc_opt
* Expected 1 --array1a1's, but found 0
* Expected between 1 and 2 --array1a2's, but found 0
* Expected 1 --array1aN's, but found 0
Try 'zig-out/bin/sample_complete --help' for more information.
```

View more examples in the [`examples`](examples) folder.

You can build the samples using:

```
zig build examples
```
## Misc

### Run tests

```
zig test src/tests.zig
```

### Generate a coverture report

Require `kcov` installed
```
zig build cover
```

View the report
```
firefox zig-out/coverture/index.html
```

Note: Since the Zig compiler exclusively compiles functions that are explicitly called or referenced and comptime can lead to substantial portions of code not being included in the runtime the coverage results only reflect the extent to which the utilized functions are covered.

## Autocomplete

You can provide easily an autocompleter for a zarg command line parser.

### How it works

To enable autocompletion, a command is compiled that analyzes the command line and suggests completion options based on the cursor position in that line. This command also allows installing a lightweight autocompletion script for a specific shell, which will call the autocompletion command for the heavy processing.

You can integreate in the same command or using a separate one, which is the recommended way.

The autocompleter analizes your provided CommandlineParser and suggest completions for:

- Short option names
- Long option names
- Option argument types
- Positional argument types

The built-in supported argument types are:
- FILE: autocomplete with a file
- DIR: autocomplete with a directory
- ENUM: autocomplete with enum values

You could define your own parser with custom autocomplete behaviour.

### How to use autocomplete

In order to generate an autocompleter command for a custom CommandlineParser use the following code:

```zig
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
defer _ = gpa.deinit();

try zarg.Autocomplete.__main(my_clp, allocator);
}
```

### Autocomplete sample

A complete sample is provided:

```
zig build examples

export PATH=zig-out/bin/:$PATH

source <(sample_autocomplete_completer install -s bash -t sample_autocomplete)
# or output to /etc/bash_completion.d/

sample_autocomplete --

```

### Road map

- Fix and complete
- Reorganize code
- Data structures simplification
- Params comptime smart param indexing
- Documentation
- Add missing basic parsers
- Much more tests
- Help structure rethink
- Color support for help with custom styles
- Upgrade to zig 0.14.0 (maintain branch per main zig version)

## Caution

**Please note that zarg is a work in progress being developed and tested**. If you are using a different Zig compiler version, we cannot guarantee that the library will work as expected. Before reporting any issues, please make sure you are using the recommended Zig compiler version. It is always a good practice to use the same compiler version that a library or application was developed with to avoid any compatibility issues. We are continuously working on providing support for newer versions of the Zig compiler. Please stay tuned for updates.

## Contribution

We welcome all contributions! Please feel free to submit a PR or create an issue if you encounter any problem or have a feature request.

## License

zarg is licensed under the EUPL-1.2 license and MIT. Please check the [`LICENSES`](examples) folder for more details.