Skip to content

Commit 8268019

Browse files
committed
Update to v0.4.0
1 parent f2d0a1b commit 8268019

2 files changed

Lines changed: 58 additions & 36 deletions

File tree

recipes/argmojo/README.md

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ A command-line argument parser library for [Mojo](https://www.modular.com/mojo),
99
-->
1010

1111
[![Version](https://img.shields.io/github/v/tag/forfudan/argmojo?label=version&color=blue)](https://github.com/forfudan/argmojo/releases)
12-
[![Mojo](https://img.shields.io/badge/mojo-0.26.1-orange)](https://docs.modular.com/mojo/manual/)
12+
[![Mojo](https://img.shields.io/badge/mojo-0.26.2-orange)](https://docs.modular.com/mojo/manual/)
1313
[![pixi](https://img.shields.io/badge/pixi%20add-argmojo-brightgreen)](https://prefix.dev/channels/modular-community/packages/argmojo)
1414
[![User manual](https://img.shields.io/badge/user-manual-purple)](https://github.com/forfudan/argmojo/wiki)
1515

@@ -42,7 +42,7 @@ ArgMojo provides a builder-pattern API for defining and parsing command-line arg
4242
- **Short flag merging**: `-abc` expands to `-a -b -c`
4343
- **Attached short values**: `-ofile.txt` means `-o file.txt`
4444
- **Choices validation**: restrict values to a set (e.g., `json`, `csv`, `table`)
45-
- **Metavar**: custom display name for values in help text
45+
- **Value name**: custom display name for values in help text
4646
- **Hidden arguments**: exclude internal args from `--help` output
4747
- **Count flags**: `-vvv``get_count("verbose") == 3`
4848
- **Positional arg count validation**: reject extra positional args
@@ -52,18 +52,46 @@ ArgMojo provides a builder-pattern API for defining and parsing command-line arg
5252
- **Long option prefix matching**: allow abbreviated options (e.g., `--verb``--verbose`). If the prefix is ambiguous (e.g., `--ver` could match both `--verbose` and `--version-info`), an error is raised.
5353
- **Append / collect action**: `--tag x --tag y` collects repeated options into a list with `.append()`
5454
- **One-required groups**: require at least one argument from a group (e.g., must provide `--json` or `--yaml`)
55-
- **Value delimiter**: `--env dev,staging,prod` splits by delimiter into a list with `.delimiter(",")`
56-
- **Multi-value options (nargs)**: `--point 10 20` consumes N consecutive values with `.nargs(N)`
55+
- **Value delimiter**: `--env dev,staging,prod` splits by delimiter into a list with `.delimiter[","]()`
56+
- **Multi-value options (nargs)**: `--point 10 20` consumes N consecutive values with `.number_of_values[N]()`
57+
- **Key-value map options**: `--define CC=gcc --define CXX=g++` collects key=value pairs with `.map_option()`
58+
- **Numeric range validation**: `--level 5` checked against `[min, max]` bounds with `.range[1, 10]()`; optional clamping with `.clamp()`
59+
- **Conditional requirements**: `--output` required when `--save` is present
60+
- **Aliases**: alternative long names (e.g., `--colour` and `--color`) with `.alias_name["color"]()`
61+
- **Deprecated arguments**: emit a warning but continue parsing
62+
- **Custom tips**: add tip lines below the help message
63+
- **Mutual implication**: `--debug` automatically sets `--verbose` with `.implies()`
64+
- **Subcommands**: hierarchical commands (`app search`, `app init`), nested subcommands (`app remote add`), persistent (global) flags, subcommand aliases, hidden subcommands
5765
- **Shell completion script generation**: `generate_completion("bash"|"zsh"|"fish")` produces a complete tab-completion script for your CLI
66+
- **Typo suggestions**: Levenshtein-distance "did you mean …?" for misspelled options and subcommands
67+
- **Interactive prompting**: `.prompt()` to interactively ask for missing values
68+
- **Password / masked input**: `.password()` to hide typed input during prompts
69+
- **Confirmation option**: `confirmation_option()` to add a `--yes`/`-y` skip-confirmation flag
70+
- **Argument parents**: `add_parent()` to share argument definitions across commands
71+
- **Custom usage line**: `usage()` to override the auto-generated usage string
72+
- **Response files**: `@args.txt` expansion (temporarily disabled due to a Mojo compiler bug)
73+
- **CJK-aware help alignment**: CJK characters treated as 2-column-wide
74+
- **CJK full-width auto-correction**: fullwidth `--verbose``--verbose` with a warning
75+
- **CJK punctuation detection**: em-dash `——verbose``--verbose`
76+
- **Argument groups**: `.group["Network"]()` to group arguments under dedicated help sections
77+
- **Default-if-no-value**: `--compress` uses a fallback; `--compress=bzip2` overrides
78+
- **Require equals syntax**: `--key=value` required, `--key value` rejected
79+
- **Remainder positional**: `.remainder()` consumes all remaining tokens
80+
- **Allow hyphen values**: `.allow_hyphen_values()` accepts `-` as a regular value (stdin convention)
81+
- **Partial parsing**: `parse_known_arguments()` collects unrecognised options instead of erroring
82+
- **Compile-time validation**: builder parameters validated at `mojo build` time via `comptime assert`
83+
- **Registration-time validation**: group constraint typos caught when the program starts, not when the user runs it
5884

5985
---
6086

6187
I created this project to support my experiments with a CLI-based Chinese character search engine in Mojo, as well as a CLI-based calculator for [Decimo](https://github.com/forfudan/decimo). It is inspired by Python's `argparse`, Rust's `clap`, Go's `cobra`, and other popular argument parsing libraries, but designed to fit Mojo's unique features and constraints.
6288

63-
My goal is to provide a Mojo-idiomatic argument parsing library that can be easily adopted by the growing Mojo community for their CLI applications. **Before Mojo v1.0** (which means it gets stable), my focus is on building core features and ensuring correctness. "Core features" refer to those who appear in `argparse`/`clap`/`cobra` and are commonly used in CLI apps. "Correctness" means that the library should handle edge cases properly, provide clear error messages, and have good test coverage. Some fancy features will depend on my time and interest.
89+
My goal is to provide a Mojo-idiomatic argument parsing library that can be easily adopted by the growing Mojo community for their CLI applications. **Before Mojo v1.0** (which means it is not yet stable), my focus is on building core features and ensuring correctness. "Core features" refer to those who appear in `argparse`/`clap`/`cobra` and are commonly used in CLI apps. "Correctness" means that the library should handle edge cases properly, provide clear error messages, and have good test coverage. Some fancy features will depend on my time and interest.
6490

6591
## Installation
6692

93+
### Package Manager
94+
6795
ArgMojo is available in the modular-community `https://repo.prefix.dev/modular-community` package repository. To access this repository, add it to your `channels` list in your `pixi.toml` file:
6896

6997
```toml
@@ -77,17 +105,14 @@ Then, you can install ArgMojo using any of these methods:
77105
1. In the `mojoproject.toml` file of your project, add the following dependency:
78106

79107
```toml
80-
argmojo = "==0.3.0"
108+
argmojo = "*"
81109
```
82110

83111
Then run `pixi install` to download and install the package.
84112

85-
The following table summarizes the package versions and their corresponding Mojo versions:
113+
### Using mojopkg
86114

87-
| `argmojo` version | `mojo` version | package manager |
88-
| ----------------- | -------------- | --------------- |
89-
| 0.1.0 | ==0.26.1 | pixi |
90-
| 0.3.0 | ==0.26.1 | pixi |
115+
The package manager may not be up to date with the latest ArgMojo release. If you want to use the latest version, you can download the `mojopkg` file from the [latest release](https://github.com/forfudan/argmojo/releases) and include it in your project directory.
91116

92117
## Quick Start
93118

@@ -97,40 +122,39 @@ Here is a simple example of how to use ArgMojo in a Mojo program. See `examples/
97122
from argmojo import Argument, Command
98123

99124

100-
fn main() raises:
125+
def main() raises:
101126
var app = Command("mgrep", "Search for PATTERN in each FILE.", version="1.0.0")
102127

103128
# Positional arguments
104129
app.add_argument(Argument("pattern", help="Search pattern").positional().required())
105-
app.add_argument(Argument("path", help="Search path").positional().default("."))
130+
app.add_argument(Argument("path", help="Search path").positional().default["."]())
106131

107132
# Boolean flags
108133
app.add_argument(
109134
Argument("ignore-case", help="Ignore case distinctions")
110-
.long("ignore-case").short("i").flag()
135+
.long["ignore-case"]().short["i"]().flag()
111136
)
112137
app.add_argument(
113138
Argument("recursive", help="Search directories recursively")
114-
.long("recursive").short("r").flag()
139+
.long["recursive"]().short["r"]().flag()
115140
)
116141

117142
# Count flag (verbosity)
118143
app.add_argument(
119144
Argument("verbose", help="Increase verbosity (-v, -vv, -vvv)")
120-
.long("verbose").short("v").count()
145+
.long["verbose"]().short["v"]().count()
121146
)
122147

123148
# Key-value option with choices
124-
var formats: List[String] = ["text", "json", "csv"]
125149
app.add_argument(
126150
Argument("format", help="Output format")
127-
.long("format").short("f").choices(formats^).default("text")
151+
.long["format"]().short["f"]().choice["text"]().choice["json"]().choice["csv"]().default["text"]()
128152
)
129153

130154
# Negatable flag — --color enables, --no-color disables
131155
app.add_argument(
132156
Argument("color", help="Highlight matching text")
133-
.long("color").flag().negatable()
157+
.long["color"]().flag().negatable()
134158
)
135159

136160
# Parse and use
@@ -147,10 +171,12 @@ For detailed explanations and more examples of every feature, see the **[User Ma
147171

148172
ArgMojo ships with two complete example CLIs:
149173

150-
| Example | File | Features |
151-
| ------------------------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
152-
| `mgrep` — simulated grep | `examples/mgrep.mojo` | Positional args, flags, count flags, negatable flags, choices, metavar, append/collect, value delimiter, nargs, mutually exclusive groups, required-together groups, conditional requirements, numeric range, key-value map, aliases, deprecated args, hidden args, negative-number passthrough, `--` stop marker, custom tips |
153-
| `mgit` — simulated git | `examples/mgit.mojo` | Subcommands (clone/init/add/commit/push/pull/log/remote/branch/diff/tag/stash), nested subcommands (remote add/remove/rename/show), persistent (global) flags, per-command args, mutually exclusive groups, choices, aliases, deprecated args, custom tips, shell completion script generation |
174+
| Example | File | Features |
175+
| ------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
176+
| `mgrep` — simulated grep | `examples/mgrep.mojo` | Positional args, flags, count flags, negatable flags, choices, value_name, append/collect, value delimiter, nargs, mutually exclusive groups, required-together groups, conditional requirements, numeric range, key-value map, aliases, deprecated args, hidden args, negative-number passthrough, `--` stop marker, custom tips |
177+
| `mgit` — simulated git | `examples/mgit.mojo` | Subcommands (clone/init/add/commit/push/pull/log/remote/branch/diff/tag/stash), nested subcommands (remote add/remove/rename/show), persistent (global) flags, per-command args, mutually exclusive groups, choices, aliases, deprecated args, custom tips, shell completion script generation |
178+
| `demo` — feature showcase | `examples/demo.mojo` | Comprehensive showcase of all ArgMojo features in a single CLI |
179+
| `yu` — Chinese CLI | `examples/yu.mojo` | CJK-aware help formatting, full-width auto-correction, CJK punctuation detection |
154180

155181
Build both example binaries:
156182

@@ -235,26 +261,22 @@ pixi run clean
235261
```txt
236262
argmojo/
237263
├── docs/ # Documentation
264+
│ ├── argmojo_overall_planning.md # Planning document and feature matrix
265+
│ ├── changelog.md # Release changelog
238266
│ └── user_manual.md # User manual with detailed examples
239267
├── examples/
268+
│ ├── demo.mojo # Comprehensive feature showcase
240269
│ ├── mgrep.mojo # grep-like CLI (no subcommands)
241-
│ └── mgit.mojo # git-like CLI (with subcommands)
270+
│ ├── mgit.mojo # git-like CLI (with subcommands)
271+
│ └── yu.mojo # Chinese-language CLI (CJK features)
242272
├── src/
243273
│ └── argmojo/ # Main package
244274
│ ├── __init__.mojo # Package exports
245275
│ ├── argument.mojo # Argument struct (argument definition)
246276
│ ├── command.mojo # Command struct (parsing logic)
247277
│ ├── parse_result.mojo # ParseResult struct (parsed values)
248278
│ └── utils.mojo # ANSI colour constants and utility functions
249-
├── tests/ # Test suites (241 tests)
250-
│ ├── test_parse.mojo
251-
│ ├── test_groups.mojo
252-
│ ├── test_collect.mojo
253-
│ ├── test_help.mojo
254-
│ ├── test_extras.mojo
255-
│ ├── test_subcommands.mojo
256-
│ ├── test_negative_numbers.mojo
257-
│ └── test_persistent.mojo
279+
├── tests/ # Test suites
258280
├── pixi.toml # pixi configuration
259281
├── LICENSE
260282
└── README.md

recipes/argmojo/recipe.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
context:
2-
version: "0.3.0"
3-
mojo_version: "=0.26.1"
2+
version: "0.4.0"
3+
mojo_version: "=0.26.2"
44

55
package:
66
name: "argmojo"
77
version: ${{ version }}
88

99
source:
1010
- git: https://github.com/forfudan/argmojo.git
11-
rev: c3e00e9da7505372f4d18abb29cb94c67d4325b8
11+
rev: 2dbb8977ce02bc5b02f4e302839dcbb94c73e586
1212

1313
build:
1414
number: 0

0 commit comments

Comments
 (0)