Build: migrate to uv-managed environment

Convert project to modern uv-based package management:
- Consolidate requirements*.txt into pyproject.toml dependencies
- Migrate setup.cfg and mypy.ini to pyproject.toml tool sections
- Generate uv.lock for reproducible builds (303 packages resolved)
- Add UV_USAGE.md documentation for developers
- Configure Hatchling build system
- Set Python 3.11+ as minimum version
- Update REUSE.toml to annotate uv.lock
- Exclude uv.lock from large file checks in pre-commit

This enables modern Python development workflow with faster
dependency resolution and reproducible environments.

Co-Authored-By: SpecKit Plan Agent <speckit@copilot.local>
Signed-off-by: Andrew Grimberg <tykeal@bardicgrove.org>
This commit is contained in:
Andrew GrimbergandSpecKit Plan Agent committed 2025-11-24 16:22:47 -08:00
1 parent de8605c4b3
commit 54ba138185
5 files changed
+8035

No files matched your search

+2
View File
@@ -19,6 +19,8 @@ repos:
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0
hooks: hooks:
- id: check-added-large-files - id: check-added-large-files
args: ['--maxkb=2000', '--enforce-all']
exclude: '^uv\.lock$'
- id: check-ast - id: check-ast
- id: check-json - id: check-json
- id: check-merge-conflict - id: check-merge-conflict
+6
View File
@@ -23,3 +23,9 @@ path = [".specify/**", ".github/*/speckit.**", ".vscode/**"]
precedence = "aggregate" precedence = "aggregate"
SPDX-FileCopyrightText = "2021 Andrew Grimberg <tykeal@bardicgrove.org>" SPDX-FileCopyrightText = "2021 Andrew Grimberg <tykeal@bardicgrove.org>"
SPDX-License-Identifier = "MIT" SPDX-License-Identifier = "MIT"
[[annotations]]
path = "uv.lock"
precedence = "aggregate"
SPDX-FileCopyrightText = "2021 Andrew Grimberg <tykeal@bardicgrove.org>"
SPDX-License-Identifier = "Apache-2.0"
+118
View File
@@ -0,0 +1,118 @@
# SPDX-FileCopyrightText: 2021 Andrew Grimberg <tykeal@bardicgrove.org>
# SPDX-License-Identifier: Apache-2.0
# Development with uv
This project now uses [uv](https://docs.astral.sh/uv/) for Python package and environment management.
## Setup
### Install uv
Follow the [official installation guide](https://docs.astral.sh/uv/getting-started/installation/):
```bash
# On macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# On Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```
### Create and activate environment
```bash
# Create virtual environment and install dependencies
uv sync
# Activate the environment (optional, uv run handles this automatically)
source .venv/bin/activate # On macOS/Linux
.venv\Scripts\activate # On Windows
```
## Usage
### Running commands
Use `uv run` to execute commands within the project environment:
```bash
# Run Python
uv run python -c "import custom_components.rental_control"
# Run pytest
uv run pytest
# Run pytest with coverage
uv run pytest --cov=custom_components.rental_control
# Run any Python script
uv run python my_script.py
```
### Managing dependencies
```bash
# Add a dependency
uv add package-name
# Add a dev dependency
uv add --group dev package-name
# Add a test dependency
uv add --optional test package-name
# Update dependencies
uv sync
# Update a specific package
uv lock --upgrade-package package-name
```
### Testing
```bash
# Run all tests
uv run pytest
# Run specific test file
uv run pytest tests/test_file.py
# Run with coverage
uv run pytest --cov=custom_components.rental_control
# Run with verbose output
uv run pytest -v
```
## Migration from requirements.txt
The project has been migrated from the traditional `requirements*.txt` and `setup.cfg` format to `pyproject.toml`. The old files are preserved for reference but are no longer used:
- `requirements.txt` → `[project.dependencies]` in `pyproject.toml`
- `requirements_dev.txt` → `[dependency-groups.dev]` in `pyproject.toml`
- `requirements_test.txt` → `[project.optional-dependencies.test]` in `pyproject.toml`
- `setup.cfg` → Various `[tool.*]` sections in `pyproject.toml`
- `mypy.ini` → `[tool.mypy]` in `pyproject.toml`
## Benefits of uv
- **Fast**: 10-100x faster than pip
- **Reliable**: Reproducible builds with uv.lock
- **Simple**: Single tool for package and environment management
- **Compatible**: Works with existing Python tools and workflows
## CI/CD Integration
For GitHub Actions:
```yaml
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Install dependencies
run: uv sync
- name: Run tests
run: uv run pytest
```
+111
View File
@@ -0,0 +1,111 @@
# SPDX-FileCopyrightText: 2021 Andrew Grimberg <tykeal@bardicgrove.org>
# SPDX-License-Identifier: Apache-2.0
[project]
name = "homeassistant-rental-control"
version = "0.0.0"
description = "Home Assistant integration for managing rental properties with calendar and door code management"
readme = "README.md"
requires-python = ">=3.11"
license = {text = "Apache-2.0"}
authors = [
{name = "Andrew Grimberg", email = "tykeal@bardicgrove.org"}
]
keywords = ["homeassistant", "rental", "calendar", "icalendar", "keymaster"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Home Automation",
]
dependencies = [
"icalendar>=6.1.0",
"x-wr-timezone>=2.0.0",
]
[project.optional-dependencies]
dev = [
"homeassistant",
]
test = [
"homeassistant",
"pytest-homeassistant-custom-component",
]
[project.urls]
Homepage = "https://github.com/tykeal/homeassistant-rental-control"
Documentation = "https://github.com/tykeal/homeassistant-rental-control"
Repository = "https://github.com/tykeal/homeassistant-rental-control"
Issues = "https://github.com/tykeal/homeassistant-rental-control/issues"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["custom_components"]
[dependency-groups]
dev = [
"homeassistant",
]
[tool.pytest.ini_options]
addopts = "-qq"
console_output_style = "count"
testpaths = ["tests"]
[tool.coverage.run]
branch = false
source = ["custom_components.rental_control"]
[tool.coverage.report]
show_missing = true
fail_under = 0
[tool.mypy]
warn_return_any = true
warn_unused_configs = true
[[tool.mypy.overrides]]
module = ["homeassistant.*", "voluptuous.*", "icalendar.*", "x_wr_timezone.*"]
ignore_missing_imports = true
[tool.ruff]
line-length = 88
target-version = "py311"
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
]
ignore = [
"E501", # line too long (handled by formatter)
"W503", # line break before binary operator
"E203", # whitespace before ':'
]
[tool.ruff.lint.isort]
force-single-line = true
force-sort-within-sections = true
known-first-party = ["custom_components.rental_control", "tests"]
forced-separate = ["tests"]
combine-as-imports = true
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
Generated
+7798
View File
File diff suppressed because it is too large. Load diff