Skip to content
This repository was archived by the owner on Apr 13, 2026. It is now read-only.

Commit 1d148b7

Browse files
committed
Merge pull request #71 from EvilBit-Labs/copilot/fix-23
feat: implement enhanced CLI error handling with anyhow integration
2 parents b4462c5 + 8dc0f05 commit 1d148b7

26 files changed

Lines changed: 1929 additions & 310 deletions

.cursor/rules/ai-assistant/ai-assistant-guidelines.mdc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ When AI agents contribute to this project, they **MUST**:
4040
04. **Use the preferred tooling commands** (see justfile)
4141
05. **Write comprehensive tests** for new functionality (unit, integration, property-based)
4242
06. **Include proper error handling** with context using `thiserror`
43-
07. **Add structured logging** for important operations using console and indicatif
43+
07. **Add user-facing output** for important operations using console styling and indicatif progress indicators
4444
08. **Validate all inputs** and handle edge cases securely
4545
09. **Document new functions and types** following Rust `///` conventions
4646
10. **Never hardcode configuration** - use appropriate data generation patterns

.cursor/rules/core/core-concepts.mdc

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ When rules conflict, always follow the rule with higher precedence.
2727
### EvilBit Labs Brand Principles
2828

2929
- **Trust the Operator**: Full control, no black boxes
30-
- **Polish Over Scale**: Quality over feature-bloat
30+
- **Polish Over Scale**: Quality over feature-bloat
3131
- **Realistic Data**: Generate configurations that mirror real-world networks
3232
- **Sane Defaults**: Clean outputs, CLI help that's actually helpful
3333
- **Testing Focus**: Built specifically for comprehensive network testing scenarios
@@ -52,7 +52,7 @@ When rules conflict, always follow the rule with higher precedence.
5252
- **Error Handling**: Use `Result<T, E>` types and `?` operator, create custom error types with `thiserror`
5353
- **Documentation**: Comprehensive `///` doc comments for all public APIs
5454
- **Testing**: Unit tests co-located with code, integration tests in separate files
55-
- **Logging**: Use `console` crate for user-facing output and `indicatif` for progress indication
55+
- **User Output**: Use `console` crate for styled output and `indicatif` for progress indication
5656

5757
### Architecture Patterns
5858

@@ -98,7 +98,7 @@ impl VlanConfig {
9898
if id == 0 || id > 4094 {
9999
return Err(ConfigError::InvalidVlanId(id));
100100
}
101-
101+
102102
Ok(Self {
103103
id,
104104
name,
@@ -107,16 +107,16 @@ impl VlanConfig {
107107
network,
108108
})
109109
}
110-
110+
111111
pub fn validate(&self) -> Result<()> {
112112
if self.id == 0 || self.id > 4094 {
113113
return Err(ConfigError::InvalidVlanId(self.id));
114114
}
115-
115+
116116
if self.name.is_empty() {
117117
return Err(ConfigError::EmptyName);
118118
}
119-
119+
120120
Ok(())
121121
}
122122
}
@@ -149,7 +149,7 @@ mod tests {
149149

150150
#[test]
151151
fn test_vlan_creation() {
152-
let vlan = VlanConfig::new(100, "Test VLAN".to_string(), "em0".to_string(),
152+
let vlan = VlanConfig::new(100, "Test VLAN".to_string(), "em0".to_string(),
153153
"192.168.1.0/24".parse().unwrap()).unwrap();
154154
assert_eq!(vlan.id, 100);
155155
assert_eq!(vlan.name, "Test VLAN");
@@ -162,7 +162,7 @@ mod tests {
162162
"192.168.1.0/24".parse().unwrap());
163163
prop_assert!(vlan.is_ok());
164164
}
165-
165+
166166
#[test]
167167
fn test_invalid_vlan_id(id in 0u16..1u16) {
168168
let vlan = VlanConfig::new(id, "Test".to_string(), "em0".to_string(),
@@ -246,12 +246,12 @@ let network = "192.168.1.0/24";
246246
// ✅ Correct: Configurable, non-conflicting ranges
247247
let network = generate_test_network_range(base_network, subnet_size);
248248

249-
// ❌ Avoid: Unclear CLI error messages
249+
// ❌ Avoid: Unclear CLI error messages
250250
return Err("Invalid input".into());
251251

252252
// ✅ Correct: Actionable error messages
253-
return Err(ConfigError::InvalidVlanCount {
254-
count,
253+
return Err(ConfigError::InvalidVlanCount {
254+
count,
255255
max: MAX_VLANS,
256256
suggestion: "Reduce the count or split into multiple files".to_string()
257257
});
@@ -324,7 +324,7 @@ When encountering problems:
324324

325325
1. **Network Validity First**: Every change must maintain realistic, valid network configurations
326326
2. **Zero Warnings**: `cargo clippy -- -D warnings` must pass
327-
3. **CLI Usability**: Commands must be intuitive with clear help and error messages
327+
3. **CLI Usability**: Commands must be intuitive with clear help and error messages
328328
4. **Testing Coverage**: Comprehensive unit, integration, and property-based tests
329329
5. **Quality Focus**: Build for network professionals who need reliable test data
330330
6. **Documentation**: Clear docs for all public APIs and CLI usage

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ jobs:
167167
key: bench-${{ hashFiles('**/Cargo.toml') }}
168168

169169
- name: Run benchmarks
170-
run: cargo bench
170+
run: cargo bench --benches --quiet
171171
env:
172172
CARGO_TERM_COLOR: never
173173
TERM: dumb

WARP.md

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
# WARP.md
2+
3+
This file provides guidance to WARP (warp.dev) when working with code in this repository.
4+
5+
## Purpose and Scope
6+
7+
Single-purpose Rust tool that generates realistic OPNsense `config.xml` files for testing, training, and development.
8+
9+
- **OPNsense-only**: Exclusively generates OPNsense firewall configurations; other platforms are out of scope
10+
- **CSV is internal**: CSV generation is an implementation detail, not a first-class user-facing feature
11+
- **Operator-centric**: Offline-first, no telemetry, deterministic-friendly CLI designed for network operators
12+
13+
## Essential Commands
14+
15+
### Build
16+
17+
```bash
18+
cargo build --all-features
19+
cargo build --release --all-features
20+
```
21+
22+
### Lint and Format (zero-tolerance policy)
23+
24+
```bash
25+
cargo fmt --check
26+
cargo clippy --all-targets --all-features --benches -- -D warnings
27+
just format-check
28+
just lint
29+
```
30+
31+
### Tests
32+
33+
```bash
34+
cargo test --all-features
35+
TERM=dumb cargo test --all-features # For deterministic output
36+
just test
37+
just test-unit # Unit tests only
38+
just test-integration # Integration tests only
39+
just test-no-bench # Exclude benchmarks
40+
```
41+
42+
### Coverage
43+
44+
```bash
45+
just install-cov # One-time setup
46+
just coverage # Local with threshold enforcement
47+
just coverage-html # HTML report → target/llvm-cov/html/index.html
48+
just coverage-report # Terminal output
49+
just coverage-clean # Clean artifacts
50+
```
51+
52+
### Benchmarks (excluded from coverage)
53+
54+
```bash
55+
cargo bench --all-features
56+
just bench
57+
```
58+
59+
### CI/QA Shortcuts
60+
61+
```bash
62+
just qa # Format check, lint, test
63+
just qa-cov # QA + coverage
64+
just ci-qa # CI-friendly QA
65+
just ci-check # Full CI validation
66+
just ci-check-fast # Quick CI check (no coverage)
67+
just act-ci # Test CI locally with act
68+
just act-ci-list # List available CI jobs
69+
```
70+
71+
### Run the Generator
72+
73+
```bash
74+
# Generate OPNsense XML configs (primary use case)
75+
cargo run --release -- xml --base-config config.xml --count 25
76+
77+
# Generate VLAN data
78+
cargo run --release -- generate vlan --count 10 --output vlans.xml
79+
cargo run --release -- generate vlan --count 50 --format csv --output network-data.csv
80+
81+
# Generate with firewall rules
82+
cargo run --release -- generate --count 10 --format xml --base-config config.xml --include-firewall-rules --firewall-rules-per-vlan 3 --firewall-rule-complexity intermediate
83+
```
84+
85+
## Architecture and Module Boundaries
86+
87+
### Data Flow
88+
89+
`CLI args → generator → model → validate → xml writer → config.xml on disk`
90+
91+
CSV may be used internally for processing, but is not a public contract.
92+
93+
### Module Responsibilities
94+
95+
- **cli**: Clap v4 derived CLI, subcommands (xml, generate), argument parsing, completions, progress/info output respecting `TERM=dumb`/`NO_COLOR`
96+
- **generator**: Produces realistic VLANs, interfaces, DHCP, NAT, firewall policies, CARP VIPs, RADIUS users with uniqueness and RFC-compliant ranges
97+
- **model**: Strongly-typed serde models for config elements; central invariants and serde derive
98+
- **validate**: Cross-object consistency checks (unique VLAN IDs, no IP conflicts, RFC ranges)
99+
- **io**: CSV utilities (internal), XML I/O helpers; streaming-friendly operations for large sets
100+
- **xml**: Constructs OPNsense config.xml via quick-xml/xmlwriter; integrates base-config and adheres to `opnsense-config.xsd`
101+
- **Cross-cutting**: Robust errors (thiserror/anyhow), performance helpers (bumpalo, lru, rustc-hash, smallvec), optional parallelism via feature `rayon`
102+
103+
## Development Workflow and Quality Gates
104+
105+
**Before proposing any changes, always run**: `just ci-check`
106+
107+
### Quality Standards
108+
109+
- **Lint policy**: `cargo clippy -- -D warnings` (no warnings allowed)
110+
- **Formatting**: `cargo fmt --check` must pass
111+
- **Tests**: Run with `TERM=dumb` for deterministic output when relevant
112+
- **Coverage**: Target ≥79% locally (currently enforced); CI does not gate on coverage drops
113+
- **Security**: `just audit` when changing dependencies
114+
- **Offline-first**: No network calls in core build/test paths
115+
116+
### Review Process
117+
118+
- Use coderabbit.ai for code review
119+
- Single maintainer workflow (@UncleSp1d3r)
120+
- Never auto-commit code
121+
122+
## Testing Strategy
123+
124+
### Test Types
125+
126+
```bash
127+
# Unit tests
128+
cargo test --lib --all-features
129+
130+
# Integration tests (CLI)
131+
cargo test --tests --all-features
132+
TERM=dumb cargo test --tests --all-features
133+
134+
# Property-based tests (proptest)
135+
cargo test proptest --all-features
136+
cargo test proptest --all-features --features slow-tests
137+
PROPTEST_CASES=1000 cargo test proptest
138+
139+
# Snapshot tests (insta)
140+
cargo test --test snapshot_tests
141+
TERM=dumb cargo test --test snapshot_tests
142+
```
143+
144+
### Snapshot Management
145+
146+
```bash
147+
cargo insta review # Review changes
148+
INSTA_UPDATE=auto cargo test --test snapshot_tests # Force accept (use sparingly)
149+
```
150+
151+
### Deterministic Output Tips
152+
153+
- Use `TERM=dumb`, `NO_COLOR=1`, `CARGO_TERM_COLOR=never`
154+
- Keep slow-tests behind feature flags
155+
- Seeded randomness for reproducibility in tests where applicable
156+
157+
## Coverage and CI
158+
159+
### Local Coverage
160+
161+
- `just coverage` enforces 79% threshold (docs mention 80% target - known discrepancy)
162+
- `just coverage-html``target/llvm-cov/html/index.html`
163+
- `just coverage-report` for terminal-only output
164+
165+
### CI Coverage
166+
167+
- `just coverage-ci` generates an lcov report without failing the job
168+
- CI respects `TERM=dumb` and `NO_COLOR`; console/indicatif auto-adapt
169+
170+
### Local CI Testing
171+
172+
```bash
173+
just act-ci # Dry-run CI locally
174+
just act-ci-dry-run # Show what would run
175+
just act-ci-list # List available jobs
176+
```
177+
178+
## Conventions and Practices
179+
180+
### Platform Scope
181+
182+
- **OPNsense-only**: CSV is internal, not a user-facing deliverable
183+
- **Single-purpose**: Do not extend to other firewall platforms
184+
185+
### Commit Messages
186+
187+
- **Conventional Commits** required
188+
- **Common scopes**: `(cli)`, `(generator)`, `(xml)`, `(validation)`, `(io)`
189+
- **Breaking changes**: Mark with `!` or footer `BREAKING CHANGE:`
190+
191+
### EvilBit Labs Standards
192+
193+
- Trust the operator, offline-first, no telemetry, sane defaults
194+
- Cross-platform (macOS, Windows, Linux)
195+
- No hardcoded secrets; validate inputs; airgap-ready
196+
197+
### Assistant Rules
198+
199+
- Run `just ci-check` before any proposed commit
200+
- Prefer coderabbit.ai for review; single maintainer (@UncleSp1d3r)
201+
- Never auto-commit
202+
- Use OpenAPI Generator for Rust clients when applicable (rare in this project)
203+
204+
## Performance and Benchmarks
205+
206+
- **Benchmarks**: criterion framework; HTML reports under `target/criterion/reports/index.html`
207+
- **Profiling**: Optional pprof + flamegraph support
208+
- **Parallelism**: Feature-gated with `--features rayon` for processing large sets
209+
- **Optimization**: Streaming XML (xmlwriter) and allocation strategies (bumpalo) for large configurations
210+
211+
## Project Layout
212+
213+
### Source Structure
214+
215+
```text
216+
src/cli # Command-line interface
217+
src/generator # Data generation logic
218+
src/io # I/O utilities (CSV internal, XML)
219+
src/model # Typed data models
220+
src/validate # Consistency validation
221+
src/xml # OPNsense XML construction
222+
tests/ # Integration tests
223+
benches/ # Performance benchmarks
224+
opnsense-config.xsd # XML schema reference
225+
```
226+
227+
### Key Dependencies
228+
229+
- **CLI**: clap, clap_complete
230+
- **Serialization**: serde, serde_json, csv, quick-xml, xmlwriter
231+
- **Networking**: ipnet, ipnetwork
232+
- **Data Generation**: rand, rand_chacha, fake, uuid
233+
- **Errors**: anyhow, thiserror
234+
- **Performance**: bumpalo, lru, rustc-hash, smallvec
235+
- **Testing**: proptest, insta, criterion, pprof
236+
- **UI**: indicatif, console
237+
238+
### Toolchain
239+
240+
- **Rust**: Stable channel
241+
- **Components**: rustfmt, clippy, llvm-tools-preview
242+
- **Targets**: Multi-platform support (x86_64-unknown-linux-gnu, x86_64-apple-darwin, aarch64-apple-darwin, x86_64-pc-windows-msvc)
243+
244+
## Usage Examples
245+
246+
### Basic XML Generation
247+
248+
```bash
249+
cargo run --release -- xml --base-config legacy/opnsense/config-example.xml --count 25
250+
```
251+
252+
### VLAN Generation
253+
254+
```bash
255+
cargo run --release -- generate vlan --count 10 --output vlans.xml
256+
cargo run --release -- generate vlan --count 50 --format csv --output network-data.csv
257+
```
258+
259+
### Firewall Rules
260+
261+
```bash
262+
cargo run --release -- generate --count 10 --format xml --base-config config.xml --include-firewall-rules --firewall-rules-per-vlan 3 --firewall-rule-complexity intermediate
263+
```
264+
265+
**Note**: `--firewall-rules-per-vlan` overrides default rule count for the chosen complexity and reassigns priorities per VLAN starting at 1.

0 commit comments

Comments
 (0)