如果你在Twitter上关注我,你可能会认为我讨厌YAML。
我不反对YAML,只是反对滥用 YAML。我想帮助防止人们滥用YAML并在此过程中无意对自己和同事施加了残忍。
YAML的优势在于结构化数据格式。是的,它有问题。空白是一个雷区。它的语法非常复杂。它有这样的结论:“ 任何使用YAML的人都会在试图缩写Norway时最终被烧毁 。” 但是YAML是人类可读的并且支持评论:这是推动其受欢迎的两个主要好处。
它可能出错的地方是我们使用YAML来描述行为的地方。
考虑CI域中的一些示例。这不是YAML以这种方式被滥用的唯一领域,但它是最严重的罪犯之一。
以 GitLab的管道定义来实现自己 :1170行:
gitlab:assets:compile:
<<: *dedicated-no-docs-pull-cache-job
image: dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.5.3-git-2.18-chrome-71.0-node-8.x-yarn-1.12-graphicsmagick-1.3.29-docker-18.06.1
dependencies:
- setup-test-env
services:
- docker:stable-dind
variables:
NODE_ENV: <font>"production"</font><font>
RAILS_ENV: </font><font>"production"</font><font>
SETUP_DB: </font><font>"false"</font><font>
SKIP_STORAGE_VALIDATION: </font><font>"true"</font><font>
WEBPACK_REPORT: </font><font>"true"</font><font>
# we override the max_old_space_size to prevent OOM errors
NODE_OPTIONS: --max_old_space_size=3584
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp:</font><font><i>//docker:2375</i></font><font>
script:
- node --version
- yarn install --frozen-lockfile --production --cache-folder .yarn-cache
- free -m
- bundle exec rake gitlab:assets:compile
- time scripts/build_assets_image
- scripts/clean-old-cached-assets
artifacts:
name: webpack-report
expire_in: 31d
paths:
- webpack-report/
- <b>public</b>/assets/
</font>
请注意script包含shell脚本列表的块。这看起来像数据吗?这是指定执行的正确模型吗?
有许多类似的案例。以下是Tekton 示例中 的一个片段,这是一种基于Kubernetes的新型交付解决方案:
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: build-push
spec:
inputs:
resources:
- name: workspace
type: git
params:
- name: pathToDockerFile
description: The path to the dockerfile to build
<b>default</b>: /workspace/workspace/Dockerfile
- name: pathToContext
description: The build context used by Kaniko (https:<font><i>//github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)</i></font><font>
<b>default</b>: /workspace/workspace
outputs:
resources:
- name: builtImage
type: image
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor
command:
- /kaniko/executor
args:
- --dockerfile=${inputs.params.pathToDockerFile}
- --destination=${outputs.resources.builtImage.url}
- --context=${inputs.params.pathToContext}
</font>
哎哟,变量,合格的名字?参数?这不是结构化数据,这是伪装成配置的编程。
我们之前没有遇到变量和连续指令等概念吗?为什么笨拙地重新发明命令式编程?模块化和可测试性如何?那么可以用编程语言免费获得的可扩展性呢?为什么要重新发明在现代语言中严格定义的异常处理?逻辑运算怎么样,更不用说更先进和优雅的FP或OOP概念了?
支持这种基于YAML的语法的最佳理由是它是一个外部DSL,强制执行一个有益的结构。但是,由于以下几个原因,这样的理由就不成立:
无论如何,你可能不需要外部DSL:我们在Atomist上学到了很多东西。
外部DSL ......就像小狗一样 ,它们都开始可爱而快乐,但随着它们的成长,它们无一例外地变成了恶毒的野兽。
现代编程语言足够灵活,可以使内部DSL越来越引人注目,具有更好的工具和可扩展性。
试图将数据格式用作编程语言是错误的。这样使用它实际与数据格式的优点无关。
YAML作为数据格式是可以的。YAML不是一种编程语言。如果您正在编程,请使用编程语言。你应该归功于Turing,Hopper,Djikstra以及无数其他计算机科学家和从业者,他们建立了我们的计算机学科。要用到你所学!