如果你在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以及无数其他计算机科学家和从业者,他们建立了我们的计算机学科。要用到你所学!