Как стать автором
Обновить

Комментарии 10

До конца так и не понял, зачем необходим такой функционал мержинга конфигов. Есть стойкое ощущение, что или задача надуманная, или она решается гораздо проще.

Изначально все затевалось ради добавления новых свойств в существующие конфиги (и иногда удалений). Ручные обновления были крайне неудобны (вплоть до того что иногда тупо перезапустить сервис автоматом нельзя пока конфиг не поправят).

Я по честному хотел найти существующее решение, но находил лишь вопросы людей ищущих решения как и я. Единственно что есть в этой области, это eo-yaml и один парсер на питоне которые частично умеют работать с комментами, но это не подходило.

Специфика конфигов в том что обычно они написаны (отформатированы) так как удобно читать человеку. Парсеры, как правило, должны прочитать дерево и отбрасывают это форматирование: соответственно и записать обратно можно только дерево в "техническом" виде. А нужно ничего не трогая добавить новое.

Вопросы, я думаю, вызывает мерж списков. Здесь я просто вспомнил что сталкивался с конфигами где списки были сложными и ветвистыми структурами (а не значениями). Собственно все связанное с ними построено на предположениях и сейчас не подтверждено практикой.

Я специально писал статью без кода, описывая с чем сталкивался и как решал, чтобы мне могли указать на концептуальные проблемы. Естественно что меня, как любого программиста, иногда переклинивает и уносит в усложнения и я буду только рад услышать как можно было сделать проще.

Может вам присмотреться к hocon'у вместо yaml-а? Если, конечно, конфиги нужны не для какой-то готовой экосистемы, наглухо прибитой к yaml?

У меня dropwizard, который по дефолту на yaml конфигах, хотя, конечно же, не наглухо прибит. Hocon я смотрел, но мне совершенно не понравился синтаксис (перегруженный и технический). Он бы подошел для "технарей" на стороне пользователя, но в общем случае желательно что-то наглядное и простое (yaml сильно чище и читается лучше).

С другой стороны, если бы он умел мержить я бы смирился. Помню прототип мержера я начинал делать именно на основе hocon'а (уж очень не хотелось делать свой парсер для yaml'а), но, к сожалению, не помню почему эта идея загнулась (во что-то уперся).

Мне кажется, для реализации библиотеки Config (референсная реализация hocon на java) делали поддержку в т.ч. yaml-а, но майнтенерам проекта особо некогда её развивать (плюс у них эта либа лежит в основе целой экосистемы, поэтому они боятся поломать что-то), так что pool request, вроде-бы, до сих пор висит.

Что касается поддержки мержа - она там прямо встроенная в синтаксис:

a {
  xx = 1
}
b = ${a} {
  yy = true
}
c = ${a}
c {
  zz = "my string"
}
d = ${a} ${b} ${c}
d {
  additional = 0
}

на выходе получим

d {
  xx = 1
  yy = true
  zz = "my string"
  additional = 0
}

p.s.: лично у меня сложилась обратное отношение, yaml кажется слишком хрупким, требующим обязательное применение IDE для правки

Это мерж значений, а что с комментами? У меня тот прототип, к сожалению, не под рукой, не скажу наверняка что именно это и было камнем преткновения, но что-то там остановило железно (может, кстати, это был мерж листов: помню где-то он был безапиляционно неотключаемый). Хотя, конечно, допускаю что мог что-то упустить.

"Проблема" с классическими парсерами в том что они прежде всего "читатели". У них нет задачи запоминать форматирование, соответственно и записать обратно "как было" не могут. Например, в случае с мультилайном, запросто может обратно записать его в одну строчку, что для человека уже сильно не удобно (например, это может быть шаблон автоответа). Часто инлайн комменты упускаются совсем (по-моему, eo-yaml как раз так делает).

В моем случае, конфиги сильно ориентированны на чтение людьми "не в теме" (сильно смахивает на конфиг апача, нгинкса и т.д. когда значения "тонут" в документации). Конфиг форматируется для удобства чтения, включая форматирование списков. И нельзя чтобы его вдруг "изнахратили". Сложность и была, прежде всего, в "верни все как было".

Конечно, я полностью согласен с не надежностью yaml: сам влетал не раз. И технически hocon естественно надежней. Но конкретно в моем случае yaml пугает людей меньше и читать его сильно удобнее. Ошибки допустимо редки (в силу характера правок).

Тут суть в том, что мержить не надо. Там есть возможность включения файлов друг в друга, итоговый конфиг можно хранить именно в таком (разобранном) виде.

Если же требуется получить смерженный итоговый конфиг - это тоже доступно (хотя на сколько "красив" будет итоговый файл - это дело вкурса, плюс текущая реализация сортирует ключи, для кого-то это может быть минусом), при чём коментарии сохраняются (и попутно можно добавить коментарий с источником, из которого появилась та или иная строка, хотя последняя функция работает не идеально).

А еще hocon хорош когда надо написть конфиги под несколько похожих стендов: при этом пишется референсный конфиг с подстановкой параметров, после чего файлики стендов просто включают этот референсный конфиг и файл с конфигурацией конкретного стенда.

Вот насчет "мержить не надо", это была моя первая мысль: я практически сразу начал зашивать мастер конфиг в джарку и при старте на лету мержить с текущим конфигом (это буквально парой строк в snakeyaml делается). Таким образом сгладилась проблема добавлений: все новые свойства просто шли из мастер конфига с дефолтными значениями.

Для админов же оказалось проблематично менять такие "фантомные" свойства, не обозначенные в основном конфиге (потому что доку по ручному обновлению конфига иногда пропускали и, соответственно, конфиг не всегда был актуальный, хоть все и продолжало работать).

Конечно была специальная админская страничка показывающая полный конфиг (без комментов), но это было не сильно удобно. Можно было бы на старте добавить автоматический "отлов" устаревших конфигов. Но это все та же ручная миграция.

Я согласен что для многих (очень многих) ситуаций Config бы прекрасно подошел. Но у меня, по сути, задача стояла заменить работу человека: внести правки так же аккуратно (при не допустимости некоторых компромиссов).

Ну и, кроме того со специализированной тулзой появляются дополнительные плюсы в виде более тонко настраиваемого процесса. Например, есть идея ввести управляющие комменты, задающие стратегию миграции конкретного свойства. Это, ни в коем случае, не было решающим или сколько-нибудь значимым фактором изначально, но может стать чудесным бонусом.

Зачем велосипед, если yq умеет это из коробки?

$ tail -n +1 data{1,2}.yml
==> data1.yml <==
# this is a comment 1
a: simple
# this is a comment 2
b: [1, 2]

==> data2.yml <==
# this is a comment 3
a: other
# this is a comment 4
c:
  test: 1
$ yq -V
yq (https://github.com/mikefarah/yq/) version 4.13.0
$ yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' data1.yml data2.yml
# this is a comment 1
# this is a comment 3
a: other
# this is a comment 2
b: [1, 2]
# this is a comment 4
c:
  test: 1

Я пытался с ним поиграться (я долго искал что есть прежде чем что-то делать). Не могу с ходу вспомнить в чем с ним была проблема, но даже из вашего примера: он у свойства 'a' тупо слепил два коммента, а у меня это будут две одинаковые портянки (как в конфигах апача) с полной докой (во что оно превратится после N апдейтов).

Наверняка, конкретно эта проблема решается какими-нибудь ключиками. Но что-то там было не подходящего, к сожалению, не помню.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Публикации

Истории