10 kroków do YAML Zen

Wszyscy kochamy Ansible, ale Ansible to YAML. Istnieje wiele formatów plików konfiguracyjnych: listy wartości, pary parametr-wartość, pliki INI, YAML, JSON, XML i wiele innych. Jednak z kilku powodów YAML jest często uważany za szczególnie trudny. W szczególności, pomimo odświeżającego minimalizmu i imponujących możliwości pracy z wartościami hierarchicznymi, składnia YAML może być denerwująca ze względu na swoje podejście do wcięć w stylu Pythona.

10 kroków do YAML Zen

Jeśli YAML Cię wkurzy, możesz – i powinieneś! – wykonaj 10 poniższych kroków, aby zredukować swoją frustrację do akceptowalnego poziomu i zakochać się w YAML. Jak przystało na tę listę, nasze dziesięć porad będzie ponumerowanych od zera, do woli będziemy dodawać medytacje i praktyki duchowe 😉

0. Spraw, aby Twój edytor działał

Nie ma znaczenia, jaki posiadasz edytor tekstu, prawdopodobnie istnieje co najmniej jedna wtyczka do pracy z YAML. Jeśli go nie masz, znajdź go i zainstaluj natychmiast. Czas spędzony na wyszukiwaniu i konfigurowaniu zwróci się wielokrotnie za każdym razem, gdy będziesz musiał edytować YAML.

Na przykład redaktor Atom domyślnie obsługuje YAML, ale w przypadku GNU Emacs będziesz musiał zainstalować dodatkowe pakiety, na przykład tryb yaml.

10 kroków do YAML Zen

Emacs w trybie YAML i wyświetlanie spacji.

Jeśli Twój ulubiony edytor nie ma trybu YAML, niektóre problemy można rozwiązać, pracując z ustawieniami. Na przykład standardowy edytor tekstu GNOME Gedit nie ma trybu YAML, ale domyślnie podświetla składnię YAML i pozwala skonfigurować pracę z wcięciami:

10 kroków do YAML Zen

Ustawianie wcięć w Gedit.

Wtyczka przestrzenie do rysowania w przypadku Gedit wyświetla spacje jako kropki, eliminując niejasności związane z poziomami wcięć.

Innymi słowy, poświęć czas na poznanie swojego ulubionego redaktora. Dowiedz się, co on lub jego społeczność programistów ma do zaoferowania w zakresie pracy z YAML i skorzystaj z tych funkcji. Na pewno nie pożałujesz.

1. Użyj lintera

W idealnym przypadku języki programowania i języki znaczników wykorzystują przewidywalną składnię. Komputery są dobre w przewidywalności, dlatego też powstała koncepcja lintera. Jeśli w ciągu 40 lat jego istnienia Cię ominął i nadal nie używasz lintera YAML, to czas wypróbować yamllint.

Zainstaluj yamlint Możesz użyć standardowego menedżera pakietów systemu Linux. Na przykład w Red Hat Enterprise Linux 8 lub Fedora robi się to tak:

$ sudo dnf install yamllint

Następnie po prostu uruchamiasz yamllint, przekazując mu plik YAML do sprawdzenia. Tak to wygląda, jeśli przekażesz plik z błędem do lintera:

$ yamllint errorprone.yaml
errorprone.yaml
23:10     error    syntax error: mapping values are not allowed here
23:11     error    trailing spaces  (trailing-spaces)

Liczby po lewej stronie to nie czas, ale współrzędne błędu: numer wiersza i kolumny. Opis błędu może nic ci nie mówi, ale wiesz dokładnie, gdzie on jest. Wystarczy spojrzeć na to miejsce w kodzie, a najprawdopodobniej wszystko stanie się jasne.

Gdy yamllint nie znajdzie żadnych błędów w pliku, nic nie zostanie wydrukowane na ekranie. Jeśli taka cisza cię przeraża i chcesz trochę więcej informacji zwrotnych, możesz uruchomić linter za pomocą polecenia warunkowego echa za pomocą podwójnego ampersandu (&&), w ten sposób:

$ yamllint perfect.yaml && echo "OK"
OK

W POSIX podwójny ampersand jest uruchamiany wtedy i tylko wtedy, gdy poprzednie polecenie zwróci 0. Yamllint po prostu zwraca liczbę znalezionych błędów i dlatego działa cała ta konstrukcja warunkowa.

2. Pisz w Pythonie, a nie YAML

Jeśli YAML naprawdę Cię wkurza, po prostu nie pisz w nim, dosłownie. Zdarza się, że YAML jest jedynym formatem, jaki aplikacja rozumie. Ale nawet w tym przypadku nie jest konieczne tworzenie pliku YAML. Napisz o tym, co lubisz, a następnie konwertuj. Na przykład istnieje świetna biblioteka dla Pythona pyyaml oraz dwie metody konwersji: samokonwersja i konwersja poprzez skrypty.

Samonawrócenie

W tym przypadku plikiem danych jest także skrypt Pythona generujący YAML. Ta metoda najlepiej nadaje się do małych zbiorów danych. Po prostu zapisujesz dane JSON w zmiennej Pythona, poprzedzisz je dyrektywą importu, a na końcu pliku dodasz trzy wiersze, aby zaimplementować dane wyjściowe.

#!/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

Teraz uruchamiamy ten plik w Pythonie i otrzymujemy plik wyjściowy.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

Jest to całkowicie poprawny YAML, ale Yamllint ostrzeże Cię, że nie zaczyna się od -. Cóż, można to łatwo poprawić ręcznie lub nieco zmodyfikować w skrypcie Pythona.

Konwersja za pomocą skryptów

W tym przypadku najpierw piszemy w JSON, a następnie uruchamiamy konwerter jako oddzielny skrypt w Pythonie, który generuje jako wynik YAML. W porównaniu z poprzednią metodą ta metoda skaluje się lepiej, ponieważ konwersja jest oddzielona od danych.

Najpierw utwórzmy plik JSON przykład.json, z którego możesz go na przykład pobrać json.org:

{
	"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"
			}
		  }
		}
	  }
	}

Następnie utworzymy prosty skrypt konwertera i zapiszemy go pod nazwą json2yaml.py. Ten skrypt importuje moduły Pythona YAML i JSON, ładuje określony przez użytkownika plik JSON, wykonuje konwersję i zapisuje dane w pliku 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()

Zapisz ten skrypt w ścieżce systemowej i uruchom go w razie potrzeby:

$ ~/bin/json2yaml.py example.json

3. Analizuj dużo i często

Czasami warto spojrzeć na problem z innej perspektywy. Jeśli masz problemy z przedstawieniem relacji między danymi w YAML, możesz tymczasowo przekształcić je w coś bardziej znanego.

Na przykład, jeśli nie masz problemu z pracą z listami słownikowymi lub JSON, możesz przekonwertować YAML na JSON za pomocą zaledwie dwóch poleceń w interaktywnej powłoce Pythona. Załóżmy, że masz plik YAML mydata.yaml, a tak by to wyglądało:

$ 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.'}

Można znaleźć wiele innych przykładów na ten temat. Ponadto dostępnych jest wiele konwerterów online i lokalnych parserów. Nie wahaj się więc ponownie sformatować danych, jeśli zobaczysz w nich jedynie niezrozumiały bałagan.

4. Przeczytaj specyfikację

Wracając do YAML po dłuższej przerwie warto odwiedzić yaml.org i ponownie przeczytaj specyfikacje (specyfikacje). Jeśli masz problemy z YAML, ale nie zapoznałeś się ze specyfikacją, czas naprawić tę sytuację. Specyfikacje są zaskakująco łatwe do napisania, a wymagania dotyczące składni zilustrowano dużą liczbą przykładów Rozdział 6.

5. Pseudokonfiguracje

Pisząc książkę lub artykuł, zawsze warto najpierw naszkicować wstępny zarys, przynajmniej w formie spisu treści. Podobnie jest z YAML-em. Najprawdopodobniej masz pojęcie, jakie dane należy zapisać w pliku YAML, ale nie do końca wiesz, jak je ze sobą połączyć. Dlatego przed wyrzeźbieniem YAML narysuj pseudokonfigurację.

Pseudo-config jest podobny do pseudokodu, w którym nie musisz się martwić o strukturę ani wcięcia, relacje rodzic-dziecko, dziedziczenie i zagnieżdżanie. Tutaj jest tak samo: rysujesz iteracje danych w miarę ich pojawiania się w Twojej głowie.

10 kroków do YAML Zen

Pseudo-config wyświetla listę programistów (Martin i Tabitha) i ich umiejętności (odpowiednio języki programowania: Python, Perl, Pascal i Lisp, Fortran, Erlang).

Po narysowaniu pseudokonfiguracji na kartce papieru dokładnie ją przeanalizuj i jeśli wszystko jest w porządku, sformatuj ją w postaci prawidłowego pliku YAML.

6. Dylemat Tabulatory kontra Spacje

Będziesz musiał rozwiązać dylemat „tabulatory czy spacje?”. Nie w sensie globalnym, ale tylko na poziomie Twojej organizacji lub przynajmniej projektu. Nie ma znaczenia, czy chodzi o postprocessing ze skryptem sed, konfigurowanie edytorów tekstu na maszynach programistów, czy też powszechne przyjmowanie paragonów za ścisłe przestrzeganie instrukcji lintera pod groźbą zwolnienia, ale wszyscy członkowie Twojego zespołu, którzy w w ten czy inny sposób odnoszą się do YAML, należy używać wyłącznie spacji (zgodnie z wymaganiami specyfikacji YAML).

W dowolnym normalnym edytorze tekstu możesz skonfigurować automatyczną korektę tabulatorów do określonej liczby spacji, więc bunt kluczowych zwolenników zakładka nie musisz się bać.

Jak dobrze wie każdy hejter YAML, nie widać różnicy pomiędzy tabulatorami i spacjami na ekranie. A gdy czegoś nie widać, to zazwyczaj jest to ostatnia rzecz, o której ludzie pamiętają, po przejrzeniu, sprawdzeniu i wyeliminowaniu wszystkich innych możliwych problemów. Godzina spędzona na poszukiwaniu krzywej tabelarycznej lub bloku spacji po prostu krzyczy, że należy pilnie stworzyć politykę korzystania z jednego lub drugiego, a następnie wdrożyć żelbetową kontrolę zgodności z nią (na przykład poprzez hak Git, aby przecisnąć go przez linter).

7. Mniej znaczy więcej (lub więcej znaczy mniej)

Niektórzy ludzie lubią pisać w YAML, ponieważ podkreśla to strukturę. Jednocześnie aktywnie wykorzystują wcięcia do wyróżniania bloków danych. Jest to rodzaj oszustwa mającego na celu imitację języków znaczników, które używają wyraźnych ograniczników.

Oto przykład takiej konstrukcji z Dokumentacja Ansibla:

# Employee records
-  martin:
        name: Martin D'vloper
        job: Developer
        skills:
            - python
            - perl
            - pascal
-  tabitha:
        name: Tabitha Bitumen
        job: Developer
        skills:
            - lisp
            - fortran
            - erlang

Niektórym ta opcja pomaga uporządkować w głowie strukturę YAML, innych wręcz przeciwnie irytuje dużą ilością niepotrzebnych ich zdaniem wcięć.

Ale jeśli jesteś właścicielem dokumentu YAML i jesteś odpowiedzialny za jego utrzymanie, to ty i tylko Ty należy określić, jak używać wcięć. Jeśli denerwuje Cię duże wypełnienie, ogranicz je do minimum, zgodnie ze specyfikacją YAML. Na przykład powyższy plik z dokumentacji Ansible można przepisać w ten sposób bez żadnych strat:

---
- martin:
   name: Martin D'vloper
   job: Developer
   skills:
   - python
   - perl
   - pascal
- tabitha:
   name: Tabitha Bitumen
   job: Developer
   skills:
   - lisp
   - fortran
   - erlang

8. Użyj spacji

Jeżeli przy wypełnianiu pliku YAML powtarzasz te same błędy, warto wstawić do niego szablon w formie komentarza. Następnym razem możesz po prostu skopiować ten szablon i wprowadzić tam prawdziwe dane, na przykład:

---
# - <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. Użyj czegoś innego

Jeśli aplikacja nie ma nad tobą kontroli, może warto zmienić YAML na inny format. Z biegiem czasu pliki konfiguracyjne mogą same urosnąć i wtedy lepiej je przekonwertować na proste skrypty w Lua lub Pythonie.

YAML to świetna rzecz, którą wiele osób uwielbia za swój minimalizm i prostotę, ale nie jest to jedyne narzędzie w Twoim arsenale. Czasem więc można odmówić. Biblioteki parsujące są łatwe do znalezienia dla YAML, więc jeśli zaoferujesz łatwe opcje migracji, Twoi użytkownicy przetrwają tę awarię stosunkowo bezboleśnie.

Jeśli nie możesz obejść się bez YAML, skorzystaj z tych 10 wskazówek i raz na zawsze pokonaj swoją niechęć do YAML!

Źródło: www.habr.com

Dodaj komentarz