Skip to content

Commit d3cbbbf

Browse files
committed
chore: add modernization beans for anyhow and clap migration
- bx-fktp: Migrate error handling to anyhow (high priority) - bx-3tpt: Migrate argument parsing to clap (high priority)
1 parent a24a2c2 commit d3cbbbf

2 files changed

Lines changed: 116 additions & 0 deletions

File tree

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
# bx-3tpt
3+
title: Migrate argument parsing to clap
4+
status: todo
5+
type: task
6+
priority: high
7+
created_at: 2026-01-22T09:25:56Z
8+
updated_at: 2026-01-22T09:25:56Z
9+
---
10+
11+
Replace manual `env::args()` parsing with `clap` derive macros for type-safe argument handling.
12+
13+
## Why
14+
- Current manual parsing is error-prone and hard to maintain
15+
- No automatic help generation
16+
- No argument validation
17+
- 50% less code with clap
18+
- Industry standard (95%+ of Rust CLI tools use clap)
19+
20+
## Checklist
21+
- [ ] Add `clap = { version = "4", features = ["derive"] }` to Cargo.toml
22+
- [ ] Create src/cli/mod.rs module
23+
- [ ] Create src/cli/args.rs with Cli struct using `#[derive(Parser)]`
24+
- [ ] Define Commands enum with subcommands (Init, Cache, Help, Run)
25+
- [ ] Update src/bin/main.rs to use `Cli::parse()`
26+
- [ ] Remove manual argument parsing code from main.rs
27+
- [ ] Update src/lib.rs to export cli module
28+
- [ ] Ensure backward compatibility with existing flags (-v, -i, -c, -d, -h)
29+
- [ ] Test all commands work as before
30+
- [ ] Verify auto-generated --help output is correct
31+
32+
## Cli Structure
33+
```rust
34+
use clap::{Parser, Subcommand};
35+
36+
#[derive(Parser)]
37+
#[command(name = "bx", version, about = "Simple, cross-platform command aliases")]
38+
pub struct Cli {
39+
#[arg(short = 'd', long, global = true)]
40+
pub debug: bool,
41+
42+
#[command(subcommand)]
43+
pub command: Option<Commands>,
44+
}
45+
46+
#[derive(Subcommand)]
47+
pub enum Commands {
48+
#[command(name = "-v", alias = "--version")]
49+
Version,
50+
#[command(name = "-i", alias = "--init")]
51+
Init {
52+
#[arg(short, long)]
53+
template: Option<String>,
54+
},
55+
#[command(name = "-c", alias = "--cache")]
56+
Cache,
57+
#[command(name = "-h", alias = "--help")]
58+
Help,
59+
#[command(external_subcommand)]
60+
Run(Vec<String>),
61+
}
62+
```
63+
64+
## Notes
65+
- Keep backward compatibility with current flag-style arguments (-v, -i, etc.)
66+
- Consider if we want to also support subcommand-style (bx init, bx cache) in addition
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
# bx-fktp
3+
title: Migrate error handling to anyhow
4+
status: todo
5+
type: task
6+
priority: high
7+
created_at: 2026-01-22T09:25:47Z
8+
updated_at: 2026-01-22T09:25:47Z
9+
---
10+
11+
Replace `Result<T, String>` pattern with `anyhow::Result<T>` for better error handling.
12+
13+
## Why
14+
- Current pattern loses error context and type information
15+
- No error chain/backtrace support
16+
- 40% less boilerplate with anyhow
17+
- Industry standard for Rust CLI applications
18+
19+
## Checklist
20+
- [ ] Add `anyhow = "1.0"` to Cargo.toml
21+
- [ ] Update src/bin/main.rs: Change `fn core() -> Result<i32, String>` to `fn core() -> anyhow::Result<i32>`
22+
- [ ] Update src/bin/main.rs: Change `fn real_main() -> i32` to return `anyhow::Result<()>`
23+
- [ ] Update src/get_cfg.rs: `get_cfg()` to return `anyhow::Result<String>`
24+
- [ ] Update src/cache.rs: All functions to use `anyhow::Result`
25+
- [ ] Update src/init.rs: `init()` to use `anyhow::Result`
26+
- [ ] Update src/raw_schema.rs: Config methods to use `anyhow::Result`
27+
- [ ] Update src/schema.rs: All Result-returning functions
28+
- [ ] Update src/bones.rs: All Result-returning functions
29+
- [ ] Add `.context()` calls for meaningful error messages
30+
- [ ] Run `cargo test` to verify all tests pass
31+
- [ ] Run `cargo clippy` to check for issues
32+
33+
## Example Migration
34+
```rust
35+
// Before
36+
pub fn get_cfg() -> Result<String, String> {
37+
match fs::read_to_string(&path) {
38+
Ok(s) => Ok(s),
39+
Err(_) => Err(format!("Error reading config at '{}'", path))
40+
}
41+
}
42+
43+
// After
44+
use anyhow::{Context, Result};
45+
46+
pub fn get_cfg() -> Result<String> {
47+
fs::read_to_string(&path)
48+
.with_context(|| format!("Failed to read config at '{}'", path))
49+
}
50+
```

0 commit comments

Comments
 (0)