Formatter for WDL files
Project description
wdlfmt — a formatter for Workflow Description Language (WDL)
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
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=value → key = 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wdlfmt-0.1.3.tar.gz.
File metadata
- Download URL: wdlfmt-0.1.3.tar.gz
- Upload date:
- Size: 61.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2456bf68fdebeb32c0be9e904b45de41c7da18ed57df5cc53adc5884b3c071b3
|
|
| MD5 |
1c99480a99e395cc77967c577918571b
|
|
| BLAKE2b-256 |
6fc383ae8bda08cfa9e45da3e27a9b086e1d1b940c28162e69c60ec487c6b2b1
|
File details
Details for the file wdlfmt-0.1.3-py3-none-any.whl.
File metadata
- Download URL: wdlfmt-0.1.3-py3-none-any.whl
- Upload date:
- Size: 60.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bfc2c80472ac5071c6950b191cd22d55544271573aaaa011dd4579bcc9798fe1
|
|
| MD5 |
da69b301f5bfc07fb4b32df9d29ccf37
|
|
| BLAKE2b-256 |
75d04ee450c77db926472ea8221527aae7f3bb946147a62cda38c8a8cbfb9aa9
|