Spring创始人Rod大叔对YAML的真实想法

19-03-21 banq
              

如果你在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: "production"
    RAILS_ENV: "production"
    SETUP_DB: "false"
    SKIP_STORAGE_VALIDATION: "true"
    WEBPACK_REPORT: "true"
    # we override the max_old_space_size to prevent OOM errors
    NODE_OPTIONS: --max_old_space_size=3584
    DOCKER_DRIVER: overlay2
    DOCKER_HOST: tcp://docker:2375
  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/
      - public/assets/

请注意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
      default: /workspace/workspace/Dockerfile
    - name: pathToContext
      description: The build context used by Kaniko (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
      default: /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}

哎哟,变量,合格的名字?参数?这不是结构化数据,这是伪装成配置的编程。

我们之前没有遇到变量和连续指令等概念吗?为什么笨拙地重新发明命令式编程?模块化和可测试性如何?那么可以用编程语言免费获得的可扩展性呢?为什么要重新发明在现代语言中严格定义的异常处理?逻辑运算怎么样,更不用说更先进和优雅的FP或OOP概念了?

支持这种基于YAML的语法的最佳理由是它是一个外部DSL,强制执行一个有益的结构。但是,由于以下几个原因,这样的理由就不成立:

  • 规定性结构在很大程度上是一种幻觉。工作的大部分被压入等shell脚本(GitLab例子),在实践中,它是狂野的西部。
  • 如果在DSL的设计中缺少一个步骤,那么你就会碰壁。例如,CI工具通常将交付阶段建模为YAML节。如果你需要一个独特的阶段,你可能会运气不好。
  • 对于外部DSL来说,YAML是一种糟糕的格式,就像XML一样。流行的配置格式总是被这种方式误用。

无论如何,你可能不需要外部DSL:我们在Atomist上学到了很多东西。

外部DSL ......就像小狗一样,它们都开始可爱而快乐,但随着它们的成长,它们无一例外地变成了恶毒的野兽。

现代编程语言足够灵活,可以使内部DSL越来越引人注目,具有更好的工具和可扩展性。

试图将数据格式用作编程语言是错误的。这样使用它实际与数据格式的优点无关。

YAML作为数据格式是可以的。YAML不是一种编程语言。如果您正在编程,请使用编程语言。你应该归功于Turing,Hopper,Djikstra以及无数其他计算机科学家和从业者,他们建立了我们的计算机学科。要用到你所学!

              

2