Skip to main content
Version: 1.0.x

ruff

API for declaring a Ruff lint aspect that visits py_library rules.

Typical usage:

load("@aspect_rules_lint//lint:ruff.bzl", "ruff_aspect")

ruff = ruff_aspect(
binary = "@multitool//tools/ruff",
configs = "@@//:.ruff.toml",
)

Using a specific ruff version

In WORKSPACE, fetch the desired version from https://github.com/astral-sh/ruff/releases

load("@aspect_rules_lint//lint:ruff.bzl", "fetch_ruff")

# Specify a tag from the ruff repository
fetch_ruff("v0.4.10")

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

# 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:

ruff = lint_ruff_aspect(
binary = "@@//tools/lint:ruff",
...
)

Repository Rules

ruff_workaround_20269

Workaround for https://github.com/bazelbuild/bazel/issues/20269

Example usage (generated):

load("@aspect_rules_lint//lint:ruff.bzl", "ruff_workaround_20269")

ruff_workaround_20269(
# A unique name for this repository.
name = "",
)

name

Required name.

A unique name for this repository.

repo_mapping

Optional 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).

build_file_content

Optional string. Default: ""

sha256

Optional string. Default: ""

strip_prefix

Optional string. Default: ""

unlike http_archive, any value causes us to pass --strip-components=1 to tar

url

Optional string. Default: ""

Macros and Functions

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

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 needed 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.

Example usage (generated):

load("@aspect_rules_lint//lint:ruff.bzl", "ruff_action")

ruff_action(
# Bazel Rule or Aspect evaluation context
ctx = None,
# label of the the ruff program
executable = None,
# python files to be linted
srcs = [],
# labels of ruff config files (pyproject.toml, ruff.toml, or .ruff.toml)
config = None,
# output file of linter results to generate
stdout = None,
)

ctx

Required.

Bazel Rule or Aspect evaluation context

executable

Required.

label of the the ruff program

srcs

Required.

python files to be linted

config

Required.

labels of ruff config files (pyproject.toml, ruff.toml, or .ruff.toml)

stdout

Required.

output file of linter results to generate

exit_code

Optional. 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

env

Optional. Default: {}

environment variaables for ruff

ruff_fix

Create a Bazel Action that spawns ruff with --fix.

Example usage (generated):

load("@aspect_rules_lint//lint:ruff.bzl", "ruff_fix")

ruff_fix(
# an action context OR aspect context
ctx = None,
# struct with _ruff and _patcher field
executable = None,
# list of file objects to lint
srcs = [],
# labels of ruff config files (pyproject.toml, ruff.toml, or .ruff.toml)
config = None,
# output file containing the applied fixes that can be applied with the patch(1) command.
patch = None,
# output file of linter results to generate
stdout = None,
# output file to write the exit code
exit_code = None,
)

ctx

Required.

an action context OR aspect context

executable

Required.

struct with _ruff and _patcher field

srcs

Required.

list of file objects to lint

config

Required.

labels of ruff config files (pyproject.toml, ruff.toml, or .ruff.toml)

patch

Required.

output file containing the applied fixes that can be applied with the patch(1) command.

stdout

Required.

output file of linter results to generate

exit_code

Required.

output file to write the exit code

env

Optional. Default: {}

environment variaables for ruff

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 of rules should be visited by the aspect

Example usage (generated):

load("@aspect_rules_lint//lint:ruff.bzl", "lint_ruff_aspect")

lint_ruff_aspect(
binary = None,
configs = None,
)

binary

Required.

configs

Required.

rule_kinds

Optional. Default: ["py_binary", "py_library", "py_test"]

fetch_ruff

A repository macro used from WORKSPACE to fetch ruff binaries.

Allows the user to select a particular ruff version, rather than get whatever is pinned in the multitool.lock.json file.

Example usage (generated):

load("@aspect_rules_lint//lint:ruff.bzl", "fetch_ruff")

fetch_ruff(
# a tag of ruff that we have mirrored, e.g
tag = None,
)

tag

Required.

a tag of ruff that we have mirrored, e.g. v0.1.0