Проверка исходников
Как гонять линтер: флаги, на что опираются глубокие правила, базлайн для старой кодовой базы и CI.
Основной режим инструмента – проверка исходников. Полный перечень правил – отдельная страница (Правила); здесь – как управлять прогоном.
Флаги CLI
--list-rules, --where (корень данных Элемента, источник и версии), --select/--enable/
--ignore (по id правила, группе – части id до / – или букве тира), --fix,
--baseline/--write-baseline, --element-version, --data-dir, --lang,
--format text|json|codeclimate.
--fix чинит механические находки прямо в файлах – хвостовые пробелы, символы типографики
(длинное тире → среднее, … → ..., кудрявые кавычки и ёлочки в комментариях → прямые),
смешанные переводы строк (нормализуются к преобладающему стилю) – и отчитывается об
оставшемся. Применяются только однозначные правки и только для правил текущего прогона
(поэтому --fix --enable typography заодно гасит долг по тире и ёлочкам); всё, что требует
суждения, не трогается.
Для интеграции с редактором --stdin --filename ИМЯ проверяет один буфер из stdin (только
пофайловые правила); JSON ({diagnostics, summary}) – тот же, что отдаёт MCP-сервер.
xbsl --index ПУТЬ вместо проверки выводит в stdout JSON-индекс проекта – объекты
(с табличными частями, локальными типами модулей и семействами членов для автодополнения после
точки), объявления методов (аннотации, список параметров как написан, тип возврата и комментарий-
описание над объявлением) и именованные компоненты форм; пути POSIX относительно
корня, строки 1-based – для перехода к определению и автодополнения в редакторах.
--format codeclimate печатает отчёт GitLab Code Quality (issue Code Climate) с путями
относительно текущего каталога – запускайте из корня репозитория и сохраняйте вывод как
артефакт codequality.
Правила подробно
Полный перечень всех 191 правил базового набора (severity, включённость по умолчанию,
область, ссылки на разделы документации платформы) – в
RULES.ru.md; в рантайме –
xbsl --list-rules, который учитывает ещё и правила и переопределения уровней установленных
плагинов. Обзор по тирам – в README; ниже – что именно проверяют глубокие тиры.
Типовые правила тира D покрывают каждую типовую позицию в коде (новый, приведение как,
аннотации, сигнатуры) и каждое значение Тип: в yaml (объединения А|Б|?, дженерики,
nullable): корень обязан быть известным типом – stdlib, объект проекта, локальный тип модуля
или глобальный тип подключённой библиотеки (см. ниже), – а цепочка с корнем-объектом проекта
не выходит за семейство порождаемых им типов:
производные из документации дистрибутива (Ссылка, Объект, СоздатьОбъект, автоформы…),
табличные части и структуры модулей. Квалификация через пространство имён
(Справочник.X.Ссылка) дополнительно сверяет вид объекта; значения перечислений проекта
проверяются и в коде, и в yaml-биндингах.
Типы подключённых библиотек линтер берёт из их архивов. Проект.yaml объявляет только
координаты (Поставщик, Имя, Версия), поэтому имена ищутся в архиве
{Поставщик}-{Имя}-{Версия}.xlib – в каталоге описания проекта и выше (до четырёх уровней),
то есть там, где архив и лежит при поставке исходников. Известным становится элемент с
ОбластьВидимости: Глобально: остальное – внутреннее дело библиотеки. Архива рядом нет –
типы библиотеки остаются неизвестными, как и до появления этой поддержки.
Межфайловые правила тира D ловят то, о чём компилятор сообщает поздно или молчит: обработчик
из yaml без метода в парном модуле, тип чужой подсистемы без секции Импорт:, динамический
список с типом автоформы без реквизита объекта в полях, кросс-компонентный вызов
Компоненты.X.Метод() без аннотации видимости, несоответствия окружений (@НаСервере из
клиентского обработчика без @ДоступноСКлиента, клиентский модуль в HttpСервисе),
зарезервированные имена (Тип/type у поля или параметра, свойство компонента с встроенным
именем), методы без единой ссылки и свойства верхнего уровня объектов по метамодели
конфигурации. Группа query/ разбирает блоки Запрос{ ... } и сверяет таблицы ИЗ/СОЕДИНЕНИЕ
с объектами проекта и их табличными частями; блок с конструкциями вне поддержанного
подмножества (временные таблицы, объединения, подзапросы) пропускается целиком, а не
угадывается.
Подробные описания групп – query/ (составной тип в В с подзапросом), project/
(свойства проекта), naming/ (стандарт имён, extra [morph]) и style/ (соглашения по
написанию кода, договорённость включено/выключено) – в
RULES.ru.md.
Базлайн: легаси-долг и исключения с причиной
Чтобы включить правило на коде, который его уже нарушает, и не утонуть в старых находках, текущие находки замораживают в базлайн и спрашивают по правилу только с нового кода:
xbsl acme/app --enable style --write-baseline baseline.json # заморозить долг один раз
xbsl acme/app --enable style --baseline baseline.json # всплывает только НОВОЕ
Идентичность находки – (файл, правило, сообщение) с допустимым количеством: перенос строки
не будит замороженную находку, а действительно новое нарушение всплывает. Итог прогона
показывает, сколько находок погашено и сколько записей устарело (долг выплачен) – сигнал
перезаписать файл. Пути хранятся относительно файла базлайна: коммитьте его в корне
репозитория и запускайте линтер откуда угодно.
Тот же файл хранит и точечные исключения с причиной: значение записи – либо голое
количество, либо {"count": N, "reason": "..."}, где причина объясняет, почему код
правильный намеренно. Причины записывает действие “Исключить проверку” из лампочки
расширения VS Code (или правка
руками); --write-baseline сохраняет причины выживших записей при перезаписи. LSP-сервер
принимает тот же ключ --baseline ФАЙЛ, поэтому исключённое гаснет и в редакторе.
В идентичность входит текст сообщения: записывайте и проверяйте базлайн под одним языком
вывода.
Устаревшими считаются только записи ТЕХ правил, которые в прогоне были. Правило, оставленное
за набором – сужением --select, выключенное по умолчанию, неизвестное установленной
надстройке, – находок не даёт по построению, и звать его записи устаревшими значило бы
объявить долг выплаченным, не посмотрев. Такие записи считаются отдельно (“записей базлайна
не проверено”, ключ baseline_not_checked в json), и --prune-baseline их не трогает.
xbsl baseline add <пути> --rule <правило> [--reason ...] замораживает находки по одной: гоняет
названное правило по указанным путям и дописывает только то, чего базлайн ещё не покрывает –
новый файл встаёт на своё место в порядке, остальное не двигается, записанные причины
остаются, повторный вызов ничего не меняет (--format json отвечает {baseline, added, findings, written}). Базлайн судится только в пределах запрошенных путей: записи чужих файлов
считаются непроверенными, а не устаревшими, и baseline_not_checked разбит на _rules и
_paths. Сводка называет, чем судили прогон – engine, plugins с версиями, rules {active, total, plugin} в json и строка “Набор прогона” в тексте, – так расхождение двух сред об одном
дереве видно сразу.
Использование в CI
xbsl возвращает ненулевой код только при находке уровня error, поэтому командой можно
останавливать конвейер как есть – предупреждения и info сборку не валят. Единственное условие –
данные о языке (см. Данные о языке): сгенерируйте их в джобе (экстракторы
лежат в репозитории – чекаутьте его) либо поставьте пакет, который несёт данные через entry
point xbsl.data (см. Расширение), – тогда
достаточно pip install.
GitHub Actions
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install xbsl
# генерация данных из вашего дистрибутива 1С:Элемент (или установите пакет с данными):
- run: xbsl extract --dist "$ELEMENT_DIST"
- run: xbsl acme/ # джоба падает при любой находке уровня error
GitLab CI (виджет Code Quality)
--format codeclimate пишет отчёт Code Climate, который GitLab показывает прямо в merge
request. Запускайте из корня репозитория и сохраняйте вывод как отчёт codequality. Код
возврата при error-находках остаётся ненулевым, поэтому artifacts.when: always сохраняет
отчёт, даже когда джоба останавливает конвейер (нужен только виджет – добавьте || true):
lint:
script:
- pip install xbsl
- xbsl --format codeclimate acme/ > gl-code-quality-report.json
artifacts:
when: always
reports:
codequality: gl-code-quality-report.json