hass.tibber_prices/docs/development/coding-guidelines.md
Julian Pawlowski a90fef6f2d refactor(scripts): reorganize and standardize development scripts
Major restructuring of the scripts/ directory with consistent output
formatting, improved organization, and stricter error handling.

Breaking Changes:
- Updated development environment to Home Assistant 2025.7+
  - Removed Python 3.12 compatibility (HA 2025.7+ requires Python 3.13)
  - Updated all HA core requirements from 2025.7 requirement files
  - Added new dependencies: python-multipart, uv (for faster package management)
  - Updated GitHub Actions workflows to use Python 3.13

Changes:
- Created centralized output library (scripts/.lib/output.sh)
  - Unified color codes and Unicode symbols
  - Consistent formatting functions (log_header, log_success, log_error, etc.)
  - Support for embedded formatting codes (${BOLD}, ${GREEN}, etc.)

- Reorganized into logical subdirectories:
  - scripts/setup/ - Setup and maintenance scripts
    - bootstrap: Install/update dependencies (used in CI/CD)
    - setup: Full DevContainer setup (pyright, copilot, HACS)
    - reset: Reset config/ directory to fresh state (NEW)
    - sync-hacs: Sync HACS integrations
  - scripts/release/ - Release management scripts
    - prepare: Version bump and tagging
    - suggest-version: Semantic version suggestion
    - generate-notes: Release notes generation
    - check-if-released: Check release status
    - hassfest: Local integration validation

- Updated all scripts with:
  - set -euo pipefail for stricter error handling
  - Consistent SCRIPT_DIR pattern for reliable sourcing
  - Professional output with colors and emojis
  - Unified styling across all 17 scripts

- Removed redundant scripts:
  - scripts/update (was just wrapper around bootstrap)
  - scripts/json_schemas/ (moved to schemas/json/)

- Enhanced clean script:
  - Improved artifact cleanup
  - Better handling of accidental package installations
  - Hints for reset and deep clean options

- New reset script features:
  - Standard mode: Keep configuration.yaml
  - Full mode (--full): Reset configuration.yaml from git
  - Automatic re-setup after reset

- Updated documentation:
  - AGENTS.md: Updated script references and workflow guidance
  - docs/development/: Updated all references to new script structure

Impact: Development environment now requires Python 3.13 and Home Assistant
2025.7+. Developers get consistent, professional script output with better
error handling and logical organization. Single source of truth for styling
makes future updates trivial.
2025-11-26 13:11:52 +00:00

117 lines
2.9 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/release/hassfest # Validate integration structure
```
## Naming Conventions
### Class Names
**All public classes MUST use the integration name as prefix.**
This is a Home Assistant standard to avoid naming conflicts between integrations.
```python
# ✅ CORRECT
class TibberPricesApiClient:
class TibberPricesDataUpdateCoordinator:
class TibberPricesSensor:
# ❌ WRONG - Missing prefix
class ApiClient:
class DataFetcher:
class TimeService:
```
**When prefix is required:**
- Public classes used across multiple modules
- All exception classes
- All coordinator and entity classes
- Data classes (dataclasses, NamedTuples) used as public APIs
**When prefix can be omitted:**
- Private helper classes within a single module (prefix with `_` underscore)
- Type aliases and callbacks (e.g., `TimeServiceCallback`)
- Small internal NamedTuples for function returns
**Private Classes:**
If a helper class is ONLY used within a single module file, prefix it with underscore:
```python
# ✅ Private class - used only in this file
class _InternalHelper:
"""Helper used only within this module."""
pass
# ❌ Wrong - no prefix but used across modules
class DataFetcher: # Should be TibberPricesDataFetcher
pass
```
**Note:** Currently (Nov 2025), this project has **NO private classes** - all classes are used across module boundaries.
**Current Technical Debt:**
Many existing classes lack the `TibberPrices` prefix. Before refactoring:
1. Document the plan in `/planning/class-naming-refactoring.md`
2. Use `multi_replace_string_in_file` for bulk renames
3. Test thoroughly after each module
See [`AGENTS.md`](../../AGENTS.md) for complete list of classes needing rename.
## 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.