Ми всі любимо Ansible, але Ansible – це YAML. Для конфігураційних файлів існує маса форматів: списки значень, пари "параметр-значення", INI-файли, YAML, JSON, XML та багато інших. Однак з кількох причин з них YAML часто вважається особливо важким. Зокрема, незважаючи на його освіжаючий мінімалізм та вражаючі можливості для роботи з ієрархічними значеннями, синтаксис YAML може дратувати своїм Python-подібним підходом до відступів.
Якщо вас дратує YAML, ви можете – і маєте! - зробити 10 наступних кроків, щоб знизити своє роздратування до прийнятного рівня та полюбити YAML. Як і належить справжньому списку, наша десятка порад нумеруватиметься з нуля, медитацію та духовні практики додаємо за бажанням 😉
0. Примусіть ваш редактор працювати
Неважливо, який у вас текстовий редактор - для нього, напевно, існує хоча б один плагін для роботи з YAML. Якщо у вас такого немає, негайно знайдіть та встановіть. Витрачений на пошук та налаштування час буде багаторазово окупатися щоразу, коли вам доведеться редагувати YAML.
Наприклад, редактор
Emacs у режимі YAML та відображення пробілів.
Якщо у вашому улюбленому редакторі немає режиму YAML, то частину проблем можна вирішити, попрацювавши з налаштуваннями. Наприклад, штатний для GNOME текстовий редактор Gedit не має режиму YAML, але за умовчанням підсвічує синтаксис YAML і дозволяє налаштувати роботу з відступами:
Налаштування відступів у Gedit.
А плагін
Іншими словами, згаяйте час на вивчення свого улюбленого редактора. З'ясуйте, що він сам або його спільнота розробки пропонують для роботи з YAML, та використовуйте ці можливості. Ви точно про це не пошкодуєте.
1. Використовуйте лінтер (linter)
В ідеалі мови програмування та мови розмітки використовують передбачуваний синтаксис. Комп'ютери добре справляються з передбачуваністю, тому ще 1978 року виникла концепція
встановити
$ sudo dnf install yamllint
Потім ви просто запускаєте yamllint, передаючи йому YAML файл для перевірки. Ось як це виглядає, якщо передати лінтеру файл з помилкою:
$ yamllint errorprone.yaml
errorprone.yaml
23:10 error syntax error: mapping values are not allowed here
23:11 error trailing spaces (trailing-spaces)
Цифри ліворуч – це не час, а координати помилки: номер рядка та стовпця. Опис помилки може вам ні про що не говорити, зате ви знаєте, де вона знаходиться. Просто подивіться на це місце в коді, і, швидше за все, все стане зрозумілим.
Коли yamllint не знаходить помилок у файлі, екран нічого не виводиться. Якщо вас лякає така тиша і хочеться трохи більше зворотного зв'язку, можна запускати лінтер з умовною командою echo через подвійний амперсанд (&&), ось так:
$ yamllint perfect.yaml && echo "OK"
OK
У POSIX подвійний амперсанд спрацьовує тоді і лише тоді, коли попередня команда повертає 0. А yamllint якраз повертає кількість знайдених помилок, тому вся ця умовна конструкція працює.
2. Пишіть на Python, а не на YAML
Якщо вас реально дратує YAML, просто не пишіть на ньому буквально. Буває, що YAML – це єдиний формат, який сприймається програмою. Але й у цьому випадку необов'язково створювати файл YAML. Пишіть на тому, що вам подобається, а потім конвертуйте. Наприклад, для Python є чудова бібліотека
Самоконвертування
У цьому випадку файл з даними заразом є і Python-скриптом, який генерує YAML. Цей спосіб найкраще підходить для невеликих наборів даних. Ви просто пишіть JSON-дані в змінну Python, випереджаєте це директивою import, а в кінці файлу додаєте три рядки для реалізації висновку.
#!/usr/bin/python3
import yaml
d={
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
f=open('output.yaml','w')
f.write(yaml.dump(d))
f.close
Тепер запускаємо цей файл на Python і на виході отримуємо файл output.yaml:
$ python3 ./example.json
$ cat output.yaml
glossary:
GlossDiv:
GlossList:
GlossEntry:
Abbrev: ISO 8879:1986
Acronym: SGML
GlossDef:
GlossSeeAlso: [GML, XML]
para: A meta-markup language, used to create markup languages such as DocBook.
GlossSee: markup
GlossTerm: Standard Generalized Markup Language
ID: SGML
SortAs: SGML
title: S
title: example glossary
Це абсолютно коректний YAML, але yamllint видасть попередження, що він не починається з. Що ж, це можна легко виправити вручну або злегка доопрацювати Python-скрипт.
Конвертування через скрипти
У цьому випадку спочатку пишемо на JSON-і, а потім запускаємо конвертор у вигляді окремого Python-скрипта, який на виході дає YAML. Порівняно з попереднім, цей спосіб краще масштабується, оскільки конвертування відокремлено даних.
Для початку створимо JSON-файл example.json, наприклад, його можна взяти на
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
Потім створимо простий скрипт-конвертор та збережемо його під ім'ям json2yaml.py. Цей скрипт імпортує обидва модулі - YAML і JSON Python, а також завантажує вказаний користувачем файл JSON, виконує конвертування і пише дані у файл output.yaml.
#!/usr/bin/python3
import yaml
import sys
import json
OUT=open('output.yaml','w')
IN=open(sys.argv[1], 'r')
JSON = json.load(IN)
IN.close()
yaml.dump(JSON, OUT)
OUT.close()
Збережіть цей скрипт у system path і запускайте при необхідності:
$ ~/bin/json2yaml.py example.json
3. Парсіте багато і часто
Іноді на проблему корисно поглянути під іншим кутом. Якщо вам важко уявити взаємозв'язки між даними в YAML, можна тимчасово перетворити їх на щось звичніше.
Наприклад, якщо вам зручно працювати зі словниковими списками або з JSON, то YAML можна перетворити на JSON лише двома командами в інтерактивній оболонці Python. Допустимо, у вас є YAML-файл mydata.yaml, тоді ось як це буде виглядати:
$ python3
>>> f=open('mydata.yaml','r')
>>> yaml.load(f)
{'document': 34843, 'date': datetime.date(2019, 5, 23), 'bill-to': {'given': 'Seth', 'family': 'Kenlon', 'address': {'street': '51b Mornington Roadn', 'city': 'Brooklyn', 'state': 'Wellington', 'postal': 6021, 'country': 'NZ'}}, 'words': 938, 'comments': 'Good article. Could be better.'}
На цю тему можна знайти безліч інших прикладів. Крім того, є безліч онлайн-конвертерів і локальних парсерів. Тож не соромтеся переформатувати дані, коли бачите в них лише незрозумілу мішанину.
4. Читайте спіки
Повертаючись до YAML після тривалої перерви, корисно зайти на
5. Псевдоконфіги
При написанні книги або статті завжди корисно спершу накидати попередній план, хоча б у вигляді змісту. Так само і з YAML. Швидше за все, ви уявляєте, які дані треба записати у файл YAML, але не дуже розумієте, як зв'язати їх один з одним. Тому перш ніж ваяти YAML, намалюйте псевдоконфіг.
Псевдоконфіг схожий на псевдокод, де не треба дбати про структуру або відступи, відносини «батько-нащадок», успадкування та вкладеності. Так і тут: ви малюєте ітерації даних у міру того, як вони з'являються у вас в голові.
Псевдоконфіг з перерахуванням програмістів (Martin та Tabitha) та їх навичок (мов програмування: Python, Perl, Pascal та Lisp, Fortran, Erlang, відповідно).
Намалювавши псевдоконфіг на аркуші паперу, уважно проаналізуйте його і, якщо все гаразд, оформіть у вигляді валідного YAML-файлу.
6. Дилема «табуляція чи прогалини»
Вам доведеться вирішити дилему
У будь-якому нормальному текстовому редакторі можна налаштувати автозаміну табуляції на задану кількість пробілів, тому бунт прихильників клавіші таб можна не боятися.
Як добре відомо кожному ненависнику YAML, на екрані не видно різниці між табуляцією та пробілами. А коли чогось не видно, про це, як правило, згадують в останню чергу, після того, як перебрали, перевірили та усунули решту можливих проблем. Час часу, вбитий на пошук кривої табуляції або блоку пробілів, просто кричить про те, що вам над терміново створити політику використання того чи іншого, а потім реалізувати залізобетонну перевірку її дотримання (наприклад, через Git-хук для примусового прогону через лінтер).
7. Краще менше та краще (або більше – це менше)
Деякі люди люблять писати YAML, оскільки він підкреслює структуру. У цьому вони активно використовують відступи, щоб виділяти блоки даних. Це таке свого роду шахрайство для імітації мов розмітки, у яких використовуються явні роздільники.
Ось приклад такої структурованості з
# Employee records
- martin:
name: Martin D'vloper
job: Developer
skills:
- python
- perl
- pascal
- tabitha:
name: Tabitha Bitumen
job: Developer
skills:
- lisp
- fortran
- erlang
Комусь такий варіант допомагає розкласти в голові структуру YAML, інших він, навпаки, дратує масою непотрібних, на їх погляд, відступів.
Але якщо ви власник YAML-документу і відповідаєте за його супровід, то ви і тільки ви повинні визначати, як використовувати відступи. Якщо вас дратують великі відступи, зведіть їх до мінімуму, який лише можливий згідно з специфікацією YAML. Наприклад, вищенаведений файл з документації Ansible без будь-яких втрат можна переписати ось так:
---
- martin:
name: Martin D'vloper
job: Developer
skills:
- python
- perl
- pascal
- tabitha:
name: Tabitha Bitumen
job: Developer
skills:
- lisp
- fortran
- erlang
8. Використовуйте заготовки
Якщо при заповненні файлу YAML ви постійно повторюєте одні й самі помилки, має сенс вставити в нього шаблон-заготівлю у вигляді коментаря. Тоді наступного разу можна буде просто скопіювати цю заготівлю та вписати туди реальні дані, наприклад:
---
# - <common name>:
# name: Given Surname
# job: JOB
# skills:
# - LANG
- martin:
name: Martin D'vloper
job: Developer
skills:
- python
- perl
- pascal
- tabitha:
name: Tabitha Bitumen
job: Developer
skills:
- lisp
- fortran
- erlang
9. Використовуйте щось інше
Якщо програма не тримає вас мертвою хваткою, можливо, варто змінити YAML на інший формат. Згодом конфігураційні файли можуть переростати себе і тоді краще перетворити їх на прості скрипти на Lua або Python.
YAML – чудова штука, яку багато хто любить за мінімалізм та простоту, але це далеко не єдиний інструмент у вашому арсеналі. Тож іноді від нього можна відмовитись. Для YAML легко знайти бібліотеки парсингу, тому якщо ви запропонуєте зручні варіанти міграції, ваші користувачі відносно безболісно переживуть таку відмову.
Якщо ж без YAML ніяк не обійтися, то візьміть на озброєння ці 10 порад і переможіть свою ворожість до YAML раз і назавжди!
Джерело: habr.com