Skip to main content

Formatter for WDL files

Project description

wdlfmt — a formatter for Workflow Description Language (WDL)

PyPI version CI Python versions Downloads License: MIT

wdlfmt is an opinionated, lossless formatter for WDL v1.0 that enforces consistency and targets the BioWDL Style Guidelines.

For now there is no automated way of styling or checking the style of WDL files according to these guidelines. — BioWDL Style Guidelines

wdlfmt aims to solve this problem.

Installation

pip install wdlfmt

Note: pip >= 23.0 is required. If you see the package install as UNKNOWN, upgrade pip first: pip install --upgrade pip

For development, clone the repo and use pixi:

git clone https://github.com/Chris1221/wdlfmt.git
cd wdlfmt && pixi install
pixi run test

Usage

By default, formatted output is written to stdout and a style compliance checklist is printed to stderr:

wdlfmt my_task.wdl

Format in place with -i:

wdlfmt -i my_task.wdl

Suppress the checklist with --no-check:

wdlfmt --no-check my_task.wdl

Redirect formatted WDL to a file while keeping the checklist visible:

wdlfmt my_task.wdl > formatted.wdl

What the formatter does

wdlfmt rewrites WDL files with consistent style, preserving all comments:

Rule Example (before → after)
4-space indentation tabs / mixed spaces → 4 spaces
Heredoc command syntax command { ... }command <<< ... >>>
Double-quoted strings 'hello'"hello"
Spaces around = key=valuekey = value

BioWDL style compliance checklist

After every format run, wdlfmt emits a per-rule checklist to stderr. Rules the formatter enforces are shown as confirmed guarantees; content rules that depend on the file's naming and structure are checked and reported:

BioWDL Style Guide Compliance
──────────────────────────────────────────────────────
  Formatter guarantees
    ✓  4-space indentation
    ✓  Heredoc (<<<) command syntax
    ✓  Double-quote string literals
    ✓  Spaces around = operator
  Content checks
    ✓  Task names are UpperCamelCase
    ✓  Workflow names are UpperCamelCase
    ✓  Struct names are UpperCamelCase
    ✗  Call aliases are lowerCamelCase
         Non-conforming aliases: myAlias
    ✓  Line length ≤ 100 chars
    !  set -e -o pipefail in multi-command blocks
         Missing in: block 1
    !  parameter_meta section present
         Missing in: task 'MyTask'
    ✓  docker defined in runtime blocks
──────────────────────────────────────────────────────
  1 failed  ·  2 warning(s)  ·  9 passed

Symbols: pass · fail (rule violated) · ! warn (advisory)

Content rules

Rule Level Description
Task names are UpperCamelCase fail task myTask → rename to MyTask
Workflow names are UpperCamelCase fail Same convention for workflows
Struct names are UpperCamelCase fail Same convention for structs
Call aliases are lowerCamelCase fail/warn call Foo as Bar fails; call Foo (no alias) warns
Line length ≤ 100 chars fail Reports offending line numbers
set -e -o pipefail in command blocks warn Advisory for multi-command blocks
parameter_meta section present warn Advisory per task/workflow
docker in runtime blocks warn Advisory per runtime block

Python API

import wdlfmt

# Format a WDL string
formatted = wdlfmt.format_wdl_str(wdl_text)

# Run the style checker on already-formatted text
results = wdlfmt.check_style(formatted)
for r in results:
    print(r.rule, r.status.value, r.details)

Technical overview

wdlfmt is built on ANTLR4 and a visitor-pattern formatter registry.

Parsing. The WDL v1.0 grammar (wdlfmt/grammar/WdlV1Lexer.g4 and WdlV1Parser.g4) is compiled to Python by ANTLR4. Parsing produces a typed parse tree where every node is a strongly-typed context object (e.g. TaskContext, Task_commandContext).

Comment preservation. WDL comments (#) are placed on a separate ANTLR token channel (channel 2) and are invisible to the default parse tree walk. wdlfmt extracts them from the token stream before visiting the tree, injects them as lightweight CommentContext nodes at the correct positions, and then emits them as part of the formatted output. This makes formatting lossless.

Formatter registry. wdlfmt/formatters/ contains a subclass of Formatter for each WDL context type (TaskFormatter, WorkflowFormatter, StructFormatter, etc.). Each subclass declares which context type it handles via a formats class attribute. The registry is built at import time by inspecting all Formatter subclasses, so adding support for a new context type requires only a new subclass — no wiring code.

Command block formatting. WDL command <<< blocks contain shell script. wdlfmt extracts the shell body, replaces WDL interpolation expressions (~{...}) with safe placeholders, passes the result through shfmt (bundled via shfmt-py), then restores the original expressions. This ensures shell code inside WDL tasks is also consistently formatted.

Style checker. The StyleChecker in wdlfmt/checker.py operates on the already-formatted text using regex — no re-parsing. This keeps it fast and decoupled from the formatter internals.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wdlfmt-0.1.1.tar.gz (61.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wdlfmt-0.1.1-py3-none-any.whl (60.0 kB view details)

Uploaded Python 3

File details

Details for the file wdlfmt-0.1.1.tar.gz.

File metadata

  • Download URL: wdlfmt-0.1.1.tar.gz
  • Upload date:
  • Size: 61.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wdlfmt-0.1.1.tar.gz
Algorithm Hash digest
SHA256 0a2ea38586dfb87876e06985ee69905ff1ab050391dafe7f50c848d7d13a6538
MD5 364c663b817c470128d668f3d6c1f980
BLAKE2b-256 a880fb24c08f673a23f10cd803167241f4337b67569ca6740ea7b9835290c8cc

See more details on using hashes here.

File details

Details for the file wdlfmt-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: wdlfmt-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 60.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wdlfmt-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0b09fbab7e05a8b871b80324ad5abd6dc41c38b8ab6afa1a68b5b7c7c27c3a39
MD5 59400ada4e36fb23ebac0ecbb541e28d
BLAKE2b-256 bcc1bb8e8ffe2de339b20f1e047b5579e991a46ff15ecbcefe84787afad06b65

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page