astral-sh/ruff
Development workflow
A linear walkthrough of the inner loop for everyday changes.
1. Branch from main
git fetch origin
git checkout -b feature/<short-name> origin/mainThe default branch is main. There are no long-lived release branches; releases are tagged off main (see CHANGELOG.md).
2. Build and run
Use debug builds. From the repo root:
cargo run -p ruff -- check path/to/file.py --no-cache
cargo run --bin ty -- check path/to/file.py--no-cache is recommended while iterating, since cache hits will skip your new code path. The cache lives under .ruff_cache/ per-project (and is gitignored).
3. Add tests first
Every behavior change is testable:
- Lint rules — add or extend a fixture under
crates/ruff_linter/resources/test/fixtures/<plugin>/and a snapshot test in the rule's module. - Formatter — add a Python file to
crates/ruff_python_formatter/resources/test/fixtures/and snapshot the output. - ty type checks — add an mdtest case under
crates/ty_python_semantic/resources/mdtest/. Each.mdfile is parsed for code blocks and expected diagnostics; the format is documented incrates/mdtest/README.md. - LSP — add tests next to
crates/ruff_server/tests/orcrates/ty_server/tests/.
4. Run tests
The full suite using nextest:
CARGO_PROFILE_DEV_OPT_LEVEL=1 \
INSTA_FORCE_PASS=1 INSTA_UPDATE=always \
CARGO_PROFILE_DEV_DEBUG="line-tables-only" \
MDTEST_UPDATE_SNAPSHOTS=1 \
cargo nextest runSingle crate while iterating:
cargo nextest run -p ruff_linter
cargo nextest run -p ty_python_semanticA single mdtest file:
cargo nextest run -p ty_python_semantic -- mdtest::<relative/path/to.md>A single mdtest case within a file (use a substring of the Markdown header):
MDTEST_TEST_FILTER="<filter>" cargo nextest run -p ty_python_semantic -- mdtest::<file.md>5. Review snapshots
After the run, accept the deltas you intended:
cargo insta review # interactive
cargo insta accept # allAlways look at the diff. A subtle change in a rule can ripple through hundreds of fixture files. Reviewers will scrutinize unexpected snapshot churn.
6. Lint and format
cargo clippy --workspace --all-targets --all-features -- -D warnings
RUFF_UPDATE_SCHEMA=1 cargo test
uvx prek run -aIf you touched anything that has a generated artifact (rule registry, options, CLI arg metadata), regenerate explicitly:
cargo dev generate-allThis regenerates ruff.schema.json, ty.schema.json, the rules table in docs/, and the CLI reference page.
7. Commit and push
Conventional, small commits work well. PR titles should be descriptive; ty PRs must start with [ty].
git add -p
git commit -m "[F841] Detect unused walrus targets"
git push -u origin HEAD8. Open the PR
A good PR description includes:
- The issue link.
- A 2–4 sentence summary of the change.
- A "Test plan" section listing how you validated it.
- Screenshots/before-after diagnostic output if user-visible.
CI runs cargo test, cargo clippy, uvx prek run -a, cargo dev generate-all (in check mode), the fuzz smoke tests, and the documentation build. Local pre-flight matches CI.
9. After review
If review feedback requires changes:
- Make them as new commits (the team rebases at merge time).
- Run
uvx prek run -aagain, every time you address comments. - Re-run snapshot tests if you touched output.
10. Merge
Maintainers squash-merge. The squashed commit message becomes part of the changelog.
Tips
- Keep PRs focused. One rule, one bug, one option. Splitting is cheap.
cargo dev round-tripround-trips the parser throughpython/corpora; useful for parser changes.cargo dev format-devruns the formatter against a curated corpus and reports stability.cargo dev print-astandcargo dev print-tokensare useful debugging helpers (seecrates/ruff_dev/).
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.