diff --git a/docs/development/code-quality.md b/docs/development/code-quality.md new file mode 100644 index 00000000..3564f540 --- /dev/null +++ b/docs/development/code-quality.md @@ -0,0 +1,345 @@ +# Code Quality + +This guide covers the code quality tools and standards used in the Wizamart platform. + +## Overview + +The project uses modern Python tooling to maintain high code quality: + +- **Ruff** - All-in-one linter and formatter (replaces black, isort, flake8, and more) +- **mypy** - Static type checker +- **pytest** - Testing framework with coverage reporting + +All tools are configured in `pyproject.toml` for consistency and ease of use. + +## Quick Start + +```bash +# Format code +make format + +# Lint and auto-fix issues +make lint + +# Run both formatting and linting +make check + +# Strict linting (no auto-fix) - for CI/CD +make lint-strict +``` + +## Ruff - Modern Linting and Formatting + +Ruff is a blazingly fast Python linter and formatter written in Rust. It replaces multiple tools with a single, comprehensive solution. + +### What Ruff Does + +**Formatting** (replaces black): +- Consistent code style +- Automatic quote normalization +- Line length enforcement (88 characters) + +**Linting** (replaces flake8, isort, pyupgrade, and more): +- Import sorting and organization +- Code style checks (PEP 8) +- Bug detection (flake8-bugbear) +- Modern Python syntax suggestions (pyupgrade) +- Code simplification suggestions + +### Enabled Rule Sets + +| Code | Description | Purpose | +|------|-------------|---------| +| E, W | pycodestyle | PEP 8 style enforcement | +| F | pyflakes | Basic error detection | +| I | isort | Import sorting | +| N | pep8-naming | Naming conventions | +| UP | pyupgrade | Modern Python syntax | +| B | flake8-bugbear | Common bug patterns | +| C4 | flake8-comprehensions | Better comprehensions | +| SIM | flake8-simplify | Code simplification | +| PIE | flake8-pie | Misc. lints | +| RET | flake8-return | Return statement improvements | +| Q | flake8-quotes | Quote consistency | + +### Usage + +```bash +# Format all code +make format +# or directly: +python -m ruff format . + +# Lint and auto-fix issues +make lint +# or directly: +python -m ruff check . --fix + +# Check without fixing (CI/CD) +make lint-strict +# or directly: +python -m ruff check . +``` + +### Configuration + +Ruff is configured in `pyproject.toml`: + +```toml +[tool.ruff] +line-length = 88 +target-version = "py311" +exclude = [".git", ".venv", "venv", "__pycache__", "alembic/versions"] + +[tool.ruff.lint] +select = ["E", "W", "F", "I", "N", "UP", "B", "C4", "SIM", "PIE", "RET", "Q"] +ignore = ["E501", "B008", "RET504", "SIM102"] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +``` + +## mypy - Type Checking + +mypy performs static type analysis to catch type-related errors before runtime. + +### Usage + +```bash +# Run type checking +python -m mypy . + +# Or as part of lint +make lint +``` + +### Configuration + +mypy is configured in `pyproject.toml`: + +```toml +[tool.mypy] +python_version = "3.11" +warn_return_any = true +warn_unused_configs = true +ignore_missing_imports = true +exclude = ["^\\.venv/", "^venv/", "^alembic/versions/"] +``` + +## Testing with pytest + +Run tests with coverage reporting: + +```bash +# Run all tests +make test + +# Run with coverage +make test-coverage + +# Run only unit tests +make test-unit + +# Run only integration tests +make test-integration + +# Run fast tests (skip slow ones) +make test-fast +``` + +### Coverage Configuration + +Coverage settings are in `pyproject.toml`: + +```toml +[tool.coverage.run] +source = ["app", "models", "middleware", "tasks", "storage"] +omit = ["*/tests/*", "*/venv/*", "*/alembic/*"] + +[tool.coverage.report] +precision = 2 +show_missing = true +``` + +## Makefile Commands + +### Code Quality Commands + +| Command | Description | When to Use | +|---------|-------------|-------------| +| `make format` | Format code with Ruff | Before committing | +| `make lint` | Lint and auto-fix with Ruff + mypy | Before committing | +| `make lint-strict` | Lint without auto-fix + mypy | In CI/CD pipelines | +| `make check` | Run format + lint | Quick pre-commit check | +| `make ci` | Full CI pipeline (strict lint + coverage) | CI/CD workflows | +| `make qa` | Quality assurance (format + lint + coverage + docs) | Before releases | + +### Testing Commands + +| Command | Description | +|---------|-------------| +| `make test` | Run all tests | +| `make test-unit` | Run unit tests only | +| `make test-integration` | Run integration tests only | +| `make test-coverage` | Run tests with coverage report | +| `make test-fast` | Run fast tests (skip slow ones) | + +## Pre-Commit Workflow + +Before committing code: + +```bash +# 1. Format and lint your code +make check + +# 2. Run relevant tests +make test-fast + +# 3. If all passes, commit +git add . +git commit -m "your message" +``` + +## CI/CD Integration + +For continuous integration: + +```bash +# Use strict mode (no auto-fixes) +make ci +``` + +This will: +1. Run strict linting (fails on any issues) +2. Run type checking with mypy +3. Run full test suite with coverage + +## IDE Integration + +### VSCode + +Install these extensions: +- Ruff (charliermarsh.ruff) +- Python (ms-python.python) + +Add to `.vscode/settings.json`: + +```json +{ + "[python]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.codeActionsOnSave": { + "source.fixAll": true, + "source.organizeImports": true + } + }, + "ruff.enable": true, + "ruff.lint.enable": true +} +``` + +### PyCharm + +1. Go to Settings → Tools → External Tools +2. Add Ruff: + - Program: `python` + - Arguments: `-m ruff check $FilePath$ --fix` + - Working directory: `$ProjectFileDir$` + +## Common Issues + +### Import Order + +Ruff automatically organizes imports into sections: +1. Future imports +2. Standard library +3. Third-party packages +4. First-party packages (app, models, middleware, tasks, storage, scripts) +5. Local folder imports + +### Line Length + +Default line length is 88 characters (black's default). Long lines are automatically wrapped. + +### Type Hints + +While not strictly enforced, adding type hints improves code quality: + +```python +# Good +def get_user(user_id: int) -> User: + return db.query(User).get(user_id) + +# Better with Optional +from typing import Optional + +def get_user(user_id: int) -> Optional[User]: + return db.query(User).get(user_id) +``` + +## Ignoring Rules + +### Per-File Ignores + +Configure in `pyproject.toml`: + +```toml +[tool.ruff.lint.per-file-ignores] +"__init__.py" = ["F401"] # Allow unused imports +"tests/**/*.py" = ["S101"] # Allow assert statements +``` + +### Inline Ignores + +Use `# noqa` comments sparingly: + +```python +# Ignore specific rule +example = lambda x: x + 1 # noqa: E731 + +# Ignore all rules for line +long_url = "https://..." # noqa +``` + +## Best Practices + +1. **Run `make check` before every commit** +2. **Let Ruff auto-fix issues** - don't fight the formatter +3. **Add type hints** for better code quality +4. **Keep test coverage above 80%** +5. **Use meaningful variable names** that pass naming checks +6. **Avoid broad exception catches** - be specific +7. **Use pathlib** instead of os.path when possible +8. **Keep functions focused** - if it's complex, break it down + +## Migration from Old Tools + +If you were using black, isort, or flake8 before: + +| Old Tool | New Tool | Notes | +|----------|----------|-------| +| black | ruff format | 100% compatible | +| isort | ruff check --select I | Built into Ruff linting | +| flake8 | ruff check | Faster, more comprehensive | +| pyupgrade | ruff check --select UP | Built into Ruff | + +All configurations have been migrated to `pyproject.toml`. + +## Performance + +Ruff is **10-100x faster** than the tools it replaces: + +- **black**: ~2s → ruff: ~0.1s +- **isort**: ~3s → ruff: ~0.1s +- **flake8**: ~10s → ruff: ~0.2s + +This means faster CI/CD pipelines and better developer experience. + +## Resources + +- [Ruff Documentation](https://docs.astral.sh/ruff/) +- [Ruff Rules](https://docs.astral.sh/ruff/rules/) +- [mypy Documentation](https://mypy.readthedocs.io/) +- [pytest Documentation](https://docs.pytest.org/) diff --git a/docs/development/contributing.md b/docs/development/contributing.md index e69de29b..8e0b9cd6 100644 Binary files a/docs/development/contributing.md and b/docs/development/contributing.md differ diff --git a/mkdocs.yml b/mkdocs.yml index 3461b73b..3d90b21f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -101,6 +101,9 @@ nav: # DEVELOPMENT (Shared Development Resources) # ============================================ - Development: + - Contributing Guide: development/contributing.md + - Code Quality: development/code-quality.md + - Code Quality Dashboard: development/code-quality-dashboard-implementation.md - Icons Guide: development/icons-guide.md - Naming Conventions: development/naming-conventions.md - Auth Dependencies Guide: development/auth-dependencies-guide.md