Skip to content

Commit af5ba8f

Browse files
authored
The first release (#4)
1 parent 40bf0bd commit af5ba8f

23 files changed

Lines changed: 806 additions & 116 deletions

.github/workflows/codecov.yml

Lines changed: 0 additions & 33 deletions
This file was deleted.

.github/workflows/lints.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Run Linters
1+
name: Run Linter Checks
22

33
on:
44
workflow_dispatch:

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Run Test
1+
name: Run Tests
22

33
on:
44
workflow_dispatch:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,4 @@ docs/api/
103103
*.dylib
104104
*.dll
105105
*.exe
106+
latest

Makefile

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ CACHE_DIR := .zig-cache
1212
BINARY_NAME := example
1313
RELEASE_MODE := ReleaseSmall
1414
TEST_FLAGS := --summary all #--verbose
15-
JUNK_FILES := *.o *.obj *.dSYM
15+
JUNK_FILES := *.o *.obj *.dSYM *.dll *.so *.dylib *.a *.lib *.pdb
1616

1717
# Automatically find all example names
1818
EXAMPLES := $(patsubst %.zig,%,$(notdir $(wildcard examples/*.zig)))
@@ -25,7 +25,7 @@ SHELL := /usr/bin/env bash
2525
# Targets
2626
################################################################################
2727

28-
.PHONY: all help build rebuild run test release clean lint format docs serve-docs install-deps coverage setup-hooks test-hooks
28+
.PHONY: all help build rebuild run test release clean lint format docs serve-docs install-deps setup-hooks test-hooks
2929
.DEFAULT_GOAL := help
3030

3131
help: ## Show the help messages for all targets
@@ -65,7 +65,7 @@ release: ## Build in Release mode
6565
@$(MAKE) BUILD_TYPE=$(RELEASE_MODE) build
6666

6767
clean: ## Remove docs, build artifacts, and cache directories
68-
@echo "Removing build artifacts, cache, generated docs, and coverage files..."
68+
@echo "Removing build artifacts, cache, generated docs, and junk files..."
6969
@rm -rf $(BUILD_DIR) $(CACHE_DIR) $(JUNK_FILES) docs/api public
7070

7171
lint: ## Check code style and formatting of Zig files
@@ -90,10 +90,6 @@ install-deps: ## Install system dependencies (for Debian-based systems)
9090
@sudo apt-get install -y make llvm snapd
9191
@sudo snap install zig --beta --classic
9292

93-
coverage: test ## Generate code coverage report
94-
@echo "Generating coverage report..."
95-
@kcov --include-pattern=src --verify coverage-out zig-out/bin/simple_cli
96-
9793
setup-hooks: ## Install Git hooks (pre-commit and pre-push)
9894
@echo "Setting up Git hooks..."
9995
@if ! command -v pre-commit &> /dev/null; then \

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
<h2>Chilli</h2>
88

99
[![Tests](https://img.shields.io/github/actions/workflow/status/habedi/chilli/tests.yml?label=tests&style=flat&labelColor=282c34&logo=github)](https://github.com/habedi/chilli/actions/workflows/tests.yml)
10-
[![Code Coverage](https://img.shields.io/codecov/c/github/habedi/chilli?label=coverage&style=flat&labelColor=282c34&logo=codecov)](https://codecov.io/gh/habedi/chilli)
1110
[![CodeFactor](https://img.shields.io/codefactor/grade/github/habedi/chilli?label=code%20quality&style=flat&labelColor=282c34&logo=codefactor)](https://www.codefactor.io/repository/github/habedi/chilli)
12-
[![License](https://img.shields.io/badge/license-MIT-007ec6?label=license&style=flat&labelColor=282c34&logo=open-source-initiative)](https://github.com/habedi/chilli/blob/main/LICENSE)
1311
[![Zig Version](https://img.shields.io/badge/Zig-0.14.1-orange?logo=zig&labelColor=282c34)](https://ziglang.org/download/)
12+
[![License](https://img.shields.io/badge/license-MIT-007ec6?label=license&style=flat&labelColor=282c34&logo=open-source-initiative)](https://github.com/habedi/chilli/blob/main/LICENSE)
1413
[![Release](https://img.shields.io/github/release/habedi/chilli.svg?label=release&style=flat&labelColor=282c34&logo=github)](https://github.com/habedi/chilli/releases/latest)
1514

1615
A microframework for creating command-line applications in Zig
@@ -25,7 +24,7 @@ while being small and fast, and not getting in the way of your application logic
2524

2625
### Features
2726

28-
- Provides a simple, declarative API for building CLI applications
27+
- Provides a simple, low-overhead, declarative API for building CLI applications
2928
- Supports nested commands, subcommands, and aliases
3029
- Provides type-safe parsing for flags, positional arguments, and environment variables
3130
- Supports generating automatic `--help` and `--version` output with custom sections
@@ -144,24 +143,24 @@ pub fn main() anyerror!void {
144143

145144
### Documentation
146145

147-
You can use the `make doc` command to generate the API documentation for Chilli.
148-
This will generate HTML documentation in the [docs/api](docs/api/index.html) directory, which you can serve locally with
149-
`make serve-docs` and view in your web browser at `http://localhost:8000/index.html`.
146+
You can use the `make docs` command to generate the API documentation for Chilli.
147+
This will generate HTML documentation in the `docs/api` directory, which you can serve locally with `make serve-docs`
148+
and view in your web browser at `http://localhost:8000/index.html`.
150149

151150
### Examples
152151

153-
Here’s your table with an added **Index** column:
154-
155-
| **#** | **File** | **Description** |
156-
|-------|-------------------------------------------------------------|---------------------------------------------------------------------|
157-
| 1 | [e1\_simple\_cli.zig](examples/e1_simple_cli.zig) | A simple CLI application that shows basic command and flag parsing |
158-
| 2 | [e2\_nested\_commands.zig](examples/e2_nested_commands.zig) | A CLI application with nested commands and subcommands |
159-
| 3 | [e3\_help\_output.zig](examples/e3_help_output.zig) | Example demonstrates automatic help output and usage information |
160-
| 4 | [e4\_flags\_and\_args.zig](examples/e4_flags_and_args.zig) | Example shows how to use flags and positional arguments in commands |
161-
| 5 | [e5\_custom\_sections.zig](examples/e5_custom_sections.zig) | Example demonstrates grouping subcommands into custom sections |
162-
| 6 | [e6\_advanced\_cli.zig](examples/e6_advanced_cli.zig) | More advanced example that combines multiple features of Chilli |
152+
| **#** | **File** | **Description** |
153+
|-------|-----------------------------------------------------------|--------------------------------------------------------------------------|
154+
| 1 | [e1_simple_cli.zig](examples/e1_simple_cli.zig) | A simple CLI application that shows basic command and flag parsing |
155+
| 2 | [e2_nested_commands.zig](examples/e2_nested_commands.zig) | A CLI application with nested commands and subcommands |
156+
| 3 | [e3_help_output.zig](examples/e3_help_output.zig) | An example that demonstrates automatic help output and usage information |
157+
| 4 | [e4_custom_sections.zig](examples/e4_custom_sections.zig) | An example that demonstrates grouping subcommands into custom sections |
158+
| 5 | [e5_advanced_cli.zig](examples/e5_advanced_cli.zig) | An example that combines multiple features of Chilli |
159+
| 6 | [e6_file_downloader.zig](examples/e6_file_downloader.zig) | A CLI application that downloads files from the internet |
160+
| 7 | [e7_calculator.zig](examples/e7_calculator.zig) | A simple calculator CLI that supports basic arithmetic operations |
161+
| 8 | [e8_flags_and_args.zig](examples/e8_flags_and_args.zig) | Example shows how to use flags and positional arguments in commands |
163162

164-
### Feature Checklist
163+
### Feature Roadmap
165164

166165
- [x] **Command Structure**
167166
- [x] Nested commands and subcommands
@@ -186,6 +185,7 @@ Here’s your table with an added **Index** column:
186185
- [x] Shared context data for passing application state
187186
- [ ] Deprecation notices for commands or flags
188187
- [ ] Built-in TUI components (like spinners and progress bars)
188+
- [ ] Automatic command history and completion
189189

190190
---
191191

build.zig

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,13 @@ pub fn build(b: *std.Build) void {
2424
const docs_step = b.step("docs", "Generate API documentation");
2525
const doc_install_path = "docs/api";
2626

27-
// Create a command to invoke `zig build-obj -femit-docs`.
28-
// This correctly analyzes the public API of src/lib.zig.
2927
const gen_docs_cmd = b.addSystemCommand(&[_][]const u8{
3028
b.graph.zig_exe, // Use the same zig that is running the build
3129
"build-lib",
3230
"src/lib.zig",
3331
"-femit-docs=" ++ doc_install_path,
3432
});
3533

36-
// Ensure the docs/api directory exists before running the command by running `mkdir -p`
3734
const mkdir_cmd = b.addSystemCommand(&[_][]const u8{
3835
"mkdir", "-p", doc_install_path,
3936
});

build.zig.zon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.{
22
.name = .chilli,
3-
.version = "0.1.0-a2",
3+
.version = "0.1.0",
44
.fingerprint = 0x6c259741ae4f5f73, // Changing this has security and trust implications.
55
.minimum_zig_version = "0.14.1",
66
.paths = .{

examples/e1_simple_cli.zig

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ pub fn main() anyerror!void {
1111
const allocator = gpa.allocator();
1212

1313
var app_context = AppContext{
14-
.config_path = "", // Will be populated by the root command's exec
14+
.config_path = "",
1515
};
1616

17+
defer if (app_context.config_path.len > 0) allocator.free(app_context.config_path);
18+
1719
const root_options = chilli.CommandOptions{
1820
.name = "chilli-app",
1921
.description = "A simple example CLI using Chilli.",
@@ -32,7 +34,6 @@ pub fn main() anyerror!void {
3234
};
3335
try root_command.addFlag(config_flag);
3436

35-
// --- `run` subcommand with variadic arguments ---
3637
const run_options = chilli.CommandOptions{
3738
.name = "run",
3839
.description = "Runs a task against a list of files.",
@@ -41,14 +42,12 @@ pub fn main() anyerror!void {
4142
var run_command = try chilli.Command.init(allocator, run_options);
4243
try root_command.addSubcommand(run_command);
4344

44-
// A required, typed positional argument
4545
try run_command.addPositional(.{
4646
.name = "task-name",
4747
.description = "The name of the task to run.",
4848
.is_required = true,
49-
.type = .String, // Explicitly a string
49+
.type = .String,
5050
});
51-
// A variadic positional argument to capture all remaining values
5251
try run_command.addPositional(.{
5352
.name = "files",
5453
.description = "A list of files to process.",
@@ -61,29 +60,50 @@ pub fn main() anyerror!void {
6160
fn rootExec(ctx: chilli.CommandContext) anyerror!void {
6261
const app_ctx = ctx.getContextData(AppContext).?;
6362
const config_slice = try ctx.getFlag("config", []const u8);
63+
const stdout = std.io.getStdOut().writer();
6464

65-
// The slice from getFlag can point to temporary memory. To safely store it,
66-
// it must be copied. The context's allocator is valid for this exec call.
67-
app_ctx.config_path = try ctx.allocator.dupe(u8, config_slice);
65+
if (app_ctx.config_path.len > 0) {
66+
ctx.app_allocator.free(app_ctx.config_path);
67+
}
68+
app_ctx.config_path = try ctx.app_allocator.dupe(u8, config_slice);
6869

69-
std.debug.print("Welcome to chilli-app!\n", .{});
70-
std.debug.print(" Using config file: {s}\n\n", .{app_ctx.config_path});
70+
try stdout.print("Welcome to chilli-app!\n", .{});
71+
try stdout.print(" Using config file: {s}\n\n", .{app_ctx.config_path});
7172
try ctx.command.printHelp();
7273
}
7374

7475
fn runExec(ctx: chilli.CommandContext) anyerror!void {
75-
// Access positional arguments by name, now with type safety
7676
const task_name = try ctx.getArg("task-name", []const u8);
77-
const files = ctx.getArgs("files"); // Variadic arguments remain string slices
77+
const files = ctx.getArgs("files");
78+
const stdout = std.io.getStdOut().writer();
7879

79-
std.debug.print("Running task '{s}'...\n", .{task_name});
80+
try stdout.print("Running task '{s}'...\n", .{task_name});
8081

8182
if (files.len == 0) {
82-
std.debug.print("No files provided to process.\n", .{});
83+
try stdout.print("No files provided to process.\n", .{});
8384
} else {
84-
std.debug.print("Processing {d} files:\n", .{files.len});
85+
try stdout.print("Processing {d} files:\n", .{files.len});
8586
for (files) |file| {
86-
std.debug.print(" - {s}\n", .{file});
87+
try stdout.print(" - {s}\n", .{file});
8788
}
8889
}
8990
}
91+
92+
// Example Invocations
93+
//
94+
// 1. Build the example executable:
95+
// zig build e1_simple_cli
96+
//
97+
// 2. Run with different arguments:
98+
//
99+
// // Show the help output for the root command
100+
// ./zig-out/bin/e1_simple_cli --help
101+
//
102+
// // Run the 'run' subcommand with a task name and a list of files
103+
// ./zig-out/bin/e1_simple_cli run build-assets main.js styles.css script.js
104+
//
105+
// // Use the --config flag from the root command
106+
// ./zig-out/bin/e1_simple_cli --config ./custom.conf run process-logs
107+
//
108+
// // Use the environment variable to set the config path
109+
// CHILLI_APP_CONFIG=~/.config/chilli.conf ./zig-out/bin/e1_simple_cli run check-status

examples/e2_nested_commands.zig

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ fn rootExec(ctx: chilli.CommandContext) !void {
77

88
fn dbMigrateExec(ctx: chilli.CommandContext) !void {
99
_ = ctx;
10-
std.debug.print("Running database migrations...\n", .{});
10+
const stdout = std.io.getStdOut().writer();
11+
try stdout.print("Running database migrations...\n", .{});
1112
}
1213

1314
fn dbSeedExec(ctx: chilli.CommandContext) !void {
1415
const file = try ctx.getArg("file", []const u8);
15-
std.debug.print("Seeding database from file: {s}\n", .{file});
16+
const stdout = std.io.getStdOut().writer();
17+
try stdout.print("Seeding database from file: {s}\n", .{file});
1618
}
1719

1820
pub fn main() anyerror!void {
@@ -56,3 +58,22 @@ pub fn main() anyerror!void {
5658

5759
try root_cmd.run(null);
5860
}
61+
62+
// Example Invocations
63+
//
64+
// 1. Build the example executable:
65+
// zig build e2_nested_commands
66+
//
67+
// 2. Run with different arguments:
68+
//
69+
// // Show help for the root 'app' command
70+
// ./zig-out/bin/e2_nested_commands --help
71+
//
72+
// // Show help for the 'db' subcommand
73+
// ./zig-out/bin/e2_nested_commands db --help
74+
//
75+
// // Execute the 'db migrate' command
76+
// ./zig-out/bin/e2_nested_commands db migrate
77+
//
78+
// // Execute the 'db seed' command with its required file argument
79+
// ./zig-out/bin/e2_nested_commands db seed data/seeds.sql

0 commit comments

Comments
 (0)