このページは FormatArc のブログ記事が引用している実測の生データです。検索結果には表示されません (noindex)。
| File | Size |
|---|---|
| README.md | 3.2 KB |
| fixtures/compose-anchor-merge.yaml | 92 B |
| fixtures/compose-multidoc.yaml | 86 B |
| measure-compose.sh | 1.2 KB |
| measure.mjs | 2.3 KB |
| measure.py | 2.4 KB |
| merge.mjs | 1.4 KB |
| package-lock.json | 1.4 KB |
| package.json | 249 B |
| results-compose.json | 327 B |
| results-node.json | 1.3 KB |
| results-python.json | 1.5 KB |
| results.json | 3.5 KB |
# 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` の値および上記外部ソース原典と完全一致させること
(数値・文言の捏造禁止ルール準拠)。
{
"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/"
}
}