通向 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 时遇到困难,但还没有了解规范,那么是时候纠正这种情况了。 这些规范非常容易编写,并且语法要求通过大量示例进行了说明 第九章.

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 的厌恶!

来源: habr.com

添加评论