Convert PRO#

The convert command converts between .yaml and .edg config formats. The output format is inferred from the input file extension (.yaml/.yml -> .edg, .edg -> .yaml) unless --output specifies a file with a different extension.

edg convert <file> [--output <path>]

Flags#

FlagShortDefaultDescription
--output-ostdoutOutput file or directory path. When omitted, the result is printed to stdout. When a directory is given, the converted file is written there with the appropriate extension.

Format detection#

Input extensionDefault output
.yaml or .yml.edg
.edg.yaml

When --output is provided, the output extension overrides the default. For example, edg convert config.yaml -o config.edg and edg convert config.yaml both produce edg-lang output, but edg convert config.edg -o backup.edg would re-parse and re-emit edg-lang.

Examples#

Given this YAML config:

globals:
  count: 100

up:
  - name: create_users
    type: exec
    query: |
      CREATE TABLE IF NOT EXISTS users (
        id INT PRIMARY KEY,
        name TEXT NOT NULL,
        email TEXT NOT NULL
      )

seed:
  - name: populate_users
    type: exec_batch
    count: 100
    args:
      id: seq(1, 1)
      name: gen('name')
      email: gen('email')
    query: INSERT INTO users (id, name, email) VALUES ($1, $2, $3)

run:
  - name: read_users
    type: query
    query: SELECT * FROM users WHERE id = $1
    args: [uniform(1, 100)]

down:
  - name: drop_users
    type: exec
    query: DROP TABLE IF EXISTS users

YAML to edg-lang#

# Output directly to stdout.
edg convert workload.yaml

# Redirect output to a file.
edg convert workload.yaml --output workload.edg

Produces:

let count = 100

up {
  create_users(type: exec) `CREATE TABLE IF NOT EXISTS users (
    id INT PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT NOT NULL
  )`
}

seed {
  populate_users(count: 100) `INSERT INTO users (id, name, email) VALUES ($1, $2, $3)` (
    id: seq(1, 1),
    name: gen('name'),
    email: gen('email')
  )
}

run {
  read_users(type: query) `SELECT * FROM users WHERE id = $1` (uniform(1, 100))
}

down {
  drop_users(type: exec) `DROP TABLE IF EXISTS users`
}

edg-lang to YAML#

# Output directly to stdout.
edg convert workload.edg

# Redirect output to a file.
edg convert workload.edg --output workload.yaml

Produces the equivalent YAML shown above.

Directory output#

When --output is a directory (no file extension or ends with /), the converted file is written there with the appropriate extension:

# Write config.edg into the output/ directory.
edg convert config.yaml -o output/

YAML !include handling#

When converting YAML to edg-lang, any !include directives are automatically handled. Each included YAML file is converted to a separate .edg file, and the main output uses include directives to reference them:

# config.yaml uses !include for shared files.
edg convert config.yaml -o config.edg

If config.yaml contains:

globals: !include shared/globals.yaml
up: !include shared/schema.yaml

seed:
  - name: populate_users
    count: count
    size: batch_size
    args: [gen('email')]
    query: INSERT INTO users (email) VALUES ($1)

The convert command produces:

  • config.edg - main file with include 'shared/globals.edg' and include 'shared/schema.edg'
  • shared/globals.edg - converted globals
  • shared/schema.edg - converted schema queries

Round-trip fidelity#

Converting YAML -> edg-lang -> YAML produces a semantically equivalent config. The intermediate representations may differ in formatting (e.g. comment placement, key ordering), but edg validate config will produce the same result for both.

Next steps#

  • Run edg validate config --config <file> to verify the converted output