Skip to content

Commit f86a05e

Browse files
committed
.
1 parent 71cf298 commit f86a05e

5 files changed

Lines changed: 157 additions & 74 deletions

File tree

.kiro/specs/black-to-ruff-migration/design.md

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,32 @@ Ruff will be configured in `pyproject.toml` using the `[tool.ruff]` section with
2828

2929
#### pyproject.toml Updates
3030

31+
**Rationale**: Centralizing all tool configuration in pyproject.toml follows Python packaging standards and simplifies maintenance.
32+
3133
- Remove `[tool.black]` section
3234
- Remove `[tool.isort]` section
3335
- Add comprehensive `[tool.ruff]` configuration
3436
- Add Ruff as a development dependency in the "# Development & Debugging" section alongside django-debug-toolbar
37+
- Remove Black and isort from dependencies if present
3538

3639
#### Pre-commit Configuration Updates
3740

41+
**Rationale**: Maintaining pre-commit integration ensures code quality checks remain automated and consistent across the development team.
42+
3843
- Replace Black hook (currently using psf/black rev 23.3.0) with Ruff formatter hook
3944
- Replace isort hook (currently using pycqa/isort rev 5.12.0) with Ruff import sorting hook
4045
- Maintain existing exclusion patterns for migrations and .vscode folders
4146
- Keep all other pre-commit hooks unchanged (trailing-whitespace, end-of-file-fixer, etc.)
4247

4348
#### Documentation Updates
4449

50+
**Rationale**: Comprehensive documentation updates ensure all team members and new contributors understand the current tooling and maintain consistency across the project.
51+
4552
- Update `.kiro/steering/tech.md` Code Quality Tools section to reference Ruff instead of Black and isort
4653
- Update `.kiro/steering/structure.md` Development Conventions section to reference Ruff formatting
4754
- Check and update `README.md` if it contains references to Black or isort
4855
- Update any developer setup instructions to include Ruff-specific commands
49-
- Ensure all documentation maintains consistency with Ruff usage and 79-character line length
56+
- Ensure all documentation maintains consistency with Ruff usage
5057

5158
### Ruff Configuration Sections
5259

@@ -56,39 +63,15 @@ Based on the current Black and isort configuration, Ruff will be configured as f
5663

5764
```toml
5865
[tool.ruff]
59-
line-length = 79
6066
target-version = "py311"
6167
exclude = [migrations, build artifacts, etc.]
6268
```
6369

64-
#### Formatter Settings
65-
66-
```toml
67-
[tool.ruff.format]
68-
quote-style = "double"
69-
indent-style = "space"
70-
skip-source-first-line = false
71-
line-ending = "auto"
72-
```
73-
7470
#### Import Sorting Settings
7571

76-
```toml
77-
[tool.ruff.isort]
78-
known-django = ["django"]
79-
section-order = ["future", "standard-library", "django", "third-party", "first-party", "local-folder"]
80-
combine-as-imports = true
81-
force-wrap-aliases = true
82-
split-on-trailing-comma = true
83-
```
72+
**Rationale**: Django-aware import sorting maintains the existing project's import organization patterns while leveraging Ruff's performance benefits. This ensures proper separation of Django imports from other third-party libraries, maintaining the project's existing import organization standards.
8473

85-
#### Linting Rules
8674

87-
```toml
88-
[tool.ruff.lint]
89-
select = ["E", "F", "W", "I"] # Basic error, warning, and import rules
90-
ignore = [] # Project-specific ignores if needed
91-
```
9275

9376
## Data Models
9477

@@ -119,11 +102,15 @@ No data models are affected by this migration as it only changes development too
119102

120103
### Validation Steps
121104

105+
**Rationale**: These validation steps ensure the migration maintains code quality and formatting consistency while verifying all requirements are met.
106+
122107
1. Install Ruff and configure in pyproject.toml
123-
2. Run `ruff format --check` on codebase to verify compatibility
124-
3. Run `ruff check --select I` to test import sorting
125-
4. Test pre-commit hooks in isolated environment
126-
5. Compare output with existing Black/isort formatting
108+
2. Run `docker compose run --rm app uv run ruff format --check .` on codebase to verify compatibility (respects pyproject.toml settings)
109+
3. Run `docker compose run --rm app uv run ruff check --select I .` to test import sorting (respects pyproject.toml settings)
110+
4. Test pre-commit hooks in containerized environment using `docker compose run --rm app pre-commit run --all-files`
111+
5. Compare output with existing Black/isort formatting to ensure consistency
112+
6. Verify uv commands work correctly with Ruff (addresses Requirement 4.4)
113+
7. Confirm migrations are properly excluded from formatting and linting
127114

128115
### Performance Verification
129116

@@ -134,9 +121,11 @@ No data models are affected by this migration as it only changes development too
134121

135122
### Dependency Management
136123

137-
- Ruff will be added to the "# Development & Debugging" section in pyproject.toml dependencies (following the existing organizational pattern where development tools like django-debug-toolbar are grouped)
138-
- Black and isort configurations will be removed from pyproject.toml (they are not explicitly listed as dependencies, only configured)
139-
- uv will handle Ruff installation and version management
124+
**Rationale**: Proper dependency management ensures Ruff is available in all development environments and follows the project's existing organizational patterns.
125+
126+
- Ruff will be added to the "# Development & Debugging" section in pyproject.toml dependencies (addresses Requirement 4.1, 4.3)
127+
- Black and isort configurations will be removed from pyproject.toml (addresses Requirement 4.2)
128+
- uv will handle Ruff installation and version management (addresses Requirement 4.4)
140129
- Ruff will be placed appropriately within the development tools section to maintain logical grouping
141130

142131
### Backward Compatibility
@@ -150,3 +139,15 @@ No data models are affected by this migration as it only changes development too
150139
- Developers will need to update their local pre-commit hooks
151140
- IDE integrations may need to be updated to use Ruff instead of Black
152141
- Documentation will guide developers through the transition
142+
143+
## Requirements Traceability
144+
145+
This design addresses all requirements from the requirements document:
146+
147+
**Requirement 1 (Tool Replacement)**: Addressed through pyproject.toml configuration sections that replace Black and isort with Ruff while maintaining migration exclusions, and Django-aware import sorting.
148+
149+
**Requirement 2 (Pre-commit Integration)**: Addressed through pre-commit configuration updates that replace Black and isort hooks with Ruff equivalents while maintaining existing exclusion patterns.
150+
151+
**Requirement 3 (Documentation Updates)**: Addressed through systematic updates to steering documents, README, and developer setup instructions to reflect Ruff usage consistently.
152+
153+
**Requirement 4 (Dependency Management)**: Addressed through adding Ruff to development dependencies and removing Black/isort configurations, with uv handling installation and version management.

.kiro/specs/black-to-ruff-migration/requirements.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,14 @@ This feature involves migrating the We All Code Django project from using Black
1414

1515
1. WHEN the project is configured THEN Ruff SHALL replace Black as the code formatter
1616
2. WHEN the project is configured THEN Ruff SHALL replace isort for import sorting
17-
3. WHEN Ruff is configured THEN it SHALL maintain the existing 79-character line length
18-
4. WHEN Ruff is configured THEN it SHALL exclude migrations from formatting (same as current Black config)
19-
5. WHEN Ruff is configured THEN it SHALL maintain Django-aware import sorting sections
17+
3. WHEN Ruff is configured THEN it SHALL exclude migrations from formatting (same as current Black config)
18+
4. WHEN Ruff is configured THEN it SHALL maintain Django-aware import sorting sections with proper separation of Django imports from other third-party libraries
2019

2120
### Requirement 2: Pre-commit Integration
2221

2322
**User Story:** As a developer, I want the pre-commit hooks updated to use Ruff, so that code quality checks run automatically before commits.
2423

25-
#### Pre-commit Acceptance Criteria
24+
#### Acceptance Criteria
2625

2726
1. WHEN pre-commit hooks are updated THEN they SHALL use Ruff instead of Black and isort
2827
2. WHEN pre-commit runs THEN it SHALL format code using Ruff
@@ -33,20 +32,19 @@ This feature involves migrating the We All Code Django project from using Black
3332

3433
**User Story:** As a developer, I want all project documentation updated to reflect the Ruff migration, so that new contributors understand the current tooling and existing developers have accurate reference materials.
3534

36-
#### Documentation Acceptance Criteria
35+
#### Acceptance Criteria
3736

3837
1. WHEN documentation is updated THEN .kiro/steering/tech.md SHALL reference Ruff instead of Black and isort in the Code Quality Tools section
3938
2. WHEN documentation is updated THEN .kiro/steering/structure.md SHALL reference Ruff formatting conventions instead of Black
4039
3. WHEN documentation is updated THEN README.md SHALL be updated if it contains references to Black or isort
4140
4. WHEN documentation is updated THEN any developer setup instructions SHALL include Ruff-specific commands
4241
5. WHEN documentation is updated THEN all references to code formatting tools SHALL be consistent with Ruff usage
43-
6. WHEN documentation is updated THEN it SHALL maintain accuracy about the 79-character line length requirement
4442

4543
### Requirement 4: Dependency Management
4644

4745
**User Story:** As a developer, I want Ruff to be added as a project dependency, so that it's available in the development environment.
4846

49-
#### Dependency Acceptance Criteria
47+
#### Acceptance Criteria
5048

5149
1. WHEN dependencies are updated THEN Ruff SHALL be added to pyproject.toml
5250
2. WHEN dependencies are updated THEN Black and isort SHALL be removed from dependencies (if present)

.kiro/specs/black-to-ruff-migration/tasks.md

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@
33
- [x] 1. Configure Ruff in pyproject.toml
44

55
- Remove existing [tool.black] and [tool.isort] configuration sections
6-
- Add comprehensive [tool.ruff] configuration with general settings (line-length = 79, target-version = "py311", exclude migrations)
7-
- Add [tool.ruff.format] section with Black-compatible settings (quote-style = "double", indent-style = "space")
8-
- Add [tool.ruff.isort] section with Django-aware import sorting (known-django, section-order, combine-as-imports)
9-
- Add [tool.ruff.lint] section with basic linting rules (select = ["E", "F", "W", "I"])
6+
- Add comprehensive [tool.ruff] configuration with general settings (target-version = "py311", exclude migrations)
107
- Add Ruff as a development dependency in the "# Development & Debugging" section alongside django-debug-toolbar
8+
- Add [tool.ruff.lint] section with comprehensive linting rules
119
- _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 4.1, 4.2, 4.3, 4.4_
1210

1311
- [x] 2. Update pre-commit configuration
1412

1513
- Replace Black hook (psf/black) with Ruff formatter hook (charliermarsh/ruff-pre-commit)
16-
- Replace isort hook (pycqa/isort) with Ruff import sorting hook using --select I flag
14+
- Replace isort hook (pycqa/isort) with Ruff import sorting hook using ruff-check
1715
- Maintain existing exclusion patterns for migrations and .vscode folders
1816
- Keep all other pre-commit hooks unchanged (trailing-whitespace, end-of-file-fixer, etc.)
1917
- _Requirements: 2.1, 2.2, 2.3, 2.4_
@@ -23,7 +21,6 @@
2321

2422
- Replace Black and isort references with Ruff in Code Quality Tools section
2523
- Update tool descriptions to reflect Ruff's combined formatting and linting capabilities
26-
- Maintain 79-character line length documentation
2724
- _Requirements: 3.1, 3.6_
2825

2926
- [x] 3.2 Update .kiro/steering/structure.md
@@ -35,29 +32,35 @@
3532

3633
- [x] 3.3 Check and update README.md if needed
3734

38-
- Search for any references to Black or isort in README.md
39-
- Update developer setup instructions to include Ruff-specific commands if present
35+
- Search for any references to Black or isort in README.md (none found)
36+
- Update developer setup instructions to include Ruff-specific commands if present (none needed)
4037
- Ensure consistency with Ruff usage throughout documentation
4138
- _Requirements: 3.3, 3.4, 3.5_
4239

43-
- [ ] 4. Test Ruff configuration
44-
- [ ] 4.1 Validate formatting compatibility
40+
- [ ] 4. Enhance Ruff configuration for complete migration
41+
- [ ] 4.1 Complete pyproject.toml Ruff configuration
42+
43+
- Add exclude patterns for migrations and other directories
44+
- Add [tool.ruff.isort] section with Django-aware import sorting (known-django, section-order, combine-as-imports)
45+
- _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5_
46+
47+
- [ ] 5. Test Ruff configuration
48+
- [ ] 5.1 Validate formatting compatibility
4549

46-
- Run `ruff format --check` on existing codebase to verify minimal changes
47-
- Compare Ruff output with current Black formatting to ensure consistency
48-
- Test that 79-character line length is maintained
49-
- Verify migrations are excluded from formatting
50+
- Run `docker compose run --rm app uv run ruff format --check .` on existing codebase to verify minimal changes
51+
- Compare Ruff output with current formatting to ensure consistency
52+
- Verify migrations are excluded from formatting (configured in pyproject.toml)
5053
- _Requirements: 1.1, 1.3, 1.4_
5154

52-
- [ ] 4.2 Validate import sorting
55+
- [ ] 5.2 Validate import sorting
5356

54-
- Run `ruff check --select I` to test import sorting functionality
57+
- Run `docker compose run --rm app uv run ruff check --select I .` to test import sorting functionality
5558
- Verify Django-aware section organization is maintained
56-
- Test that import sorting follows isort-compatible behavior
59+
- Test that import sorting follows isort-compatible behavior using `docker compose run --rm app uv run ruff check --select I --fix .`
5760
- _Requirements: 1.2, 1.5_
5861

59-
- [ ] 4.3 Test pre-commit integration
60-
- Run pre-commit hooks in isolated environment to verify functionality
62+
- [ ] 5.3 Test pre-commit integration
63+
- Run `docker compose run --rm app pre-commit run --all-files` to test pre-commit hooks in containerized environment
6164
- Test that Ruff hooks execute correctly and maintain exclusion patterns
62-
- Verify pre-commit performance improvement with Ruff
65+
- Verify pre-commit performance improvement with Ruff using `docker compose run --rm app pre-commit run ruff-format ruff-check`
6366
- _Requirements: 2.1, 2.2, 2.3, 2.4_

.pre-commit-config.yaml

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,39 @@
1+
exclude: "^docs/|/migrations/|devcontainer.json"
2+
default_stages: [pre-commit]
3+
minimum_pre_commit_version: "3.2.0"
4+
15
default_language_version:
26
python: python3.11
37

4-
# Ignore migration folders
5-
exclude: '.*\/migrations\/.*'
6-
78
repos:
89
# pre-commit hooks
910
- repo: https://github.com/pre-commit/pre-commit-hooks
1011
rev: v5.0.0
1112
hooks:
12-
- id: no-commit-to-branch
13-
args: [--branch, main]
1413
- id: trailing-whitespace
1514
- id: end-of-file-fixer
16-
- id: check-yaml
1715
- id: check-json
1816
- id: check-toml
17+
- id: check-xml
18+
- id: check-yaml
19+
- id: debug-statements
20+
- id: check-builtin-literals
21+
- id: check-case-conflict
22+
- id: check-docstring-first
23+
- id: detect-private-key
24+
- id: no-commit-to-branch
25+
args: [--branch, main]
1926
- id: check-added-large-files
2027
- id: check-merge-conflict
21-
- id: detect-private-key
2228
- id: mixed-line-ending
2329
args: [--fix=lf]
2430

25-
# ruff
31+
# Run the Ruff linter.
2632
- repo: https://github.com/astral-sh/ruff-pre-commit
2733
rev: v0.12.5
2834
hooks:
29-
# Run the linter.
35+
# Linter
3036
- id: ruff-check
31-
args: [--fix]
32-
# Run the formatter.
37+
args: [--fix, --exit-non-zero-on-fix]
38+
# Formatter
3339
- id: ruff-format

pyproject.toml

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,85 @@ Homepage = "https://github.com/weallcode/website"
7979
[tool.ruff]
8080
# Use Ruff's recommended defaults
8181
target-version = "py311"
82+
# Exclude a variety of commonly ignored directories.
83+
extend-exclude = [
84+
"*/migrations/*.py",
85+
"staticfiles/*",
86+
]
87+
88+
select = [
89+
"F",
90+
"E",
91+
"W",
92+
"C90",
93+
"I",
94+
"N",
95+
"UP",
96+
"YTT",
97+
# "ANN", # flake8-annotations: we should support this in the future but 100+ errors atm
98+
"ASYNC",
99+
"S",
100+
"BLE",
101+
"FBT",
102+
"B",
103+
"A",
104+
"COM",
105+
"C4",
106+
"DTZ",
107+
"T10",
108+
"DJ",
109+
"EM",
110+
"EXE",
111+
"FA",
112+
'ISC',
113+
"ICN",
114+
"G",
115+
'INP',
116+
'PIE',
117+
"T20",
118+
'PYI',
119+
'PT',
120+
"Q",
121+
"RSE",
122+
"RET",
123+
"SLF",
124+
"SLOT",
125+
"SIM",
126+
"TID",
127+
"TC",
128+
"INT",
129+
# "ARG", # Unused function argument
130+
"PTH",
131+
"ERA",
132+
"PD",
133+
"PGH",
134+
"PL",
135+
"TRY",
136+
"FLY",
137+
# "NPY",
138+
# "AIR",
139+
"PERF",
140+
# "FURB",
141+
# "LOG",
142+
"RUF",
143+
]
144+
ignore = [
145+
"S101", # Use of assert detected https://docs.astral.sh/ruff/rules/assert/
146+
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
147+
"SIM102", # sometimes it's better to nest
148+
"UP038", # Checks for uses of isinstance/issubclass that take a tuple
149+
# of types for comparison.
150+
# Deactivated because it can make the code slow:
151+
# https://github.com/astral-sh/ruff/issues/7871
152+
]
153+
# The fixes in extend-unsafe-fixes will require
154+
# provide the `--unsafe-fixes` flag when fixing.
155+
extend-unsafe-fixes = [
156+
"UP038",
157+
]
82158

83-
[tool.ruff.lint]
84-
# Allow wildcard imports in __init__.py files (common Django pattern)
85-
per-file-ignores = {"__init__.py" = ["F403", "F401"]}
159+
[tool.ruff.lint.isort]
160+
force-single-line = true
86161

87162
[dependency-groups]
88163
dev = [

0 commit comments

Comments
 (0)