通往 YAML Zen 的 10 個步驟

我們都喜歡 Ansible,但 Ansible 是 YAML。 設定檔有多種格式:值清單、參數值對、INI 檔案、YAML、JSON、XML 等等。 然而,由於多種原因,YAML 通常被認為特別困難。 特別是,儘管 YAML 語法具有令人耳目一新的極簡主義和令人印象深刻的處理分層值的功能,但其類似於 Python 的縮排方法可能會令人煩惱。

通往 YAML Zen 的 10 個步驟

如果 YAML 惹惱了你,你可以——而且應該! – 採取以下 10 個步驟將您的挫折感減少到可接受的水平並愛上 YAML。 為了適合這個列表,我們的十個技巧將從頭開始編號,我們將隨意添加冥想和精神實踐😉

0. 讓你的編輯器發揮作用

無論您使用哪種文字編輯器,都可能至少有一個用於使用 YAML 的插件。 如果您沒有,請立即尋找並安裝。 與每次編輯 YAML 相比,搜尋和設定所花費的時間會帶來數倍的回報。

例如,編輯器 原子 預設支援 YAML,但對於 GNU Emacs,您必須安裝其他軟體包,例如, yaml 模式.

通往 YAML Zen 的 10 個步驟

YAML 模式下的 Emacs 並顯示空格。

如果您最喜歡的編輯器沒有 YAML 模式,那麼可以透過設定來解決一些問題。 例如,標準 GNOME 文字編輯器 Gedit 沒有 YAML 模式,但預設情況下它會反白顯示 YAML 語法並允許您配置縮排:

通往 YAML Zen 的 10 個步驟

在 Gedit 中設定縮排。

一個插件 繪圖空間 對於 Gedit,將空格顯示為點,從而消除縮排等級的歧義。

換句話說,花時間了解您最喜歡的編輯器。 了解他或他的開發社群必須為使用 YAML 提供哪些功能,並使用這些功能。 你絕對不會後悔的。

1. 使用短絨檢查器

理想情況下,程式語言和標記語言使用可預測的語法。 計算機擅長預測,這就是為什麼「計算機」的概念 林特拉。 如果它已經存在 40 年了,但您仍然不使用 YAML linter,那麼是時候嘗試 yamllint 了。

建立 亞姆林特 您可以使用標準的 Linux 套件管理器。 例如,在 紅帽企業Linux 8或 Fedora 它是這樣完成的:

$ sudo dnf install yamllint

然後,您只需運行 yamllint,將 YAML 檔案傳遞給它進行檢查。 如果將有錯誤的檔案傳遞給 linter,則結果如下所示:

$ 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 命令來執行 linter,如下所示:

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

在 POSIX 中,當且僅當前面的命令返回 0 時,才會觸發雙 & 符號。並且 yamllint 只返回找到的錯誤數,這就是整個條件構造起作用的原因。

2. 用Python編寫,而不是YAML

如果 YAML 真的讓你惱火,那就不要直接寫進去。 YAML 恰好是應用程式可以理解的唯一格式。 但即使在這種情況下,也沒有必要建立 YAML 檔案。 寫下你喜歡的內容,然後轉換。 例如,有一個很棒的 Python 庫 皮亞姆爾 轉換方式有自行轉換和腳本轉換兩種。

自我轉變

在這種情況下,資料檔案也是產生 YAML 的 Python 腳本。 此方法最適合小數據集。 您只需將 JSON 資料寫入 Python 變量,在其前面加上導入指令,然後在文件末尾添加三行即可實現輸出。

#!/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,例如,您可以從 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"
			}
		  }
		}
	  }
	}

然後我們將建立一個簡單的轉換器腳本並將其保存在名稱 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()

將此腳本保存在系統路徑中並根據需要運行:

$ ~/bin/json2yaml.py example.json

3. 經常進行大量解析

有時從不同的角度看問題是有用的。 如果您在以 YAML 表示資料之間的關係時遇到困難,可以暫時轉換為更熟悉的內容。

例如,如果您習慣使用字典清單或 JSON,則只需在互動式 Python shell 中使用兩個命令即可將 YAML 轉換為 JSON。 假設您有一個 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,訪問還是很有用的 yaml.org 並重新閱讀規格(specs)。 如果您在使用 YAML 時遇到困難,但還沒有了解規範,那麼是時候糾正這種情況了。 這些規範非常容易編寫,並且語法要求通過大量示例進行了說明 第6章.

5. 偽配置

在寫一本書或文章時,首先勾畫出初步的大綱(至少以目錄的形式)總是有用的。 YAML 也是如此。 最有可能的是,您知道需要將哪些資料寫入 YAML 文件,但您並不真正了解如何將它們相互連接。 因此,在雕刻 YAML 之前,先繪製一個偽配置。

偽配置類似於偽代碼,您不必擔心結構或縮排、父子關係、繼承和巢狀。 這裡也是一樣的:當資料出現在你的腦海中時,你會繪製資料的迭代。

通往 YAML Zen 的 10 個步驟

偽配置列出程式設計師(Martin 和 Tabitha)及其技能(程式語言:分別為 Python、Perl、Pascal 和 Lisp、Fortran、Erlang)。

在紙上繪製偽配置後,仔細分析它,如果一切正常,則將其格式化為有效的 YAML 檔案的形式。

6.製表符與空格的困境

你必須解決這個困境 “製表符還是空格?”。 不是在全球意義上,而是在您的組織或至少是一個專案的層面上。 無論這是否涉及使用 sed 腳本進行後處理、在程式設計師的機器上設定文字編​​輯器,還是在解僱的威脅下普遍接受嚴格遵守 linter 指令的收據,都無關緊要,但團隊中的所有成員與YAML 相關的一種或另一種方式必須僅使用空格(根據YAML 規範的要求)。

在任何普通的文字編輯器中,您都可以將自動更正製表符配置為指定數量的空格,因此關鍵追隨者的叛逆 標籤 你不必害怕。

正如每個 YAML 討厭者都清楚的那樣,您在螢幕上看不到製表符和空格之間的區別。 當某些東西不可見時,它通常是人們在整理、檢查並排除所有其他可能的問題之後記得的最後一件事。 花費一個小時的時間搜索表格曲線或一塊空間只是尖叫著您迫切需要創建一個使用其中一個或另一個的策略,然後實施鋼筋混凝土檢查以確保其符合性(例如,通過一個Git 鉤子來強制它通過linter)。

7. 少即是多(或多即是少)

有些人喜歡用 YAML 編寫,因為它強調結構。 同時,他們積極使用縮進來突出顯示資料塊。 這是一種模仿使用顯式分隔符號的標記語言的騙局。

這是此類結構的範例 Ansible 文檔:

# 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 的厭惡!

來源: www.habr.com

添加評論