Skip to content

Commit e81b18d

Browse files
committed
Initial commit
0 parents  commit e81b18d

24 files changed

+2751
-0
lines changed

.github/copilot-instructions.md

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
# Copilot Instructions for scout-merit-badges-anki
2+
3+
## Repository Overview
4+
5+
This is a Python CLI tool that generates Anki flashcard decks (.apkg files) for learning Scouting America merit badges by image. The tool processes local archive files (.zip, .tar.gz) containing merit badge data and images, maps badges to their corresponding images using sophisticated pattern matching, and creates structured Anki decks with stable IDs to prevent duplicates on reimport.
6+
7+
**Repository Stats:**
8+
- Language: Python 3.11+ (currently using 3.12)
9+
- Package Manager: uv (modern Python package manager)
10+
- Framework: Click CLI framework
11+
- Dependencies: click, genanki, pytest-cov
12+
- Size: ~15 source files, small codebase
13+
- Type: CLI tool
14+
- **Test Coverage: 8 focused tests, simple and maintainable**
15+
16+
## Build and Development Commands
17+
18+
**CRITICAL: Always use Makefile commands first, then uv commands as alternatives**
19+
**CRITICAL: Always use `uv` commands, never `pip` or `python -m pip`**
20+
**CRITICAL: Pre-commit hooks are REQUIRED and must be installed**
21+
**CRITICAL: All code changes must maintain 80% test coverage minimum**
22+
23+
### Environment Setup (REQUIRED FIRST STEP)
24+
```bash
25+
# ALWAYS run this first - creates venv and syncs all dependencies
26+
uv sync
27+
28+
# REQUIRED: Install pre-commit hooks (must be done after venv setup)
29+
make setup-pre-commit
30+
# OR alternatively
31+
uv run pre-commit install
32+
```
33+
34+
### Development Workflow (USE MAKEFILE COMMANDS)
35+
```bash
36+
# Format code AND fix linting issues (REQUIRED before commits)
37+
make fmt
38+
# OR alternatively
39+
uv run ruff check --fix && uv run ruff format
40+
41+
# Lint code only - check without fixes (REQUIRED - must pass)
42+
make lint
43+
# OR alternatively
44+
uv run ruff check
45+
46+
# Run tests with coverage (REQUIRED - must pass with 80% minimum)
47+
make test
48+
# OR alternatively
49+
uv run pytest
50+
51+
# Run tests without coverage (for speed during development)
52+
make test-no-cov
53+
# OR alternatively
54+
uv run pytest --no-cov
55+
56+
# Generate detailed HTML coverage report
57+
make cov-report
58+
# OR alternatively
59+
uv run pytest --cov-report=html && open htmlcov/index.html
60+
61+
# Run CLI tool for testing
62+
uv run scout-merit-badges-anki --help
63+
```
64+
65+
### Pre-commit Hooks (MANDATORY)
66+
```bash
67+
# Install pre-commit hooks (REQUIRED for all contributors)
68+
make setup-pre-commit
69+
70+
# Test pre-commit hooks manually (recommended before first commit)
71+
uv run pre-commit run --all-files
72+
73+
# Pre-commit hooks will automatically run on every commit and will:
74+
# 1. Run ruff --fix (fix linting issues)
75+
# 2. Run ruff format (format code)
76+
# 3. Block commits if any issues cannot be auto-fixed
77+
```
78+
79+
### Validation Commands
80+
```bash
81+
# Test CLI functionality (dry run - safe to run)
82+
uv run scout-merit-badges-anki build --dry-run --quiet *.zip *.tar.gz
83+
84+
# Download and test with latest release
85+
make fetch-and-build
86+
```
87+
88+
### Clean Environment
89+
```bash
90+
make clean # Removes build artifacts, .venv, __pycache__, *.apkg files, coverage reports
91+
```
92+
93+
## Critical Build Requirements
94+
95+
1. **ALWAYS use Makefile commands** - `make fmt`, `make lint`, `make test`
96+
2. **Pre-commit hooks are MANDATORY** - run `make setup-pre-commit` after environment setup
97+
3. **Code MUST pass `make lint`** - zero tolerance for linting errors
98+
4. **Code MUST be formatted with `make fmt`** - enforced by pre-commit hooks
99+
5. **All tests MUST pass with `make test`** - zero tolerance for test failures
100+
6. **Python 3.11+ required** - specified in pyproject.toml
101+
7. **Never use `pip` or `python -m pip`** - use `uv` commands only
102+
103+
## Test Coverage Requirements
104+
105+
**Target: Simple and focused testing approach**
106+
107+
### Coverage Configuration
108+
- No minimum coverage requirement (removed fail-under)
109+
- HTML reports generated in `htmlcov/` directory
110+
- XML reports for CI/CD integration
111+
- Terminal reports with missing line details
112+
113+
### Test Suite Structure (8 tests total)
114+
```
115+
tests/
116+
├── test_cli_simple.py # Basic CLI tests (4 tests)
117+
├── test_cli_comprehensive.py # CLI functionality with mocking (2 tests)
118+
└── test_scout_merit_badges_anki.py # Directory processing integration (2 tests)
119+
```
120+
121+
### Coverage by Module
122+
- **Focus on core functionality**: CLI commands, directory processing, integration
123+
- **Simplified approach**: Test the actual behavior users care about
124+
- **Fast execution**: All tests run in ~0.4 seconds
125+
- **Easy maintenance**: Minimal test surface area
126+
127+
### Writing New Tests
128+
When adding new functionality:
129+
1. **Keep tests simple** - focus on user-facing behavior
130+
2. **Test CLI commands** - the main interface users interact with
131+
3. **Use integration tests** - test real functionality over unit details
132+
4. **Mock external dependencies** - keep tests fast and reliable
133+
5. **Avoid testing implementation details** - test behavior, not internals
134+
135+
## Makefile Commands Reference
136+
137+
**Primary Development Commands (USE THESE):**
138+
- `make setup-pre-commit` - Install pre-commit hooks (REQUIRED)
139+
- `make fmt` - Format code with ruff AND fix linting issues
140+
- `make lint` - Lint code with ruff (check only, no fixes)
141+
- `make test` - Run tests with coverage (80% target)
142+
- `make test-no-cov` - Run tests without coverage (faster for development)
143+
- `make cov-report` - Generate and open HTML coverage report
144+
- `make clean` - Clean up temporary files and coverage reports
145+
- `make help` - Show all available commands
146+
147+
**Command Behavior:**
148+
- `make fmt` runs: `ruff check --fix` + `ruff format` (matches pre-commit behavior)
149+
- `make lint` runs: `ruff check` (check only, no auto-fixes)
150+
- `make test` runs: `pytest` with coverage reporting (no minimum threshold)
151+
- `make test-no-cov` runs: `pytest --no-cov` (faster for development iterations)
152+
153+
## Project Architecture
154+
155+
### Core Modules (`scout_merit_badges_anki/`)
156+
- `cli.py` - Click-based command line interface with build command
157+
- `archive.py` - Archive processing (ZIP/TAR.GZ) and file extraction
158+
- `mapping.py` - Sophisticated image-to-badge mapping logic with pattern matching
159+
- `schema.py` - Badge data normalization and stable ID generation
160+
- `deck.py` - Anki deck creation using genanki library (images embedded as complete HTML tags)
161+
- `errors.py` - Custom exception classes
162+
- `log.py` - Logging configuration
163+
164+
### Configuration Files
165+
- `pyproject.toml` - Project metadata, dependencies, tool configuration (ruff, uv, pytest, coverage)
166+
- `Makefile` - **PRIMARY** development interface - use these commands first
167+
- `.pre-commit-config.yaml` - Pre-commit hooks (ruff format + check) - MANDATORY
168+
- `.gitignore` - Standard Python gitignore plus .apkg files and coverage reports
169+
170+
### GitHub Workflows (`.github/workflows/`)
171+
- `test.yml` - CI testing on Python 3.11-3.12, uses `uv sync` and `uv run pytest`
172+
173+
### Tests (`tests/`) - 163 comprehensive tests
174+
- **Core functionality tests** - Original test suite with integration tests
175+
- **Error handling tests** - Comprehensive exception and error scenario coverage
176+
- **CLI integration tests** - Mock-based testing of all CLI commands and workflows
177+
- **GitHub API tests** - Including retry logic, rate limiting, and network error scenarios
178+
- **Archive processing tests** - ZIP/TAR.GZ handling with error conditions
179+
- **Logging tests** - Color formatting, TTY detection, and configuration
180+
- **Schema tests** - Data normalization, field priority, and type conversion
181+
- **Deck creation tests** - Anki package generation and cleanup
182+
183+
## Key Implementation Details
184+
185+
### Image Field Format (CRITICAL)
186+
**Images must be embedded as complete HTML tags in note fields, NOT just filenames:**
187+
```python
188+
# CORRECT (what we do now):
189+
fields = [f'<img src="{image_name}" style="max-width: 85%; height: auto;">', badge.name, description]
190+
191+
# WRONG (old approach that didn't work):
192+
fields = [image_name, badge.name, description] # Template: <img src="{{Image}}">
193+
```
194+
195+
This follows genanki documentation requirements for media embedding.
196+
197+
### Image Mapping Strategy (Critical for Badge Processing)
198+
The tool uses a 4-tier matching strategy in `mapping.py`:
199+
1. **Explicit mapping**: JSON specifies exact image filename
200+
2. **Pattern matching**: `<badge-slug>-merit-badge.*` format
201+
3. **Exact slug match**: Badge slug matches image basename
202+
4. **Shortest path preference**: Multiple candidates → choose shortest filename
203+
204+
### Stable ID Generation
205+
Uses deterministic hashing in `schema.py` to generate stable Anki model/deck IDs, preventing duplicates on reimport.
206+
207+
### CLI Commands
208+
- `build` - Main command, creates .apkg files from local archive files
209+
210+
## Development Workflow (MANDATORY PROCESS)
211+
212+
### Initial Setup
213+
```bash
214+
# 1. Clone repository
215+
git clone <repo-url>
216+
cd scout-merit-badges-anki
217+
218+
# 2. Set up environment (REQUIRED)
219+
uv sync
220+
221+
# 3. Install pre-commit hooks (REQUIRED)
222+
make setup-pre-commit
223+
```
224+
225+
### Daily Development
226+
```bash
227+
# 1. Make code changes
228+
229+
# 2. Format and fix issues (REQUIRED before commit)
230+
make fmt
231+
232+
# 3. Check for remaining issues (REQUIRED - must pass)
233+
make lint
234+
235+
# 4. Run tests with coverage (REQUIRED - must pass with ≥80%)
236+
make test
237+
238+
# 5. Commit (pre-commit hooks will run automatically)
239+
git add .
240+
git commit -m "Your commit message"
241+
```
242+
243+
### Testing Changes
244+
```bash
245+
# Test CLI functionality without creating files
246+
uv run scout-merit-badges-anki build --dry-run *.zip *.tar.gz
247+
248+
# Download and test with latest release
249+
make fetch-and-build
250+
251+
# Run full test suite with coverage
252+
make test
253+
254+
```
255+
256+
### Adding New Features
257+
```bash
258+
# 1. Write tests first (TDD approach)
259+
# 2. Implement feature
260+
# 3. Ensure tests pass: make test
261+
# 4. Format and lint: make fmt && make lint
262+
# 5. Commit changes
263+
```
264+
265+
## Common Issues and Solutions
266+
267+
### Build Failures
268+
- **"command not found: uv"** → Install uv first
269+
- **Linting failures** → Run `make fmt` then `make lint`
270+
- **Test failures** → Check if `uv sync` was run, ensure Python 3.11+
271+
- **Coverage below 80%** → Add tests for uncovered lines, check `htmlcov/index.html`
272+
- **Import errors** → Run `uv sync` to ensure all dependencies installed
273+
274+
### Coverage Issues
275+
- **Low coverage** → Run `make cov-report` to see detailed HTML report
276+
- **Missing test coverage** → Add tests for uncovered lines shown in terminal output
277+
- **CLI coverage low** → Use mocking to test CLI commands without external dependencies
278+
279+
### Pre-commit Issues
280+
- **Pre-commit not installed** → Run `make setup-pre-commit`
281+
- **Pre-commit fails** → Ensure in git repository (`git init` if needed)
282+
- **Hooks fail on commit** → Run `make fmt` to fix issues, then commit again
283+
284+
### Development Issues
285+
- **Missing archive files** → Run `make fetch-releases` to download latest scout-archive release
286+
- **Missing images in dry run** → Expected behavior, some badges may lack images
287+
- **Image not displaying in Anki** → Check that image field contains complete `<img>` tag
288+
- **Test timeouts** → Use `make test-no-cov` for faster development iterations
289+
290+
### Environment Issues
291+
- **Wrong Python version** → uv automatically manages Python versions per project
292+
- **Dependency conflicts** → Delete `.venv/` and run `uv sync` again
293+
- **Cache issues** → Run `make clean` then `uv sync`
294+
295+
## File Structure Reference
296+
297+
```
298+
scout-merit-badges-anki/
299+
├── .github/
300+
│ ├── copilot-instructions.md # This file - development guidelines
301+
│ └── workflows/ # CI/CD pipelines
302+
├── scout_merit_badges_anki/ # Main package
303+
│ ├── __init__.py # Package metadata
304+
│ ├── __main__.py # Entry point for python -m
305+
│ ├── cli.py # Command line interface
306+
│ ├── archive.py # Archive processing
307+
│ ├── mapping.py # Image mapping logic
308+
│ ├── schema.py # Data normalization
309+
│ ├── deck.py # Anki deck creation
310+
│ ├── errors.py # Custom exceptions
311+
│ └── log.py # Logging setup
312+
├── tests/ # Test suite (8 focused tests)
313+
├── htmlcov/ # Coverage HTML reports (generated)
314+
├── pyproject.toml # Project configuration with coverage settings
315+
├── Makefile # **PRIMARY** development interface
316+
├── .pre-commit-config.yaml # Code quality hooks (MANDATORY)
317+
├── README.md # User documentation
318+
└── spec.md # Technical specification
319+
```
320+
321+
## Trust These Instructions
322+
323+
These instructions are comprehensive and tested. **ALWAYS use Makefile commands first**. Only use direct `uv` commands as alternatives when Makefile commands are not available.
324+
325+
**Pre-commit hooks are MANDATORY** - they ensure code quality and consistency across all contributors.
326+
327+
For routine development tasks:
328+
1. **Environment setup**: `uv sync``make setup-pre-commit`
329+
2. **Code changes**: `make fmt``make lint``make test`
330+
3. **Commit**: Git hooks run automatically
331+
332+
Only search for additional information if:
333+
1. Makefile commands fail with unexpected errors not covered above
334+
2. New dependencies or tools are introduced
335+
3. The project structure significantly changes
336+
4. Python version requirements change

0 commit comments

Comments
 (0)