- name
- fix-bug
- description
- Debug and fix bugs in Syncpack using scientific debugging methodology. Use when a test is failing, unexpected behaviour occurs, or investigating issues. Covers hypothesis-driven debugging and TDD-based fixes.
# Fix Bug
Guide for debugging and fixing bugs in Syncpack.
## Scientific Debugging Workflow
1. **Observe** — Understand the symptom precisely
2. **Hypothesise** — Form a theory about the root cause
3. **Experiment** — Test the hypothesis with targeted changes
4. **Validate** — Confirm the fix with tests
5. **Verify** — Run full test suite
## Step 1: Observe
Gather information before changing code:
```bash
# Run the failing test with output
cargo test test_name -- --nocapture
# Run with backtrace
RUST_BACKTRACE=1 cargo test test_name
# Test against fixture
cd fixtures/fluid-framework
cargo run -- lint
```
Questions to answer:
- What is the exact error message?
- What input triggers it?
- What is the expected vs actual behaviour?
## Step 2: Hypothesise
Common root causes by symptom:
| Symptom | Likely Cause |
| -------------------- | ------------------------------------------------------- |
| State is `Unknown` | `visit_packages` not called or instance skipped |
| Wrong state assigned | Validation logic order, earlier check overriding |
| Instance not found | Package/dependency name mismatch, location format |
| Command not running | Missing registration in cli.rs, main.rs, or commands.rs |
| Panic/unwrap failure | Unexpected None or Err value |
## Step 3: Experiment
Add targeted debug output:
```rust
use log::debug;
debug!("Instance: {:#?}", instance);
debug!("State before: {:?}", instance.state.borrow());
```
Search for related code:
```bash
# Find where state is assigned
ast-grep -p 'InstanceState::fixable' src/visit_packages/
# Find similar patterns
ast-grep -p 'PATTERN' src/
```
## Step 4: Validate
Write a failing test FIRST (TDD):
```rust
#[test]
fn reproduces_the_bug() {
let ctx = TestBuilder::new()
.with_packages(vec![/* minimal reproduction */])
.build_and_visit_packages();
// Assert expected behaviour (will fail initially)
}
```
Then fix the code until the test passes.
## Step 5: Verify
```bash
just test # All tests pass
cargo clippy # No warnings
```
## Where to Look
### By component
| Issue with... | Check... |
| ---------------- | ---------------------------------------- |
| CLI parsing | `src/cli.rs` |
| Config loading | `src/config.rs`, `src/rcfile.rs` |
| Package reading | `src/packages.rs`, `src/package_json.rs` |
| State assignment | `src/visit_packages/*.rs` |
| Command output | `src/commands/*.rs`, `src/commands/ui/` |
| Version parsing | `src/specifier/*.rs` |
### By phase
| Phase | What happens | Files |
| ------- | ---------------------------------------- | ------------------------------------------ |
| Create | Read config, packages, collect instances | `context.rs`, `packages.rs` |
| Inspect | Assign InstanceState | `visit_packages.rs`, `visit_packages/*.rs` |
| Run | Process instances, output/write | `commands/*.rs` |
## Common Fixes
### Instance state not being assigned
Check:
1. Is the instance's version group variant handled in `visit_packages.rs`?
2. Is there an early return skipping this instance?
3. Is another validation assigning a state first?
### Test assertion failing
Check:
1. Is `build_and_visit_packages()` called (not just `build()`)?
2. Is the location string format correct? (`"{dep} in {location} of {package}"`)
3. Are there multiple instances of the same dependency?
### Command not found
Verify registration in all three places:
1. `src/cli.rs` — `Subcommand` enum
2. `src/main.rs` — match arm
3. `src/commands.rs` — module declaration
## Debugging Tips
- **Isolate** — Create minimal reproduction
- **Binary search** — Comment out code to narrow down
- **Print early** — Add debug output before suspected area
- **Check order** — Validation order matters (first match wins)
- **Read tests** — Existing tests show expected behaviour
## Anti-Patterns
❌ Changing code without understanding the cause
❌ Removing code just to make tests pass
❌ Fixing symptoms instead of root cause
❌ Skipping the test-first step
在 GitHub 查看