> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# @aspect_rules_lint//lint:ruff.bzl

> Bazel rules_lint Ruff integration: lint_ruff_aspect to run the Ruff Python linter and formatter as a Bazel aspect across py_binary, py_library, py_test.

<Callout icon="book">
  Documentation for [@aspect\_rules\_lint@v2.3.0](https://registry.bazel.build/modules/aspect_rules_lint/2.3.0) -- <Icon icon="github" iconType="brands" /> [View source](https://github.com/aspect-build/rules_lint/blob/v2.3.0/lint/ruff.bzl)
</Callout>

API for declaring a Ruff lint aspect that visits py\_`binary`, `library`, `test` rules.

Typical usage:

Ruff is provided as a built-in tool by rules\_lint. To use the built-in version,
create the linter aspect, typically in `tools/lint/linters.bzl`:

```python theme={null}
load("@aspect_rules_lint//lint:ruff.bzl", "lint_ruff_aspect")

ruff = lint_ruff_aspect(
    binary = Label("@aspect_rules_lint//lint:ruff_bin",
    configs = [Label("//:.ruff.toml")],
)
```

## Using a specific ruff version

In `MODULE.bazel`, fetch the desired version from [https://github.com/astral-sh/ruff/releases](https://github.com/astral-sh/ruff/releases).

In `tools/lint/BUILD.bazel`, select the tool for the host platform:

```python theme={null}
# Note: this won't interact properly with the --platform flag, see
# https://github.com/aspect-build/rules_lint/issues/389
alias(
    name = "ruff",
    actual = select({
        "@bazel_tools//src/conditions:linux_x86_64": "@ruff_x86_64-unknown-linux-gnu//:ruff",
        "@bazel_tools//src/conditions:linux_aarch64": "@ruff_aarch64-unknown-linux-gnu//:ruff",
        "@bazel_tools//src/conditions:darwin_arm64": "@ruff_aarch64-apple-darwin//:ruff",
        "@bazel_tools//src/conditions:darwin_x86_64": "@ruff_x86_64-apple-darwin//:ruff",
        "@bazel_tools//src/conditions:windows_x64": "@ruff_x86_64-pc-windows-msvc//:ruff.exe",
    }),
)
```

Finally, reference this tool alias rather than the one from `@multitool`:

```python theme={null}
ruff = lint_ruff_aspect(
    binary = "@@//tools/lint:ruff",
    ...
)
```

## Function: `ruff_action`

Run ruff as an action under Bazel.

Ruff will select the configuration file to use for each source file, as documented here:
[https://docs.astral.sh/ruff/configuration/#config-file-discovery](https://docs.astral.sh/ruff/configuration/#config-file-discovery)

Note: all config files are passed to the action.
This means that a change to any config file invalidates the action cache entries for ALL
ruff actions.

However, this is important because:

1. ruff has an `extend` field, so it may need to read more than one config file
2. ruff's logic for selecting the appropriate config needs to read the file content to detect a `[tool.ruff]` section.

### Parameters

<ParamField body="ctx" type="unknown" required>
  Bazel Rule or Aspect evaluation context
</ParamField>

<ParamField body="executable" type="unknown" required>
  label of the ruff program
</ParamField>

<ParamField body="srcs" type="unknown" required>
  python files to be linted
</ParamField>

<ParamField body="config" type="unknown" required>
  labels of ruff config files (pyproject.toml, ruff.toml, or .ruff.toml)
</ParamField>

<ParamField body="stdout" type="unknown" required>
  output file of linter results to generate
</ParamField>

<ParamField body="exit_code" type="unknown" default={`None`}>
  output file to write the exit code.
  If None, then fail the build when ruff exits non-zero.
  See [https://github.com/astral-sh/ruff/blob/dfe4291c0b7249ae892f5f1d513e6f1404436c13/docs/linter.md#exit-codes](https://github.com/astral-sh/ruff/blob/dfe4291c0b7249ae892f5f1d513e6f1404436c13/docs/linter.md#exit-codes)
</ParamField>

<ParamField body="env" type="unknown" default={`{}`}>
  environment variaables for ruff
</ParamField>

<ParamField body="patch" type="unknown" default={`None`}>
  output file for patch (optional). If provided, uses run\_patcher instead of run\_shell.
</ParamField>

## Function: `lint_ruff_aspect`

A factory function to create a linter aspect.

Attrs:
binary: a ruff executable
configs: ruff config file(s) (`pyproject.toml`, `ruff.toml`, or `.ruff.toml`)
rule\_kinds: which [kinds](https://bazel.build/query/language#kind) of rules should be visited by the aspect
filegroup\_tags: filegroups tagged with these tags will be visited by the aspect in addition to Python rule kinds

### Parameters

<ParamField body="binary" type="unknown" required />

<ParamField body="configs" type="unknown" required />

<ParamField body="rule_kinds" type="unknown" default={`["py_binary", "py_library", "py_test"]`} />

<ParamField body="filegroup_tags" type="unknown" default={`["python", "lint-with-ruff"]`} />

## Repository rule: `ruff_workaround_20269`

Workaround for [https://github.com/bazelbuild/bazel/issues/20269](https://github.com/bazelbuild/bazel/issues/20269)

### Attributes

<ParamField body="name" type="name" required>
  A unique name for this repository.
</ParamField>

<ParamField body="repo_mapping" type="dictionary: String → String">
  In `WORKSPACE` context only: a dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.

  For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`).

  This attribute is *not* supported in `MODULE.bazel` context (when invoking a repository rule inside a module extension's implementation function).
</ParamField>

<ParamField body="build_file_content" type="string" default={`""`} />

<ParamField body="sha256" type="string" default={`""`} />

<ParamField body="strip_prefix" type="string" default={`""`}>
  unlike http\_archive, any value causes us to pass --strip-components=1 to tar
</ParamField>

<ParamField body="url" type="string" default={`""`} />
