hass.tibber_prices/docs/development/coding-guidelines.md
Julian Pawlowski 503075c443 refactor(config_flow): restructure package to satisfy hassfest validation
Home Assistant's hassfest validation requires config flows to be defined
in a file named config_flow.py (not a package directory).

Changes:
- Renamed custom_components/tibber_prices/config_flow/ → config_flow_handlers/
- Created config_flow.py as bridge file re-exporting from config_flow_handlers/
- Updated all import paths across 5 files (user_flow, options_flow, subentry_flow, etc.)
- Added ./scripts/hassfest for local validation (JSON/Python syntax, required files)
- Added ./scripts/clean with three modes (--minimal, normal, --deep)
- Refactored develop/lint/lint-check to use centralized cleanup (DRY principle)
- Updated documentation in AGENTS.md and docs/development/

Technical details:
- Bridge file uses __all__ exports to maintain clean public API
- hassfest script uses ast.parse() for syntax validation (no disk artifacts)
- clean --minimal removes .egg-info only (silent, for automated scripts)
- Dual pip/uv pip compatibility for package uninstallation

Impact: Integration now passes hassfest validation. Local validation available
via ./scripts/hassfest before pushing to GitHub. Cleanup logic centralized and
DRY across all development scripts.
2025-11-15 17:40:53 +00:00

60 lines
1.3 KiB
Markdown

# Coding Guidelines
> **Note:** For complete coding standards, see [`AGENTS.md`](../../AGENTS.md).
## Code Style
- **Formatter/Linter**: Ruff (replaces Black, Flake8, isort)
- **Max line length**: 120 characters
- **Max complexity**: 25 (McCabe)
- **Target**: Python 3.13
Run before committing:
```bash
./scripts/lint # Auto-fix issues
./scripts/hassfest # Validate integration structure
```
## Import Order
1. Python stdlib (specific types only)
2. Third-party (`homeassistant.*`, `aiohttp`)
3. Local (`.api`, `.const`)
## Critical Patterns
### Time Handling
Always use `dt_util` from `homeassistant.util`:
```python
from homeassistant.util import dt as dt_util
price_time = dt_util.parse_datetime(starts_at)
price_time = dt_util.as_local(price_time) # Convert to HA timezone
now = dt_util.now()
```
### Translation Loading
```python
# In __init__.py async_setup_entry:
await async_load_translations(hass, "en")
await async_load_standard_translations(hass, "en")
```
### Price Data Enrichment
Always enrich raw API data:
```python
from .price_utils import enrich_price_info_with_differences
enriched = enrich_price_info_with_differences(
price_info_data,
thresholds,
)
```
See [`AGENTS.md`](../../AGENTS.md) for complete guidelines.