yq — Antora
Attribute Inventory
The single most frequent yq operation in this repository: inspecting antora.yml attributes.
yq '.asciidoc.attributes | keys | length' docs/antora.yml
# Output: ~134 (grows as infrastructure expands)
yq -r '.asciidoc.attributes | keys | .[]' docs/antora.yml | head -20
# Output:
# ad-dc-hostname
# ad-dc-ip
# attribute-missing
# author
# bind-ip
# bt-buds-mac
# bt-buds-name
# bt-kinesis-mac
# bt-kinesis-name
# category
# ...
yq -r '.asciidoc.attributes | to_entries[] | select(.key | test("^ise-")) | "\(.key): \(.value)"' docs/antora.yml
# Output:
# ise-hostname: ise-01.inside.domusdigitalis.dev
# ise-ip: 10.50.1.20
# ise-ers-port: 9060
# ise-openapi-port: 443
# ise-mnt-port: 443
# ise-dc-port: 2484
# ise-pxgrid-port: 8910
Attribute Auditing Patterns
yq -r '.asciidoc.attributes | to_entries[] | select(.value | type == "!!str" and test("^10\\.50\\.")) | "\(.key): \(.value)"' docs/antora.yml
# Output: every attribute containing a 10.50.x.x IP
This is the audit command for IP sprawl. Run it before any network migration to find every reference.
yq -r '.asciidoc.attributes | to_entries[] | select(.key | test("-hostname$")) | "\(.key): \(.value)"' docs/antora.yml
# Output:
# ise-hostname: ise-01.inside.domusdigitalis.dev
# vault-hostname: vault-01.inside.domusdigitalis.dev
# vault-01-hostname: vault-01.inside.domusdigitalis.dev
# pfsense-hostname: pfsense-01.inside.domusdigitalis.dev
# wlc-hostname: wlc-01.inside.domusdigitalis.dev
# nas-hostname: nas-01.inside.domusdigitalis.dev
# ...
yq -r '.asciidoc.attributes | to_entries[] | select(.key | test("pfsense")) | "\(.key): \(.value)"' docs/antora.yml
# Output:
# pfsense-hostname: pfsense-01.inside.domusdigitalis.dev
# pfsense-ip: 10.50.1.1
# pfsense-api-port: 443
These are retained for historical document references — not active infrastructure.
yq -r '.asciidoc.attributes | keys | .[]' docs/antora.yml | awk -F- '{print $1}' | sort | uniq -c | sort -rn | head -15
# Output (approximate):
# 12 port
# 10 stats
# 8 ise
# 7 vault
# 6 focus
# 5 vyos
# 5 origin
# 5 level
# 4 kvm
# 4 bt
# 3 ws
# 3 type
# 3 status
# 2 nas
# 2 mail
Combining yq key extraction with awk frequency counting.
Component Metadata
yq '{name: .name, title: .title, version: .version, start_page: .start_page}' docs/antora.yml
# Output:
# name: captures
# title: Work Chronicles
# version: null
# start_page: ROOT:index.adoc
yq '.nav[]' docs/antora.yml
# Output: modules/ROOT/nav.adoc
Cross-Repo Attribute Comparison
When multiple Antora components define the same attribute, drift happens. Use yq to compare attributes across repos.
echo "captures: $(yq -r '.asciidoc.attributes.domain' docs/antora.yml)"
echo "netapi: $(yq -r '.asciidoc.attributes.domain' ~/atelier/_bibliotheca/domus-netapi-docs/docs/asciidoc/antora.yml 2>/dev/null || echo 'N/A')"
# Shows whether domain is consistent across components
diff <(yq -r '.asciidoc.attributes | keys | .[]' docs/antora.yml | sort) \
<(yq -r '.asciidoc.attributes | keys | .[]' ~/atelier/_bibliotheca/domus-netapi-docs/docs/asciidoc/antora.yml 2>/dev/null | sort) \
2>/dev/null | head -30
# Shows attributes present in one but not the other
Process substitution with diff — no temp files needed.
comm -23 <(yq -r '.asciidoc.attributes | keys | .[]' docs/antora.yml | sort) \
<(yq -r '.asciidoc.attributes | keys | .[]' ~/atelier/_bibliotheca/domus-netapi-docs/docs/asciidoc/antora.yml 2>/dev/null | sort) \
2>/dev/null | head -20
# Output: attributes defined here but not in netapi-docs
Playbook Queries
The Antora playbook (antora-playbook.yml) defines which repos Antora aggregates.
yq '.content.sources[].url' ~/atelier/_bibliotheca/domus-docs/antora-playbook.yml 2>/dev/null
# Output: URLs of all content source repos
yq -r '.content.sources[] | "\(.url) [\(.branches // ["HEAD"] | join(", "))]"' ~/atelier/_bibliotheca/domus-docs/antora-playbook.yml 2>/dev/null
# Output: each repo with its configured branch
yq '.content.sources[] | select(.url | test("domus-captures"))' ~/atelier/_bibliotheca/domus-docs/antora-playbook.yml 2>/dev/null
# Output: the content source entry for this component
yq '.content.sources[] | [.url, .start_path] | join(" → ")' ~/atelier/_bibliotheca/domus-docs/antora-playbook-ci.yml
# Output:
# ". → docs"
# "./components/domus-infra-ops → docs/asciidoc"
# "./components/domus-ise-linux → docs"
# "./components/domus-captures → docs"
# ...
Quick visual check for which spokes have been migrated from docs/asciidoc to docs.
yq '.content.sources[] | select(.url | test("ise-linux")) | .start_path' ~/atelier/_bibliotheca/domus-docs/antora-playbook-ci.yml
# Output: docs
select(.url == "glob") does not work — == is literal comparison. Use test() for regex matching.
Antora UI Configuration
yq '.ui' ~/atelier/_bibliotheca/domus-docs/antora-playbook.yml 2>/dev/null
# Output: UI bundle URL, snapshot flag, supplemental files
yq '.antora.extensions[]' ~/atelier/_bibliotheca/domus-docs/antora-playbook.yml 2>/dev/null
# Output: registered Antora extensions
Attribute Validation
yq -r '.asciidoc.attributes | to_entries[] | select(.value == "") | .key' docs/antora.yml
# Output:
# noindex
# icons
# experimental
# sectanchors
# sectlinks
# hide-uri-scheme
Empty string attributes in Antora are boolean flags — they are "set" by having any value, even empty. This is intentional, not a bug.
yq -r '.asciidoc.attributes | to_entries[] | select(.value == null) | .key' docs/antora.yml
# Output: (any keys with null values — these may be errors)
yq '.asciidoc.attributes["attribute-missing"]' docs/antora.yml
# Output: warn@
The warn@ value tells Antora to emit a build warning when a page references an undefined {attribute-name}.
This is the safety net against typos.