Summary
A new, non-standard builtin providing simple YAML operations, mirroring the json builtin (#561) semantics. YAML is the dominant config format (Kubernetes, CI/CD, Ansible, Docker Compose, GitHub Actions) — yet shell tooling for it is poor. yq exists but isn't standard and has competing incompatible versions.
Note: This is a bashkit-specific extension, not a standard command. Mirrors the json builtin API for consistency.
Proposed Syntax
yaml <subcommand> [args...] [< input]
Proposed Subcommands
| Subcommand |
Description |
yaml get .path |
Extract value at dot-notation path |
yaml set .path value |
Set value at path |
yaml delete .path |
Remove key at path |
yaml merge file1 file2 |
Deep merge two YAML documents |
yaml keys |
List top-level keys |
yaml type .path |
Print type (string, number, mapping, sequence, bool, null) |
yaml valid |
Validate YAML (exit 0 if valid, 1 if not) |
yaml fmt |
Pretty-print / normalize YAML |
yaml each .path |
Iterate sequence, output one element per line |
yaml to-json |
Convert YAML to JSON |
yaml from-json |
Convert JSON to YAML |
Use Cases
# Read a value from config
yaml get .database.host < config.yaml
# localhost
# Set a value
yaml set .database.port 5432 < config.yaml > updated.yaml
# Merge configs (override takes precedence)
yaml merge defaults.yaml overrides.yaml > config.yaml
# Validate before deploying
if yaml valid < deployment.yaml; then
kubectl apply -f deployment.yaml
fi
# Iterate over list items
yaml each .services < docker-compose.yaml
# web
# db
# redis
# Extract nested value from GitHub Actions
yaml get .jobs.build.runs-on < .github/workflows/ci.yaml
# ubuntu-latest
# Convert between formats
yaml to-json < config.yaml | json get .version
cat config.json | yaml from-json > config.yaml
# Pipeline: modify and write back
cat deployment.yaml \
| yaml set .spec.replicas 3 \
| yaml set .spec.template.spec.containers[0].image "app:v2" \
> deployment-updated.yaml
# Multi-document support (--- separator)
yaml get .metadata.name --document 1 < multi.yaml
Proposed Flags
| Flag |
Description |
--document N / -d N |
Select Nth document in multi-document YAML (0-indexed, default 0) |
--all-documents |
Apply operation to all documents |
--in-place FILE / -i FILE |
Modify file in place |
Path Notation
Same dot notation as json builtin for consistency:
.foo.bar — nested key access
.items[0] — sequence index
.items[-1] — last element
.items[*] — all elements
. — root document
YAML-Specific Considerations
| Feature |
Handling |
Multi-document (---) |
--document N to select, default is first |
Anchors & aliases (&/*) |
Resolved on read, not preserved on write |
| Comments |
Preserved where possible (best-effort) |
| Quoted strings |
Round-trip preserves quoting style |
| Flow vs block style |
yaml fmt normalizes to block style |
Tags (!!str, !!int) |
Supported but rarely needed |
null vs missing |
yaml get returns empty string + exit 1 for missing; literal "null" for explicit null |
Implementation Notes
- Use
serde_yaml or yaml-rust2 crate for parsing/serialization
- Path resolution logic shared with
json builtin (extract into common module)
yaml to-json and yaml from-json enable interop with jq for complex queries
- Multi-document YAML is common in Kubernetes — must handle
--- separators
- Comment preservation is a differentiator vs
yq — use a parser that tracks comments if possible
- Exit codes match
json builtin: 0 = success, 1 = path not found or invalid YAML
- YAML is a superset of JSON, so
yaml can also parse JSON input
Summary
A new, non-standard builtin providing simple YAML operations, mirroring the
jsonbuiltin (#561) semantics. YAML is the dominant config format (Kubernetes, CI/CD, Ansible, Docker Compose, GitHub Actions) — yet shell tooling for it is poor.yqexists but isn't standard and has competing incompatible versions.Note: This is a bashkit-specific extension, not a standard command. Mirrors the
jsonbuiltin API for consistency.Proposed Syntax
Proposed Subcommands
yaml get .pathyaml set .path valueyaml delete .pathyaml merge file1 file2yaml keysyaml type .pathyaml validyaml fmtyaml each .pathyaml to-jsonyaml from-jsonUse Cases
Proposed Flags
--document N/-d N--all-documents--in-place FILE/-i FILEPath Notation
Same dot notation as
jsonbuiltin for consistency:.foo.bar— nested key access.items[0]— sequence index.items[-1]— last element.items[*]— all elements.— root documentYAML-Specific Considerations
---)--document Nto select, default is first&/*)yaml fmtnormalizes to block style!!str,!!int)nullvs missingyaml getreturns empty string + exit 1 for missing; literal "null" for explicit nullImplementation Notes
serde_yamloryaml-rust2crate for parsing/serializationjsonbuiltin (extract into common module)yaml to-jsonandyaml from-jsonenable interop withjqfor complex queries---separatorsyq— use a parser that tracks comments if possiblejsonbuiltin: 0 = success, 1 = path not found or invalid YAMLyamlcan also parse JSON input