Skip to content
Next Next commit
feat: Improve local dev experience with file-aware hooks and auto par…
…allelization

- Make precommit hooks file-aware: format and lint only changed Python files
- Add conditional template hook that only runs when template files change
- Update test-python-integration-local to use -n auto and --dist loadscope
- Add new pytest markers: slow, cloud, local_only for better test selection
- Add format-python-files and lint-python-files Makefile targets

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
  • Loading branch information
2 people authored and ntkathole committed Feb 11, 2026
commit 82ae1097a2e07d233ff371872a34f7a073d1616e
24 changes: 16 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,29 @@ default_stages: [commit]
repos:
- repo: local
hooks:
- id: format
name: Format
# File-aware format hook - only runs on changed Python files
- id: format-files
name: Format Changed Files
stages: [commit]
language: system
entry: make format-python
pass_filenames: false
- id: lint
name: Lint
types: [python]
entry: uv run ruff check --fix
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Outdated
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Run Ruff formatter in the file-aware format hook

The new format-files hook only runs ruff check --fix, which does not apply ruff format styling. Since the paired lint hook also skips ruff format --check, commits can pass local pre-commit while still failing the repository's standard lint path (make lint-python) on formatting checks. This is a regression from the previous hook behavior that ran full formatting before commit.

Useful? React with 👍 / 👎.

pass_filenames: true

# File-aware lint hook - only runs on changed Python files
- id: lint-files
name: Lint Changed Files
stages: [commit]
language: system
entry: make lint-python
pass_filenames: false
types: [python]
entry: uv run ruff check
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Outdated
pass_filenames: true

# Conditional template hook - only runs when template files change
- id: template
name: Build Templates
stages: [commit]
language: system
files: ^infra/templates/|\.jinja2$
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include roadmap inputs in template-hook file filter

Restricting the template hook to ^infra/templates/|\.jinja2$ means make build-templates will no longer run when docs/roadmap.md changes, even though infra/scripts/compile-templates.py reads that file to regenerate README.md. In that scenario, commits can update the roadmap without updating the generated README, leaving checked-in docs inconsistent until someone runs the build manually.

Useful? React with 👍 / 👎.

entry: make build-templates
pass_filenames: false
20 changes: 19 additions & 1 deletion Makefile
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,29 @@ format-python: ## Format Python code
uv run ruff check --fix sdk/python/feast/ sdk/python/tests/
uv run ruff format sdk/python/feast/ sdk/python/tests/

# File-aware format (for use with pre-commit, accepts file args)
format-python-files: ## Format specified Python files
@if [ -n "$(FILES)" ]; then \
uv run ruff check --fix $(FILES); \
uv run ruff format $(FILES); \
else \
echo "Usage: make format-python-files FILES='file1.py file2.py'"; \
fi
Comment thread
franciscojavierarceo marked this conversation as resolved.
Outdated

lint-python: ## Lint Python code
uv run ruff check sdk/python/feast/ sdk/python/tests/
uv run ruff format --check sdk/python/feast/ sdk/python/tests/
uv run bash -c "cd sdk/python && mypy feast"

# File-aware lint (for use with pre-commit, accepts file args)
lint-python-files: ## Lint specified Python files
@if [ -n "$(FILES)" ]; then \
uv run ruff check $(FILES); \
uv run ruff format --check $(FILES); \
else \
echo "Usage: make lint-python-files FILES='file1.py file2.py'"; \
fi
Comment thread
franciscojavierarceo marked this conversation as resolved.
Outdated

# New combined target
precommit-check: format-python lint-python ## Run all precommit checks
@echo "✅ All precommit checks passed"
Expand Down Expand Up @@ -209,7 +227,7 @@ test-python-integration-local: ## Run Python integration tests (local dev mode)
HADOOP_HOME=$$HOME/hadoop \
CLASSPATH="$$( $$HADOOP_HOME/bin/hadoop classpath --glob ):$$CLASSPATH" \
HADOOP_USER_NAME=root \
uv run python -m pytest --tb=short -v -n 8 --color=yes --integration --durations=10 --timeout=1200 --timeout_method=thread --dist loadgroup \
uv run python -m pytest --tb=short -v -n auto --color=yes --integration --durations=10 --timeout=1200 --timeout_method=thread --dist loadscope \
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Outdated
-k "not test_lambda_materialization and not test_snowflake_materialization" \
-m "not rbac_remote_integration_test" \
--log-cli-level=INFO -s \
Expand Down
3 changes: 3 additions & 0 deletions sdk/python/pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ markers =
rbac_remote_integration_test: RBAC and remote functionality tests
integration: Integration tests (slower, requires services)
benchmark: Benchmark tests
slow: Tests taking >30 seconds
cloud: Tests requiring cloud credentials
local_only: Tests that run entirely locally

timeout = 300
timeout_method = thread
Expand Down