diff --git a/README.md b/README.md index ad1974ed71618..2e157c7ece01e 100644 --- a/README.md +++ b/README.md @@ -116,12 +116,21 @@ For more, see the [documentation](https://docs.astral.sh/ruff/). ### Installation -Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI: +Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI. + +Invoke Ruff directly with [`uvx`](https://docs.astral.sh/uv/): + +```shell +uvx ruff check # Lint all files in the current directory. +uvx ruff format # Format all files in the current directory. +``` + +Or install Ruff with `uv` (recommended), `pip`, or `pipx`: ```shell # With uv. -uv add --dev ruff # to add ruff to your project -uv tool install ruff # to install ruff globally +uv tool install ruff@latest # Install Ruff globally. +uv add --dev ruff # Or add Ruff to your project. # With pip. pip install ruff diff --git a/docs/faq.md b/docs/faq.md index 2c1227b8112e9..5e15dc63f19c8 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -220,19 +220,39 @@ Ruff is installable under any Python version from 3.7 onwards. ## Do I need to install Rust to use Ruff? -Nope! Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI: +Nope! Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI. We recommend installing Ruff with [uv](https://docs.astral.sh/uv/), +though it's also installable with `pip`, `pipx`, and a [variety of other package managers](installation.md): ```console -# With uv. -$ uv add --dev ruff # to add ruff to your project -$ uv tool install ruff # to install ruff globally +$ # Install Ruff globally. +$ uv tool install ruff@latest -# With pip +$ # Or add Ruff to your project. +$ uv add --dev ruff + +$ # With pip. $ pip install ruff + +$ # With pipx. +$ pipx install ruff +``` + +Starting with version `0.5.0`, Ruff can also be installed with our standalone installers: + +```console +$ # On macOS and Linux. +$ curl -LsSf https://astral.sh/ruff/install.sh | sh + +$ # On Windows. +$ powershell -c "irm https://astral.sh/ruff/install.ps1 | iex" + +$ # For a specific version. +$ curl -LsSf https://astral.sh/ruff/0.5.0/install.sh | sh +$ powershell -c "irm https://astral.sh/ruff/0.5.0/install.ps1 | iex" ``` -Ruff ships with wheels for all major platforms, which enables `pip` to install Ruff without relying -on Rust at all. +Ruff ships with wheels for all major platforms, which enables `uv`, `pip`, and other tools to install Ruff without +relying on a Rust toolchain at all. ## Can I write my own linter plugins for Ruff? diff --git a/docs/installation.md b/docs/installation.md index d73fafa1c1e80..c8df38ee164c2 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,9 +1,28 @@ # Installing Ruff -Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI: +Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI. + +Ruff can be invoked directly with [`uvx`](https://docs.astral.sh/uv/): + +```shell +uvx ruff check # Lint all files in the current directory. +uvx ruff format # Format all files in the current directory. +``` + +Or installed with `uv` (recommended), `pip`, or `pipx`: ```console +$ # Install Ruff globally. +$ uv tool install ruff@latest + +$ # Or add Ruff to your project. +$ uv add --dev ruff + +$ # With pip. $ pip install ruff + +$ # With pipx. +$ pipx install ruff ``` Once installed, you can run Ruff from the command line: @@ -13,7 +32,7 @@ $ ruff check # Lint all files in the current directory. $ ruff format # Format all files in the current directory. ``` -Starting with version `0.5.0`, Ruff can be installed with our standalone installers: +Starting with version `0.5.0`, Ruff can also be installed with our standalone installers: ```console $ # On macOS and Linux. diff --git a/docs/tutorial.md b/docs/tutorial.md index 8b183aabc8962..d004eb102a697 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -5,21 +5,24 @@ your project. For a more detailed overview, see [_Configuring Ruff_](configurati ## Getting Started -To start, we'll install Ruff through PyPI (or with your [preferred package manager](installation.md)): +To start, we'll initialize a project using [uv](https://docs.astral.sh/uv/): ```console -$ pip install ruff +$ uv init numbers ``` -Let's then assume that our project structure looks like: +This command creates a Python project with the following structure: ```text numbers - ├── __init__.py - └── numbers.py + ├── pyproject.toml + └── src + └── numbers + ├── __init__.py + └── py.typed ``` -...where `numbers.py` contains the following code: +We'll then replace the contents of `src/numbers/__init__.py` with the following code: ```python from typing import Iterable @@ -35,28 +38,40 @@ def sum_even_numbers(numbers: Iterable[int]) -> int: ) ``` -We can run the Ruff linter over our project via `ruff check`: +Next, we'll add Ruff to our project: ```console -$ ruff check -numbers/numbers.py:3:8: F401 [*] `os` imported but unused +$ uv add --dev ruff +``` + +We can then run the Ruff linter over our project via `uv run ruff check`: + +```console +$ uv run ruff check +src/numbers/__init__.py:3:8: F401 [*] `os` imported but unused Found 1 error. [*] 1 fixable with the `--fix` option. ``` +!!! note + + As an alternative to `uv run`, you can also run Ruff by activating the project's virtual + environment (`source .venv/bin/active` on Linux and macOS, or `.venv\Scripts\activate` on + Windows) and running `ruff check` directly. + Ruff identified an unused import, which is a common error in Python code. Ruff considers this a "fixable" error, so we can resolve the issue automatically by running `ruff check --fix`: ```console -$ ruff check --fix +$ uv run ruff check --fix Found 1 error (1 fixed, 0 remaining). ``` Running `git diff` shows the following: ```diff ---- a/numbers/numbers.py -+++ b/numbers/numbers.py +--- a/src/numbers/__init__.py ++++ b/src/numbers/__init__.py @@ -1,7 +1,5 @@ from typing import Iterable @@ -74,13 +89,13 @@ def sum_even_numbers(numbers: Iterable[int]) -> int: Note Ruff runs in the current directory by default, but you can pass specific paths to check: ```console -$ ruff check numbers/numbers.py +$ uv run ruff check src/numbers/__init__.py ``` Now that our project is passing `ruff check`, we can run the Ruff formatter via `ruff format`: ```console -$ ruff format +$ uv run ruff format 1 file reformatted ``` @@ -109,7 +124,7 @@ Ruff's behavior. To determine the appropriate settings for each Python file, Ruff looks for the first `pyproject.toml`, `ruff.toml`, or `.ruff.toml` file in the file's directory or any parent directory. -To configure Ruff, let's create a configuration file in our project's root directory: +To configure Ruff, we'll add the following to the configuration file in our project's root directory: === "pyproject.toml" @@ -141,8 +156,8 @@ To configure Ruff, let's create a configuration file in our project's root direc Running Ruff again, we see that it now enforces a maximum line width, with a limit of 79: ```console -$ ruff check -numbers/numbers.py:5:80: E501 Line too long (90 > 79) +$ uv run ruff check +src/numbers/__init__.py:5:80: E501 Line too long (90 > 79) Found 1 error. ``` @@ -223,8 +238,8 @@ If we run Ruff again, we'll see that it now enforces the pyupgrade rules. In par the use of the deprecated `typing.Iterable` instead of `collections.abc.Iterable`: ```console -$ ruff check -numbers/numbers.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable` +$ uv run ruff check +src/numbers/__init__.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable` Found 1 error. [*] 1 fixable with the `--fix` option. ``` @@ -266,10 +281,10 @@ all functions have docstrings: If we run Ruff again, we'll see that it now enforces the pydocstyle rules: ```console -$ ruff check +$ uv run ruff check numbers/__init__.py:1:1: D104 Missing docstring in public package -numbers/numbers.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable` -numbers/numbers.py:1:1: D100 Missing docstring in public module +src/numbers/__init__.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable` +src/numbers/__init__.py:1:1: D100 Missing docstring in public module Found 3 errors. [*] 1 fixable with the `--fix` option. ``` @@ -291,9 +306,9 @@ def sum_even_numbers(numbers: Iterable[int]) -> int: Running `ruff check` again, we'll see that it no longer flags the `Iterable` import: ```console -$ ruff check +$ uv run ruff check numbers/__init__.py:1:1: D104 Missing docstring in public package -numbers/numbers.py:1:1: D100 Missing docstring in public module +src/numbers/__init__.py:1:1: D100 Missing docstring in public module Found 3 errors. ``` @@ -322,7 +337,7 @@ line based on its existing violations. We can combine `--add-noqa` with the `--s flag to add `# noqa` directives to all existing `UP035` violations: ```console -$ ruff check --select UP035 --add-noqa . +$ uv run ruff check --select UP035 --add-noqa . Added 1 noqa directive. ``` @@ -331,8 +346,8 @@ Running `git diff` shows the following: ```diff diff --git a/tutorial/src/main.py b/tutorial/src/main.py index b9291c5ca..b9f15b8c1 100644 ---- a/numbers/numbers.py -+++ b/numbers/numbers.py +--- a/src/numbers/__init__.py ++++ b/src/numbers/__init__.py @@ -1,4 +1,4 @@ -from typing import Iterable +from typing import Iterable # noqa: UP035 diff --git a/python/ruff-ecosystem/README.md b/python/ruff-ecosystem/README.md index 3e61fb8ae407b..243028e7757e2 100644 --- a/python/ruff-ecosystem/README.md +++ b/python/ruff-ecosystem/README.md @@ -4,10 +4,10 @@ Compare lint and format results for two different ruff versions (e.g. main and a ## Installation -From the Ruff project root, install with `pip`: +From the Ruff project root, install with [uv](https://docs.astral.sh/uv/): ```shell -pip install -e ./python/ruff-ecosystem +uv tool install -e ./python/ruff-ecosystem ``` ## Usage