Режим наблюдения и форматы вывода
--watch для разработки, JSON и GitHub-формат для CI.
Обзор возможностей вывода
Ruff предлагает множество форматов вывода и режимов работы, которые делают его удобным как для разработки, так и для CI/CD. В этом уроке мы рассмотрим:
- --watch — режим наблюдения за файлами в реальном времени
- --output-format — различные форматы вывода (text, json, github, gitlab, pylint, concise, full)
- --show-files — какие файлы проверяются
- --show-settings — какие настройки активны
- --show-source — показать исходный код с ошибкой
- --preview — включить preview-правила
Все эти флаги делают Ruff гибким инструментом, который можно интегрировать в любой рабочий процесс.
--watch — режим наблюдения
Флаг --watch запускает Ruff в режиме непрерывного наблюдения. Ruff следит за файловой системой и автоматически перезапускает проверку при любых изменениях (сохранении файлов). Это невероятно удобно держать в отдельном окне терминала или в split-панели редактора во время разработки.
Как это работает: Ruff использует notify (кросс-платформенную библиотеку для отслеживания файловой системы), которая эффективно отслеживает изменения без постоянного опроса диска. При каждом изменении Ruff перепроверяет только изменённый файл, а не весь проект, что делает режим очень быстрым даже на больших проектах.
# базовый режим наблюдения
ruff check --watch .
# с выбором правил
ruff check --select E,F,I --watch .
# с автоисправлением (безопасным)
ruff check --fix --watch .
# с предпросмотром — не работает с --watch (только diff)
# но можно комбинировать с --output-format
ruff check --output-format concise --watch .
# наблюдение за конкретной папкой
ruff check --watch src/
Практический сценарий: Откройте терминал, разделённый на две панели. В одной — редактор (VS Code, vim и т.д.), в другой —:
ruff check --select ALL --ignore E501 --watch .
# Теперь при каждом сохранении файла вы сразу видите все ошибки.
--watch особенно полезен, когда вы изучаете новое правило или набор правил. Включите правило, смотрите на ошибки в реальном времени и сразу исправляйте их.
--output-format: обзор всех форматов
Флаг --output-format позволяет выбрать формат вывода результатов проверки. Доступные форматы:
| Формат | Описание | Использование |
|---|---|---|
text |
Стандартный текстовый вывод (по умолчанию) | Разработка, локальное использование |
concise |
Сокращённый текст, по одному нарушению на строку | Терминал, быстрый просмотр |
json |
JSON-формат для программной обработки | CI/CD, кастомные инструменты, парсинг |
github |
GitHub Actions аннотации | GitHub Actions CI |
gitlab |
GitLab CI Code Quality формат | GitLab CI |
pylint |
Совместимость с pylint | Миграция с pylint |
full |
Полный формат с исходным кодом для каждого нарушения | Детальный анализ, обучение |
ruff check --output-format text . # дефолтный текстовый (по умолчанию)
ruff check --output-format concise . # компактный
ruff check --output-format json . # JSON для парсинга
ruff check --output-format github . # GitHub Actions аннотации
ruff check --output-format gitlab . # GitLab CI формат
ruff check --output-format pylint . # совместимость с pylint
ruff check --output-format full . # полный с исходным кодом
text. Его можно изменить в конфигурационном файле: output-format = "concise" в секции [tool.ruff].
Форматы text и concise
text (по умолчанию) выводит каждое нарушение с полной информацией: путь, строка, колонка, код правила и сообщение:
# text:
src/main.py:10:5: F841 Local variable `unused` is assigned to but never used
src/main.py:15:1: E302 Expected 2 blank lines after class or function definition, found 1
src/main.py:20:89: E501 Line too long (95 > 88 characters)
src/main.py:25:1: I001 Import block is unsorted or incorrectly formatted.
src/main.py:30:5: UP015 Unnecessary open mode parameters
Found 5 errors.
concise — более компактный формат, где путь выводится один раз для группы нарушений в одном файле:
# concise:
src/main.py:10:5: F841 Local variable `unused` is assigned to but never used
src/main.py:15:1: E302 Expected 2 blank lines after class or function definition, found 1
src/main.py:20:89: E501 Line too long (95 > 88 characters)
src/main.py:25:1: I001 Import block is unsorted
src/main.py:30:5: UP015 Unnecessary open mode parameters
found 5 errors
Разница в том, что concise не выводит разделители между файлами и заголовки, делая вывод более плотным. Удобно для терминала с ограниченной высотой.
JSON формат — для программной обработки
Формат json выводит все нарушения в структурированном JSON-виде, который можно парсить в любом языке программирования. Это основа для интеграции Ruff с кастомными CI-системами, дашбордами качества кода и другими инструментами.
Пример вывода JSON:
ruff check --output-format json . > report.json
# Содержимое report.json:
{
"files": {
"/path/to/src/main.py": {
"cell": null,
"messages": [
{
"code": "F841",
"message": "Local variable `unused` is assigned to but never used",
"fix": null,
"location": {
"row": 10,
"column": 5
},
"end_location": {
"row": 10,
"column": 11
},
"filename": "/path/to/src/main.py",
"noqa_row": 10,
"url": null
}
]
}
},
"summary": {
"raw": "Found 5 errors.",
"violations": 5
}
}
Пример парсинга JSON на Python:
import json
import subprocess
# запускаем ruff и парсим JSON
result = subprocess.run(
["ruff", "check", "--output-format", "json", "."],
capture_output=True, text=True
)
data = json.loads(result.stdout)
# анализируем
for file_path, file_data in data["files"].items():
for msg in file_data["messages"]:
code = msg["code"]
row = msg["location"]["row"]
col = msg["location"]["column"]
print(f"{file_path}:{row}:{col}: {code} - {msg['message']}")
# группировка по коду правила
from collections import Counter
codes = Counter()
for file_data in data["files"].values():
for msg in file_data["messages"]:
codes[msg["code"]] += 1
print("Статистика:", codes.most_common())
# фильтрация: только ошибки безопасности
security_issues = []
for file_path, file_data in data["files"].items():
for msg in file_data["messages"]:
if msg["code"].startswith("S"):
security_issues.append((file_path, msg))
print(f"Найдено {len(security_issues)} проблем безопасности")
Формат github — GitHub Actions аннотации
Формат github создаёт аннотации в формате GitHub Actions. Это позволяет отображать ошибки линтинга прямо в интерфейсе GitHub — как комментарии к строкам кода в Pull Request и во вкладке Files changed.
# вывод в формате github:
ruff check --output-format github .
# ::error file=src/main.py,line=10,col=5,title=F401::`os` imported but unused
# ::error file=src/main.py,line=15,col=1,title=E302::Expected 2 blank lines...
# ::warning file=src/main.py,line=20,col=89,title=E501::Line too long...
Пример workflow для GitHub Actions:
# .github/workflows/lint.yml
name: Lint
on: [push, pull_request]
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v2
with:
args: check --output-format github --select E,F,I,N,UP,B
Формат сообщений GitHub Actions:
::error file={path},line={line},col={col},title={code}::{message}— ошибка::warning file={path},line={line},col={col},title={code}::{message}— предупреждение::notice file={path},line={line},col={col},title={code}::{message}— заметка
Формат gitlab — GitLab CI Code Quality
Формат gitlab генерирует отчёт в формате GitLab Code Quality. GitLab может отображать эти отчёты в интерфейсе Merge Request, показывая ошибки прямо в diff.
# вывод в формате gitlab:
ruff check --output-format gitlab . > gl-code-quality-report.json
# [
# {
# "description": "`os` imported but unused",
# "check_name": "F401",
# "fingerprint": "abc123...",
# "severity": "major",
# "location": {
# "path": "src/main.py",
# "lines": { "begin": 10 }
# }
# }
# ]
# .gitlab-ci.yml
ruff:
script:
- ruff check --output-format gitlab . > gl-code-quality-report.json
artifacts:
reports:
codequality: gl-code-quality-report.json
Формат pylint — обратная совместимость
Формат pylint эмулирует вывод pylint. Это полезно при миграции с pylint на Ruff — ваши существующие инструменты и парсеры продолжат работать без изменений.
# pylint-совместимый вывод:
ruff check --output-format pylint .
# src/main.py:10:5: F401: `os` imported but unused
# src/main.py:15:1: E302: Expected 2 blank lines...
# src/main.py:20:89: E501: Line too long...
# теперь можно передавать в инструменты, ожидающие pylint:
ruff check --output-format pylint . | pylint-report-parser
Формат full — с исходным кодом
Формат full выводит каждое нарушение вместе с фрагментом исходного кода. Это самый информативный формат, который помогает быстро понять контекст ошибки.
# full формат:
ruff check --output-format full .
# src/main.py:10:5: F841 Local variable `unused` is assigned to but never used
# |
# 9 | def foo():
# 10 | unused = 42
# | ^^^^^^ F841
# 11 | return True
# |
# src/main.py:15:1: E302 Expected 2 blank lines after class definition
# |
# 14 | class Foo:
# 15 | pass
# | ^^^^^^^^ E302
# |
Этот формат особенно полезен при обучении и в ситуациях, когда нужно быстро понять, что именно нарушает правило, без открытия файла в редакторе.
--show-files — какие файлы проверяются
Флаг --show-files выводит список файлов, которые Ruff будет проверять с учётом всех настроек включения/исключения. Это помогает отладить конфигурацию, особенно когда вы используете сложные правила include, exclude, extend-exclude или src.
# показать какие файлы будут проверены
ruff check --show-files .
# пример вывода:
# src/main.py
# src/utils.py
# src/models.py
# tests/test_main.py
# tests/test_utils.py
# с --show-files можно увидеть эффект exclude:
ruff check --exclude tests --show-files .
# src/main.py
# src/utils.py
# src/models.py
Полезно, когда у вас настроены include/exclude паттерны и вы хотите убедиться, что нужные файлы проверяются, а ненужные — нет.
--show-settings — текущая конфигурация
Флаг --show-settings выводит все активные настройки Ruff для текущего проекта. Он объединяет настройки из конфигурационных файлов (pyproject.toml, ruff.toml) и CLI-флагов, показывая итоговую конфигурацию. Это незаменимый инструмент для отладки, когда вы не уверены, какие настройки реально активны.
ruff check --show-settings .
# пример вывода (сокращён):
# ================================================================
# Settings for: /path/to/project
# ================================================================
#
# [general]
# src = ["src"]
# exclude = [".bzr", ".direnv", ".eggs", ".git", ".git-rewrite",
# ".hg", ".ipynb_checkpoints", ".mypy_cache", ".nox",
# ".pants.d", ".pyenv", ".pytest_cache", ".ruff_cache",
# ".svn", ".tox", ".venv", ".vscode", "__pypackages__",
# "_build", "buck-out", "build", "dist", "node_modules",
# "site-packages", "venv"]
#
# [lint]
# select = ["E", "F", "I", "N", "UP", "B"]
# ignore = ["E501"]
#
# [format]
# line-length = 88
# quote-style = "double"
# indent-style = "space"
# полезно для отладки — видно что переопределилось из CLI
Если запустить с флагами CLI, они будут учтены в выводе:
# увидим, что select переопределён
ruff check --select ALL --ignore D --show-settings .
--show-source — показать исходный код
Флаг --show-source выводит для каждого нарушения соответствующую строку исходного кода с указанием проблемного места. Это как формат full, но встроенный в стандартный text-вывод.
ruff check --show-source .
# src/main.py:10:5: F841 Local variable `unused` is assigned to but never used
# |
# 10 | unused = 42
# | ^^^^^^
#
# src/main.py:15:89: E501 Line too long (95 > 88 characters)
# |
# 15 | result = some_function_with_very_long_arguments(a, b, c, d, e, f, g, h, i)
# | ^^^
Удобно использовать вместе с --watch для быстрого просмотра ошибок с контекстом.
--preview — preview-правила
Флаг --preview включает правила, которые находятся в стадии Preview (нестабильные, могут измениться в будущих версиях). Это позволяет опробовать новые правила до их официального релиза.
# включить preview-правила
ruff check --preview .
ruff check --select ALL --preview .
# в конфиге:
[tool.ruff]
preview = true
--preview в CI для production-проектов без явного понимания рисков.
--silent и --quiet — управление выводом
Флаги управления verbosity:
# --quiet: выводить только ошибки, без информационных сообщений
ruff check --quiet .
# --silent: вообще ничего не выводить (только код возврата)
ruff check --silent .
# полезно в CI: код возврата 0 = всё ок, 1 = есть ошибки
--silent особенно полезен в скриптах, где важен только код возврата (exit code). Например, pre-commit хуки или Makefile: ruff check --silent . || exit 1.
Сравнение форматов вывода
| Формат | Читаемость | Машиночитаемость | Лучшее применение |
|---|---|---|---|
| text | ⭐⭐⭐⭐ | ⭐ | Локальная разработка |
| concise | ⭐⭐⭐ | ⭐ | Терминал, watch режим |
| json | ⭐ | ⭐⭐⭐⭐⭐ | Парсинг, CI, кастомные отчёты |
| github | ⭐⭐⭐ | ⭐⭐⭐⭐ | GitHub Actions |
| gitlab | ⭐⭐ | ⭐⭐⭐⭐ | GitLab CI |
| full | ⭐⭐⭐⭐⭐ | ⭐ | Обучение, детальный разбор |
| pylint | ⭐⭐⭐ | ⭐⭐⭐ | Миграция с pylint |
Практические сценарии
Сценарий 1: Локальная разработка с watch
# Терминал 1: редактор
code .
# Терминал 2: ruff в режиме наблюдения
ruff check --select ALL --ignore E501,D --output-format concise --watch .
Сценарий 2: CI pipeline с GitHub Actions
# .github/workflows/ruff.yml
name: Ruff
on: [push, pull_request]
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v2
with:
args: >
check --output-format github
--select E,F,I,N,UP,B,S
--ignore E501
Сценарий 3: Генерация отчёта для дашборда
# генерация JSON для кастомного дашборда
ruff check --output-format json . > lint-report.json
# затем Python скрипт для создания HTML отчёта:
python3 -c "
import json
data = json.load(open('lint-report.json'))
total = data['summary']['violations']
print(f'Lint Report
Total violations: {total}
')
" > report.html
Сценарий 4: Отладка конфигурации
# проверить какие файлы будут проверяться
ruff check --show-files .
# проверить какие настройки активны
ruff check --show-settings .
# убедиться что exclude работает
ruff check --exclude "migrations" --show-files .
--show-files и --show-settings для отладки. Если Ruff ведёт себя неожиданно, первым делом проверьте, какие настройки реально активны.
Резюме
| Флаг | Назначение |
|---|---|
--watch |
Режим наблюдения за файлами |
--output-format |
Выбор формата вывода (text, json, github и др.) |
--show-files |
Список проверяемых файлов |
--show-settings |
Текущая конфигурация Ruff |
--show-source |
Показать исходный код с ошибкой |
--preview |
Включить preview-правила |
--quiet / --silent |
Управление verbosity |
Детали работы --watch
Режим --watch использует механизм файловых уведомлений операционной системы (inotify на Linux, FSEvents на macOS, ReadDirectoryChanges на Windows). Это обеспечивает мгновенную реакцию на изменения без постоянного опроса диска (polling).
Особенности работы --watch:
- При запуске выполняет полную проверку всего проекта
- При изменении файла перепроверяет только его (не весь проект)
- Не поддерживает --diff (дифф применяется мгновенно)
- Работает как с одиночными файлами, так и с директориями
- Автоматически обрабатывает новые и удалённые файлы
- Игнорирует изменения в .ruff_cache и node_modules
# watch с автоисправлением — изменения применяются сразу
ruff check --fix --watch .
# watch с компактным выводом
ruff check --output-format concise --watch .
# watch только для определённой директории
ruff check --watch src/ruff/
# watch с ограниченным набором правил
ruff check --select F,I --watch .
--watch с конкретной директорией, а не со всем проектом: ruff check --watch src/my_module/
Интеграция с редакторами кода
Хотя --watch удобен, большинство разработчиков предпочитают интеграцию Ruff напрямую в редактор. Вот как это работает:
VS Code: расширение "Ruff" от Astral Software. Устанавливается из маркетплейса. Автоматически запускает ruff check при сохранении и подсвечивает ошибки в редакторе.
// .vscode/settings.json
{
"[python]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
},
"editor.defaultFormatter": "charliermarsh.ruff"
},
"ruff.lineLength": 88,
"ruff.organizeImports": true,
"ruff.fixOnSave": true
}
Neovim: через null-ls или conform.nvim:
lua << EOF
require("null-ls").setup({
sources = {
require("null-ls").builtins.diagnostics.ruff,
require("null-ls").builtins.formatting.ruff,
},
})
EOF
# Или через conform:
require("conform").setup({
formatters_by_ft = {
python = { "ruff_format" },
},
})
PyCharm: установите плагин "Ruff" через Settings → Plugins. Настройте внешний инструмент:
# File → Settings → Tools → External Tools → Add
# Program: ruff
# Arguments: check $FilePath$
# Working directory: $ProjectFileDir$
Структура JSON-вывода
Полная структура JSON-вывода Ruff:
{
"files": {
"/absolute/path/to/file.py": { # ключ — абсолютный путь
"cell": null, # для Jupyter ноутбуков
"messages": [ # массив нарушений
{
"code": "F841", # код правила
"message": "Local variable...", # сообщение
"fix": { # объект исправления (null если нет)
"applicability": "safe", # safe или unsafe
"message": "...",
"edits": [
{
"content": "...",
"location": {
"row": 10,
"column": 5
},
"end_location": {
"row": 10,
"column": 11
}
}
]
},
"location": {
"row": 10,
"column": 5
},
"end_location": {
"row": 10,
"column": 11
},
"filename": "/absolute/path/to/file.py",
"noqa_row": 10,
"url": "https://docs.astral.sh/ruff/rules/unused-variable"
}
]
}
},
"summary": {
"raw": "Found 5 errors.",
"violations": 5
}
}
fix содержит информацию о доступном автоисправлении. Если fix равен null, для этого правила нет автоматического исправления.
Коды возврата (exit codes)
Коды возврата Ruff важны для интеграции в CI/CD. Они позволяют автоматически определить, прошла ли проверка успешно:
| Код | Значение |
|---|---|
| 0 | Успех — ошибок не найдено |
| 1 | Найдены ошибки |
# использование в bash скриптах
if ruff check --silent .; then
echo "Код чист!"
else
echo "Найдены ошибки!"
exit 1
fi
# или более кратко:
ruff check --silent . || { echo "Линтинг не прошёл!"; exit 1; }
Шпаргалка
# Watch режим
ruff check --watch .
ruff check --fix --watch .
# Форматы вывода
ruff check --output-format json .
ruff check --output-format github .
ruff check --output-format gitlab .
ruff check --output-format concise .
ruff check --output-format full .
ruff check --output-format pylint .
# Отладка
ruff check --show-files .
ruff check --show-settings .
ruff check --show-source .
# Preview
ruff check --preview .
ruff check --select ALL --preview .
# Verbosity
ruff check --quiet .
ruff check --silent .
# Комбинации
ruff check --select E,F,I --output-format concise --watch .
ruff check --fix --select I --output-format github .
Урок 2.3: Форматы вывода
5 вопросов