Branchline CLI¶
The Branchline CLI wraps the interpreter, compiler, and VM APIs. Both JVM and Node bundles expose the same commands:
run(default) — compile and execute a.blscript directly.compile— produce a bytecode artifact (.blc) that embeds the source and selected transform.exec— evaluate a compiled artifact through the VM without recompiling the source.
Calling a CLI with no arguments now prints a full help screen (-h/--help also work). All commands accept structured inputs via --input <path> and support XML payloads with --input-format xml.
Command modes and when to use them¶
- run: quickest way to try a Branchline script; compiles + executes in one step. Use in dev loops or CI smoke tests.
- compile: produces a portable
.blcartifact with bytecode + embedded source/transform. Use when you want to freeze a script at build time or ship it separately. - exec: runs a
.blcthrough the VM. Use when the source is already compiled, or when you want to lock a transform/version while letting inputs vary.--transformoverrides the embedded transform at execution time.
Transform selection: all modes default to the first TRANSFORM block. Pass --transform <name> to pick another.
Input handling: --input <path> reads JSON/XML; --input - reads stdin so you can pipe data into the CLI. --input-format xml parses XML into objects (attributes as @attr, text as #text).
Copy/paste quickstart¶
Create hello.bl:
Create input.json:
- Run directly (JVM):
./gradlew :cli:runBl --args "hello.bl --input input.json" - Compile:
./gradlew :cli:runBlc --args "hello.bl --output build/hello.blc" - Execute compiled artifact:
./gradlew :cli:runBlvm --args "build/hello.blc --input input.json" - Pipe stdin:
cat input.json | ./gradlew :cli:runBl --args "hello.bl --input -" --quiet
JVM binaries¶
Run the Gradle helpers to launch the JVM entry points (each helper sets the default command automatically):
./gradlew :cli:runBl --args "path/to/program.bl --input sample.json"./gradlew :cli:runBlc --args "path/to/program.bl --output build/program.blc"./gradlew :cli:runBlvm --args "build/program.blc --input sample.json"
Gradle compiles the CLI on demand and wires the correct classpath for each command. Passing --stacktrace or --info helps diagnose failing scripts during development.
Node bundle¶
To work with the Node build directly, package the compiled JavaScript output and run it with Node:
- Build the bundle (installs dependencies automatically):
./gradlew :cli:prepareJsCliPackage - Execute scripts:
node cli/build/cliJsPackage/bin/bl.cjs path/to/program.bl --input sample.json
The bl.cjs launcher delegates to the compiled Kotlin/JS runtime and respects the same arguments as the JVM version. Use BRANCHLINE_CLI_BIN to point automation at a custom bundle if the default location differs.
Distribution archive¶
./gradlew :cli:packageJsCli produces a gzipped tarball under cli/build/distributions/. The archive includes the CLI entry point, compiled Kotlin/JS artifacts, the package.json manifest, and the node_modules/ tree so consumers do not need to install dependencies separately. ./gradlew :cli:blShadowJar creates a standalone JVM jar (branchline-cli-<tag>-all.jar) runnable with java -jar.
Release artifacts for apps and automation¶
- CLI:
branchline-cli-js-<tag>.tgz(Node) andbranchline-cli-<tag>-all.jar(JVM). - Libraries:
- JVM:
branchline-interpreter-<tag>-jvm.jar,branchline-vm-<tag>-jvm.jar. - JS/Node:
branchline-interpreter-<tag>-js.tgz,branchline-vm-<tag>-js.tgz(installable vianpm install ./branchline-interpreter-<tag>-js.tgz). - GitHub Releases publish all of the above via the
release-artifactsworkflow. Build locally with:
./gradlew :cli:packageJsCli :cli:blShadowJar \
:interpreter:jvmJar :vm:jvmJar \
:interpreter:jsNodeProductionLibraryDistribution :vm:jsNodeProductionLibraryDistribution
Embedding the libraries¶
- Kotlin/JVM apps: add the JARs to your classpath, then use the
v2interpreter/VM APIs directly. - Node/JS apps: unpack the
*-js.tgztarball and import fromkotlin/branchline-interpreter.jsorkotlin/branchline-vm.js, or pointnpm installat the tarball path to pull it intonode_modules/.
JVM fat jar¶
- Build a standalone jar you can run with
java -jar(no Gradle on the consumer side): - The jar sets
io.branchline.cli.BlJvmMainas the entry point. Use--input-format xmlfor XML.
Using the CLI without Gradle on consumers¶
- Download or produce the tarball once (from CI artifacts or a release), unpack it, and run the launcher directly:
- Check the unpacked bundle into a Docker image or internal artifact store so downstream users do not need the Gradle build.
- You can host both the JS tarball and the JVM fat jar on GitHub Releases; consumers download the asset they need and run it directly.
CI smoke test¶
The CLI JVM test suite now runs a Node-based smoke test to ensure the packaged bundle executes JSON inputs successfully. This guards against regressions in the packaging flow and verifies the Node wrapper stays in sync with the shared CLI surface.