Форматтер YAML

Форматтер YAML приводит документ к единому виду: отступы 2 или 4 пробела, кавычки, списки. Показывает типичные ошибки YAML с номером строки.

Всё работает в вашем браузере — данные не отправляются на сервер.

Зачем приводить YAML к единому виду

YAML форматтер нужен там, где YAML уже написан, но выглядит по-разному: один человек ставит два пробела, другой четыре, третий пользуется табуляцией, а ключи кое-где в кавычках, кое-где без. Формально всё это допустимо, и любой парсер такой файл прочитает. Практически же такой файл невозможно ревьюить: при диффе глаза цепляются не за смысл, а за пробелы. Отсюда две практические задачи. Первая — привести существующий документ к одному виду, чтобы изменения в нём были видны как изменения данных, а не как шум. Вторая — найти то, что мешает парсеру: табуляцию в отступе, двоеточие без пробела, незакрытую кавычку, повторяющийся ключ. Ниже разобран разбор файла с ошибками, а таблица показывает, что именно делает форматтер с каждым видом дефекта.

Что умеет форматтер YAML

  • Два режима: нормализация с отступами и сворачивание всего документа в одну строку
  • Отступы 2 или 4 пробела на выбор — как принято в вашем проекте
  • Списки приводятся к единому виду: каждый пункт с дефисом, вложенные объекты выровнены
  • Лишние кавычки снимаются, но только там, где тип значения не изменится
  • Ключи можно отсортировать по алфавиту, чтобы порядок не зависел от того, кто редактировал файл
  • Список проблем с номером строки: табы, разный шаг отступа, двоеточие без пробела, незакрытая кавычка, дубли ключей

Как пользоваться форматтером

  1. Вставьте YAML в поле ввода — можно целиком из файла, можно фрагментом
  2. Выберите режим: нормализация для чтения или минимизация для вставки в код
  3. Задайте ширину отступа и при необходимости включите сортировку ключей
  4. Нажмите «Нормализовать» и заберите результат кнопкой копирования
  5. Если в списке ошибок есть записи, исправьте их в исходном тексте и прогоните ещё раз

Как устроен разбор

Разбор написан вручную, без внешних библиотек, и состоит из трёх проходов. Сначала каждая строка очищается от комментария: знак # внутри кавычек комментарием не считается. Затем по отступам строится дерево: отступ задаёт уровень вложенности, дефис в начале строки — пункт списка, двоеточие с пробелом — границу между ключом и значением. Третий проход обходит дерево и собирает текст заново: с выбранной шириной отступа, единым видом списков и кавычками по правилам. Отдельно проверяются табуляция в отступе, несовпадение шага отступа между соседними блоками, баланс кавычек в строке и повторяющиеся ключи внутри одного отображения. Одна оговорка: полноценный YAML 1.1 с якорями, псевдонимами, тегами и несколькими документами не поддерживается, ровно как в конвертере YAML в JSON.

Что форматтер делает с типичными ошибками

Было в файлеЧто сделаноСтало
name:Aliceдобавлен пробел после двоеточияname: Alice
a: b: 1табуляция заменена отступом в два пробелаa: b: 1
a: b: 1 c: d: 2отступ приведён к шагу, принятому в документеa: b: 1 c: d: 2
title: "Пример"лишние кавычки снятыtitle: Пример
port: "8080"кавычки оставлены, иначе число стало бы строкойport: "8080"
flag: "true"кавычки оставлены, иначе булево значение стало бы строкойflag: "true"
items: [1, 2, 3]потоковый список развёрнут в обычныйitems: - 1 - 2 - 3
a: 1 a: 2показан повторяющийся ключ, строки указаныa: 1 a: 2
text: "строкапоказана незакрытая кавычкаtext: "строка
log: /var/log/app.logзначение оставлено как естьlog: /var/log/app.log
script:line 1 line 2блочный скаляр сохранён
b: 2 a: 1ключи отсортированы по алфавитуa: 1 b: 2

Часть строк показана с переносом строки внутри ячейки: так видно, где именно менялся отступ.

Где YAML приходится приводить к единому виду

Первый и самый заметный случай — конфигурация в репозитории, которую правили несколько человек. Каждый привык к своему отступу, и через полгода файл состоит из четырёх разных стилей в одном экране. При таком раскладе любой diff выглядит как переписывание всего файла, и ревью перестаёт работать: никто не способен разглядеть в шуме одну изменённую строку. Нормализация решает эту проблему механически: отступы становятся одинаковыми, списки одинаковыми, кавычки одинаковыми, и дальше в диффе остаются только данные.

Второй случай — файл, который пишут автоматически. Генератор шаблонов, скрипт выгрузки, настройка CI: каждая такая штука печатает YAML по-своему, и на выходе получается документ, который никто не читал глазами. Перед тем как такой файл уедет в продакшен, его полезно прогнать через форматтер: он станет предсказуемым, и любая следующая правка в нём будет видна. Третий случай — ручная правка большого конфига в редакторе без подсветки YAML: там особенно часто появляются табы и забытые пробелы после двоеточия.

  • Конфигурация в git, которую правили несколько разработчиков
  • Файл, который генерируется скриптом и уходит в CI
  • Правка большого docker-compose в редакторе без подсветки
  • Объединение двух версий конфига, написанных в разных стилях
  • Подготовка файла к выкладке, где важна предсказуемость
  • Проверка чужого файла перед добавлением в свой проект

Что ломается в YAML чаще всего

Первое место в списке — табуляция. Её набирают не специально: редактор подставил её вместо пробелов, человек не заметил, потому что на экране отступ выглядит ровно. Вторая ошибка — лишний пробел или его отсутствие после двоеточия. С виду разница невелика, но YAML требует пробел, и без него ключ не отделяется от значения. Третья — незакрытая кавычка: обычно она возникает при копировании строки из одного файла в другой, когда кавычка «проезжает» вместе с текстом.

Четвёртая ошибка — дубликат ключа. Её нетрудно получить, скопировав блок и забыв удалить исходный. Пятая — разный шаг отступа в соседних блоках: выглядит безобидно, пока файл не начинают читать другие инструменты. И шестая, самая коварная, — значения, которые меняют тип при снятии кавычек. «true» в кавычках это строка, без кавычек это булево значение, и код, который сравнивает поле с true, внезапно перестаёт работать. Хороший форматтер не должен молча менять смысл, поэтому такие значения он не трогает.

  • Табуляция вместо пробелов в отступе
  • Двоеточие без пробела после: name:Alice
  • Незакрытая кавычка в строке со значением
  • Повторяющийся ключ внутри одного блока
  • Разный шаг отступа у соседних блоков
  • Кавычки, снятие которых меняет тип значения

Разбор файла с ошибками по шагам

Возьмём файл, в котором смешались четыре типовые проблемы. Первая строка содержит табуляцию в отступе, вторая — двоеточие без пробела, третья — повторяющийся ключ, четвёртая — незакрытую кавычку. Форматтер сначала очищает каждую строку от комментария, аккуратно не трогая знак # внутри кавычек, потом строит дерево по отступам и уже по дереву собирает новый текст.

Порядок важен: сначала убираются комментарии, потому что в комментарии может встретиться двоеточие или фигурная скобка, которые иначе были бы приняты за структуру. Затем приводятся к одному виду отступы и списки, и только в конце снимаются лишние кавычки — когда уже известно, какое значение получилось и не поменяет ли оно тип. Проверка при этом идёт параллельно: каждая найденная проблема попадает в список с номером строки, чтобы по ней можно было сразу перейти к нужному месту в исходнике.

Что происходит на каждом шаге разбора

ШагДействиеРезультат
1Очистка строкКомментарии убраны, # внутри кавычек сохранён
2Определение отступаПробелы посчитаны, табуляция отмечена
3Разбор пар ключ и значениеДвоеточие с пробелом делит строку
4Сборка дереваДефис в начале строки означает пункт списка
5ПроверкиТабы, шаг отступа, кавычки, дубликаты
6Сборка ответаОтступы и списки приведены к единому виду
7КавычкиСнимаются только там, где тип не меняется
8Проверка результатаТекст разбирается заново

Разбор линейный: он делает несколько проходов по строкам, поэтому размер файла на скорость почти не влияет.

Форматтер, конвертеры и проверка JSON

Форматтер YAML стоит рядом с конвертерами в других форматы, и между ними есть разница, о которой стоит сказать прямо. Конвертер в JSON меняет формат: то, что было YAML, становится данными, которые можно передать в код. Форматтер формат сохраняет и трогает только запись. На практике их часто используют вместе: сначала нормализуют, чтобы diff был читаемым, потом конвертируют, чтобы отдать данные приложению. Обратный путь тоже работает: из JSON получают YAML, и если исходный JSON был сгенерирован машиной, его приводят к тому же единому виду.

Отдельно стоит сказать про проверку. Форматтер отвечает на вопрос «читается ли этот файл», но не на вопрос «правильные ли в нём данные». Для второго есть валидатор JSON Schema, а для сравнения двух версий одного файла — сравнение JSON и разница текстов. Именно эти инструменты помогают ответить, что именно изменилось в данных, когда формат уже приведён к единому виду и шума больше нет.

  • Форматтер отвечает на вопрос «читается ли файл»
  • Конвертеры отвечают на вопрос «в каком формате отдать данные»
  • Порядок работы: сначала формат, потом смысл
  • Сравнение версий имеет смысл только после нормализации
  • Проверка по схеме — отдельный слой и отдельный инструмент
  • Форматирование JSON решает ту же задачу для другого формата

Частые вопросы

Чем форматтер YAML отличается от конвертера в JSON

Конвертер меняет формат целиком: на входе YAML, на выходе JSON и обратно. Форматтер работает с тем же YAML, но оставляет его YAML — просто приводит к единому виду и показывает проблемы. Это разные задачи: конвертация нужна, когда формат надо поменять, а нормализация — когда формат менять нельзя, но хочется одинаковые отступы, кавычки и порядок ключей. После нормализации конвертировать можно в любой момент, и наоборот: JSON в YAML и форматирование JSON делают то же самое для другого формата.

Почему YAML нельзя парсить табуляцией

В отступе табуляция недопустима, и это не прихоть реализации. Пробел и табуляция — разные символы, и ширина табуляции зависит от настроек редактора: в одном месте это 4 позиции, в другом 8. Два человека, сохранив один и тот же логический отступ, получают разный текст, и файл перестаёт совпадать в diff. YAML запрещает табуляцию в отступе именно поэтому: иначе одинаково выглядящие файлы нельзя было бы сравнивать. Форматтер показывает такую строку отдельной ошибкой и переводит отступ в пробелы.

Когда нужно ставить отступ в 4 пробела, а когда в 2

YAML не задаёт ширину отступа: подходит любая, главное чтобы она была одинаковой внутри одного блока. На практике два пробела встречаются чаще — так пишут в Compose-файлах, в конфигурациях CI и в большинстве примеров в документации. Четыре пробела выбирают там, где в одном файле соседствуют другие языки с такими же отступами, например Python, или когда в файле много уровней вложенности и два пробела трудно отсчитать глазами. В форме есть переключатель, потому что универсального правила нет: главное, чтобы во всём репозитории было одно.

Что будет, если в файле два одинаковых ключа

Это ошибка, и форматтер покажет её с номером строки и номером первого появления. Поведение разных парсеров расходится: часть берёт первое значение, часть последнее, а часть вообще отказывается читать файл. Поэтому полагаться на такой файл нельзя, даже если в вашем конвейере он сегодня читается. Дубликаты обычно появляются при копировании блока конфигурации или при слиянии двух правок. Форматтер дубликат не удаляет — он только показывает, где он лежит, чтобы вы решили, какое из значений правильное.

Что значит ошибка про значение с двоеточием

Это предупреждение, а не поломка. В YAML двоеточие с пробелом после считается разделителем, поэтому значение вида «время: 12: 30» без кавычек читается как два фрагмента, а не как строка. Ссылка или почта такого не содержат, и потому такой текст форматтер не трогает. А вот версия с пробелом после двоеточия уже подозрительна: либо это ошибка, либо значение специально пишут в кавычках. Форматтер показывает строку как предупреждение и на всякий случай берёт значение в кавычки, чтобы дальше оно точно не распалось.

Умеет ли форматтер проверять YAML по схеме

Нет, и это важно понимать. Форматтер проверяет синтаксис и типовые ошибки записи: табы, шаг отступа, баланс кавычек, двоеточие, дубликаты ключей. Схема ответа — совсем другой слой: она говорит, какие ключи обязательны, какие типы у значений и какие поля лишние. Для такой проверки существует отдельный класс инструментов, а в наборе есть валидатор JSON Schema для JSON. Форматтер отвечает на другой вопрос: можно ли этот файл прочитать и не разъедутся ли отступы при следующем изменении.

Почему снимаются не все кавычки

Потому что кавычки в YAML меняют тип значения, а не только внешний вид. Строка «123» без кавычек станет числом, а «true» без кавычек станет булевым значением, и в зависимости от того, как её читает приложение, поменяется смысл. Поэтому лишние кавычки снимаются только там, где содержимое однозначно остаётся строкой: обычный текст без двоеточия, без специальных символов в начале и без служебных слов. Значения, похожие на числа или на true и false, остаются в кавычках — иначе получился бы другой документ.

Что происходит с YAML 1.1, якорями и псевдонимами

Они не поддерживаются, и об этом честно сказано под формой. Разбор написан вручную и покрывает подмножество YAML 1.2: отображения, последовательности, скаляры, блочные скаляры, комментарии и потоковые коллекции. Якоря с префиксом амперсанда, псевдонимы со звёздочкой, теги вида !custom и несколько документов в одном файле разбор не понимает. Если в вашем файле такие конструкции есть, сначала разверните их в явный вид, а уже потом нормализуйте. Разбор YAML в JSON ведёт себя так же.

Похожие инструменты