yaml-tool-acceptance

このページは FormatArc のブログ記事が引用している実測の生データです。検索結果には表示されません (noindex)。

Files

FileSize
README.md3.2 KB
fixtures/compose-anchor-merge.yaml92 B
fixtures/compose-multidoc.yaml86 B
measure-compose.sh1.2 KB
measure.mjs2.3 KB
measure.py2.4 KB
merge.mjs1.4 KB
package-lock.json1.4 KB
package.json249 B
results-compose.json327 B
results-node.json1.3 KB
results-python.json1.5 KB
results.json3.5 KB

README.md

# YAML feature acceptance across parsers and tools (measured)

`yaml-syntax-guide` 記事の「アンカー・マージキー・マルチドキュメント × ツール対応表」の
一次ソース。アンカー/エイリアス (`&` `*`)・マージキー (`<<:`)・マルチドキュメント (`---`)
の 3 機能を、主要 4 パーサーと Docker Compose に実際に食わせて受理/拒否を記録する。

`../yaml-syntax-errors/` (不正 YAML のエラーメッセージ) や `../yaml-parser-differences/`
(曖昧スカラーの型解決差) とは測定軸が別: こちらは **valid YAML の機能受理可否** を扱う。

## 測定対象 (ローカル実測)

| 対象 | バージョン | 実行系 |
| --- | --- | --- |
| js-yaml (`load` / `loadAll`, DEFAULT_SCHEMA) | 4.1.1 | Node v26.3.1 |
| yaml (eemeli, `parse` / `parseAllDocuments` defaults) | 2.8.3 | Node v26.3.1 |
| PyYAML (`safe_load` / `safe_load_all`) | 6.0.3 | Python 3.14.6 |
| ruamel.yaml (`YAML(typ="safe")` `load` / `load_all`) | 0.19.1 | Python 3.14.6 |
| Docker Compose (`docker compose config`) | v5.3.0 | Docker 29.6.1 |

実行環境: Apple M5 Pro / macOS (Darwin 25.5.0)。

## 外部ソース (ローカル実測不能なホスト型ツール、原典 URL を results.json に記録)

- GitHub Actions アンカー対応 (2025-09-18): [GitHub Changelog](https://github.blog/changelog/2025-09-18-actions-yaml-anchors-and-non-public-workflow-templates/)
- GitHub Actions マージキー未対応 (silently fail): [frenck.dev 検証](https://frenck.dev/github-actions-yaml-anchors-aliases-merge-keys/)
- GitLab CI アンカー + マージキー対応: [GitLab docs](https://docs.gitlab.com/ee/ci/yaml/yaml_optimization/)
- Kubernetes マルチドキュメント対応: [Kubernetes docs](https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/)

## 再現手順

```bash
cd scripts/benchmarks/yaml-tool-acceptance

# Node 側 (js-yaml + eemeli yaml) → results-node.json
npm install
node measure.mjs

# Python 側 (PyYAML + ruamel.yaml) → results-python.json
python3 -m venv venv
./venv/bin/pip install pyyaml ruamel.yaml
./venv/bin/python measure.py

# Docker Compose → results-compose.json (Docker Desktop 必須)
bash measure-compose.sh

# 結合 → results.json
node merge.mjs
```

## 主要な発見 (results.json より)

- **eemeli yaml 2.8.3 の `parse` (defaults) はマージキー `<<:` を展開しない**。
  `{"child":{"<<":{"x":1},"y":2}}` のように `<<` が文字通りのキーとして残る
  (YAML 1.2 でマージキーが仕様から外れたため)。js-yaml / PyYAML / ruamel は展開する
- マルチドキュメントは 4 パーサーとも単発 API (`load` / `parse` / `safe_load`) では
  エラー、複数 API (`loadAll` / `parseAllDocuments` / `safe_load_all` / `load_all`)
  で受理。エラーメッセージは各パーサーで異なる
- Docker Compose はアンカー + マージキーを受理し、マルチドキュメントは
  **複数ドキュメントを 1 つの config にマージして受理する** (拒否しない)

記事本文の表は `results.json` の値および上記外部ソース原典と完全一致させること
(数値・文言の捏造禁止ルール準拠)。

results.json

{
  "environment": {
    "node": "v26.3.1",
    "python": "3.14.6",
    "composeVersion": "5.3.0",
    "machine": "Apple M5 Pro / macOS (Darwin 25.5.0)"
  },
  "parsers": [
    {
      "parser": "js-yaml 4.1.1",
      "results": {
        "anchor-alias": {
          "outcome": "accepted",
          "repr": "{\"base\":{\"x\":1},\"child\":{\"x\":1}}"
        },
        "merge-key": {
          "outcome": "accepted",
          "repr": "{\"base\":{\"x\":1},\"child\":{\"x\":1,\"y\":2}}"
        },
        "multi-doc-load": {
          "outcome": "error",
          "message": "expected a single document in the stream, but found more"
        },
        "multi-doc-loadAll": {
          "outcome": "accepted",
          "repr": "[{\"a\":1},{\"b\":2}]"
        }
      }
    },
    {
      "parser": "yaml (eemeli) 2.8.3",
      "results": {
        "anchor-alias": {
          "outcome": "accepted",
          "repr": "{\"base\":{\"x\":1},\"child\":{\"x\":1}}"
        },
        "merge-key": {
          "outcome": "accepted",
          "repr": "{\"base\":{\"x\":1},\"child\":{\"<<\":{\"x\":1},\"y\":2}}"
        },
        "multi-doc-load": {
          "outcome": "error",
          "message": "Source contains multiple documents; please use YAML.parseAllDocuments() at line 2, column 1:"
        },
        "multi-doc-loadAll": {
          "outcome": "accepted",
          "repr": "[{\"a\":1},{\"b\":2}]"
        }
      }
    },
    {
      "parser": "PyYAML 6.0.3",
      "results": {
        "anchor-alias": {
          "outcome": "accepted",
          "repr": "{\"base\": {\"x\": 1}, \"child\": {\"x\": 1}}"
        },
        "merge-key": {
          "outcome": "accepted",
          "repr": "{\"base\": {\"x\": 1}, \"child\": {\"x\": 1, \"y\": 2}}"
        },
        "multi-doc-load": {
          "outcome": "error",
          "message": "expected a single document in the stream in \"<unicode string>\", line 1, column 1: a: 1 ^ but found another document in \"<unicode string>\", line 2, column 1: --- ^"
        },
        "multi-doc-loadAll": {
          "outcome": "accepted",
          "repr": "[{\"a\": 1}, {\"b\": 2}]"
        }
      }
    },
    {
      "parser": "ruamel.yaml 0.19.1",
      "results": {
        "anchor-alias": {
          "outcome": "accepted",
          "repr": "{\"base\": {\"x\": 1}, \"child\": {\"x\": 1}}"
        },
        "merge-key": {
          "outcome": "accepted",
          "repr": "{\"base\": {\"x\": 1}, \"child\": {\"x\": 1, \"y\": 2}}"
        },
        "multi-doc-load": {
          "outcome": "error",
          "message": "expected a single document in the stream in \"<file>\", line 1, column 1 but found another document in \"<file>\", line 2, column 1"
        },
        "multi-doc-loadAll": {
          "outcome": "accepted",
          "repr": "[{\"a\": 1}, {\"b\": 2}]"
        }
      }
    }
  ],
  "dockerCompose": [
    {
      "id": "anchor-merge",
      "outcome": "accepted",
      "services": 3
    },
    {
      "id": "multi-doc",
      "outcome": "accepted",
      "services": 3
    }
  ],
  "externalSources": {
    "github-actions-anchors": "https://github.blog/changelog/2025-09-18-actions-yaml-anchors-and-non-public-workflow-templates/",
    "github-actions-merge-keys-not-supported": "https://frenck.dev/github-actions-yaml-anchors-aliases-merge-keys/",
    "gitlab-ci-anchors-merge-keys": "https://docs.gitlab.com/ee/ci/yaml/yaml_optimization/",
    "kubernetes-multi-doc": "https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/"
  }
}