Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 59 additions & 16 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,89 @@ To do so follow this [official github guide](https://docs.github.com/en/free-pro
We use [uv](https://github.com/astral-sh/uv) to manage our dev dependencies.
To install it, see their [installation guide](https://docs.astral.sh/uv/getting-started/installation/)

Once it's done, simply run the following command to automatically setup a virtual environment and install dev dependencies:
We use [just](https://github.com/casey/just) as a command runner. Install it with:

```bash
uv sync
source .venv/bin/activate
uv tool install rust-just
```

Finally, install the pre-commit hooks:
Then bootstrap your environment (installs pre-commit hooks and syncs dependencies):

```bash
pre-commit install
just bootstrap
```

<details>
<summary>Manual setup (without <code>just</code>)</summary>

```bash
uv sync
source .venv/bin/activate
pre-commit install --install-hooks
```
</details>

### Testing and Linting

We use `mypy`, `pytest`, `ruff`, and `black` for quality control. `ruff` and `black` are executed using pre-commit when you make a commit.
To ensure there are not formatting or typing issues in the entire repository you can run:
Running `just` at the root of the repository lists all available recipes:

```bash
pre-commit run --all-files
```
$ just
Available recipes:
[dev]
bootstrap # Bootstrap dev environment: install pre-commit hooks and sync dependencies
lint # Run pre-commit hooks on all files
pre-mr-check # Run all checks before submitting a PR
clean # Remove mypy cache

[typecheck]
mypy # Run mypy on plugin, ext, scripts, stubs and tests
pyright # Run pyright on test cases
pyrefly # Run pyrefly on test cases
ty # Run ty on test cases

[test]
test +args # Run pytest on specific files or with custom args (no xdist)
all-test # Run full pytest test suite with parallel workers
stubtest *args # Run stubtest to check stubs match runtime
ext-test # Run django-stubs-ext tests

[build]
build # Build all packages
lock-check # Check that uv.lock is up to date
```

NOTE: This command will not only lint but also modify files - so make sure to commit whatever changes you've made before hand.
You can also run pre-commit per file or for a specific path, simply replace "--all-files" with a target (see [this guide](https://codeburst.io/tool-your-django-project-pre-commit-hooks-e1799d84551f) for more info).
Before submitting a PR, run all checks at once:

To execute the unit tests, simply run:
```bash
just pre-mr-check
```

Or run individual checks:

```bash
pytest -n auto
just lint # pre-commit hooks (ruff, codespell, ...)
just mypy # mypy on plugin, ext, scripts, stubs and tests
just test tests/test_xyz.yml # run specific tests (no xdist)
just all-test # full pytest suite (parallel)
just stubtest # stubtest: check stubs match runtime
just pyright # pyright on test cases
just ty # ty on test cases
just pyrefly # pyrefly on test cases
```

If you get some unexpected results or want to be sure that tests run is not affected by previous one, remove `mypy` cache:
Extra arguments can be passed to `test` and `stubtest`:

```bash
rm -r .mypy_cache
just test tests -k test_name
just stubtest --allowlist extra.txt
```

If you get unexpected results, clear the mypy cache with `just clean`.

### Testing stubs with `stubtest`

Run [`./scripts/stubtest.sh`](scripts/stubtest.sh) to test that stubs and sources are in-line.
Run `just stubtest` (or [`./scripts/stubtest.sh`](scripts/stubtest.sh) directly) to test that stubs and sources are in-line.

We have some special files to allow errors:

Expand Down
73 changes: 73 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# List all available recipes
_default:
@just --list --unsorted

# Bootstrap dev environment: install pre-commit hooks and sync dependencies
[group('dev')]
bootstrap:
uv tool install pre-commit
uv sync
pre-commit install --install-hooks

# Run pre-commit hooks on all files
[group('dev')]
lint:
pre-commit run --all-files

# Run all checks before submitting a PR
[group('dev')]
pre-mr-check: lint ty pyrefly mypy stubtest pyright ext-test test

# Remove mypy cache
[group('dev')]
clean:
rm -rf .mypy_cache

# Run mypy on plugin, ext, scripts, stubs and tests
[group('typecheck')]
mypy:
uv run mypy --strict ext
uv run mypy --strict scripts
uv run mypy --strict mypy_django_plugin
uv run mypy --cache-dir=/dev/null --no-incremental django-stubs
uv run mypy --strict tests

# Run pyright on test cases
[group('typecheck')]
pyright:
uv run pyright -p pyrightconfig.testcases.json

# Run pyrefly on test cases
[group('typecheck')]
pyrefly:
uv run pyrefly check tests/assert_type

# Run ty on test cases
[group('typecheck')]
ty:
uv run ty check tests/assert_type

# Run pytest tests
[group('test')]
test +args="-n auto tests":
uv run pytest {{ args }}

# Run stubtest to check stubs match runtime
[group('test')]
stubtest *args:
uv run ./scripts/stubtest.sh {{ args }}

# Run django-stubs-ext tests
[group('test')]
ext-test:
uv run pytest ext

# Build all packages
[group('build')]
build:
uv build --all-packages

# Check that uv.lock is up to date
[group('build')]
lock-check:
uv lock --check
Loading