Imports
Eucalypt supports importing content from other units in a variety of ways.
Imported names can be scoped to specific declarations, they may be made accessible under a specific namespace, and they may be imported from disk or direct from git repositories.
Import scopes
Imports are specified in declaration metadata and make the names in the imported unit available within the declaration that is annotated.
{ import: "config.eu" }
data: {
# names from config are available here
x: config-value
}
As described in syntax, declaration metadata can be applied at a unit level simply by including a metadata block as the very first thing in a eucalypt file:
{ import: "config.eu" }
# names from config are available here
x: config-value
Import syntax
Imports are specified using the key import in a declaration metadata
block. The value may be a single import specification:
{ import: "dep-a.eu"}
or a list of import specifications:
{ import: ["dep-a.eu", "dep-b.eu"]}
The import specification itself can be either a simple import or a git import.
Simple imports
Simple imports are specified in exactly the same way as inputs are specified at the command line (see command line).
So you can override the format of the imported file when the file extension is misleading:
{ import: "yaml@dep.txt" }
...and provide a name under which the imported names will be available:
{ import: "cfg=config.eu" }
# names in config.eu are available by lookup in cfg:
x: cfg.x
In cases, where the import format delivers a list rather than a block ("text", "csv", "jsonl", ...) a name is mandatory:
{ import: "txns=transactions.csv" }
Simple imports support exactly the same inputs as the command line, with the proviso that the stdin input ("-") will not be consumable if it has already been specified in the command line or another unit.
Git imports
Git imports allow you to import eucalypt direct from a git repository at a specified commit, combining the convenience of not having to explicitly manage a git working copy and a library path with the repeatability of a git SHA. A git import is specified as a block with the keys "git", "commit" and "import", all of which are mandatory:
{ import: { git: "https://github.com/gmorpheme/eu.aws"
commit: "0140232cf882a922bdd67b520ed56f0cddbd0637"
import: "aws/cloudformation.eu" } }
The git URL may be any format that the git command line expects.
commit is required and should be a SHA. It is intended to ensure the
import is repeatable and cacheable.
import identifies the file within the repository to import.
Just as with simple imports, several git imports may be listed:
{ import: [{ git: ... }, { git: ... }]}
...and simple imports and git imports may be freely mixed.
YAML import features
When importing YAML files, eucalypt supports several YAML features that help reduce repetition and express data more naturally.
Anchors and aliases
YAML anchors (&name) and aliases (*name) allow you to define a value
once and reference it multiple times. When eucalypt imports a YAML file
with anchors and aliases, the aliased values are resolved to copies of
the anchored expression.
# config.yaml
defaults: &defaults
timeout: 30
retries: 3
development:
<<: *defaults
debug: true
production:
<<: *defaults
debug: false
Anchors can be applied to any YAML value: scalars, lists, or mappings.
# Anchor on a scalar
name: &author "Alice"
books:
- title: "First Book"
author: *author
- title: "Second Book"
author: *author
# Anchor on a list
colours: &primary [red, green, blue]
palette:
primary: *primary
secondary: [yellow, cyan, magenta]
# Anchor on a mapping (block)
base: &base
x: 1
y: 2
ref: *base # ref now has { x: 1, y: 2 }
Nested anchors are supported—an anchored structure can itself contain anchored values:
outer: &outer
inner: &inner 42
ref_outer: *outer # { inner: 42 }
ref_inner: *inner # 42
If you reference an undefined alias, eucalypt reports an error:
# This will fail: *undefined is not defined
value: *undefined
Merge keys
The YAML merge key (<<) allows you to merge entries from one or more
mappings into another. This is useful for creating configuration
variations that share a common base.
Single merge:
base: &base
host: localhost
port: 8080
server:
<<: *base
name: main
# server = { host: localhost, port: 8080, name: main }
Multiple merge:
When merging multiple mappings, later ones override earlier ones:
defaults: &defaults
timeout: 30
retries: 3
overrides: &overrides
timeout: 60
config:
<<: [*defaults, *overrides]
name: myapp
# config = { timeout: 60, retries: 3, name: myapp }
Explicit keys override merged values:
Keys defined explicitly in the mapping (before or after the merge) always take precedence over merged values:
base: &base
x: 1
y: 2
derived:
<<: *base
y: 99
# derived = { x: 1, y: 99 }
Inline merge:
You can also merge an inline mapping directly:
config:
<<: { timeout: 30, retries: 3 }
name: myapp
The merge key value must be a mapping (or list of mappings). Attempting
to merge a non-mapping value (e.g., <<: 42) results in an error.
Timestamps
Eucalypt automatically converts YAML timestamps to ZDT (zoned date-time) expressions. Plain scalar values matching timestamp patterns are parsed and converted; quoted strings are left as strings.
Supported formats:
| Format | Example | Notes |
|---|---|---|
| Date only | 2023-01-15 |
Midnight UTC |
| ISO 8601 UTC | 2023-01-15T10:30:00Z |
|
| ISO 8601 offset | 2023-01-15T10:30:00+05:00 |
|
| Space separator | 2023-01-15 10:30:00 |
Treated as UTC |
| Fractional seconds | 2023-01-15T10:30:00.123456Z |
Examples:
# These are converted to ZDT expressions:
created: 2023-01-15
updated: 2023-01-15T10:30:00Z
scheduled: 2023-06-01 09:00:00
# This remains a string (quoted):
date_string: "2023-01-15T10:30:00Z"
Invalid timestamps fall back to strings:
If a value looks like a timestamp but has invalid date components (e.g., month 13 or day 45), it remains a string:
invalid: 2023-13-45 # Remains string "2023-13-45"
To keep timestamps as strings:
If you need to preserve a timestamp-like value as a string rather than converting it to a ZDT, quote it:
# As ZDT:
actual_date: 2023-01-15
# As string:
date_label: "2023-01-15"