Spring創始人Rod大叔對YAML的真實想法

banq發表於2019-03-21

如果你在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/kanikokaniko-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以及無數其他電腦科學家和從業者,他們建立了我們的計算機學科。要用到你所學!

相關文章