Skip to main content
Version: 0.16.0

Implementations

Every command needs at least one implementation - the actual code that runs when you invoke the command. Implementations define what runs, where it runs (platform), and how it runs (runtime).

Basic Structure​

An implementation has three main parts:

{
name: "build"
implementations: [
{
// 1. The script to run
script: {content: "go build ./..."}

// 2. Target constraints (runtime + platform)
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}
]
}

Scripts​

The script field contains the commands to execute. Use script.content for inline commands. Inside invowk modules, script.file can reference a script file contained in that same module.

Inline Scripts​

Single-line scripts are simple:

script: {content: "echo 'Hello, World!'"}

Multi-line scripts use triple quotes:

script: {content: """
#!/bin/bash
set -e
echo "Building..."
go build -o bin/app ./...
echo "Done!"
"""}

External Script Files​

Inside an invowk module, reference a module-contained script file instead of inline code:

// Root/project invowkfile: invoke a project-local script from inline content
script: {content: "./scripts/build.sh"}

// Module invowkfile: reference a file contained in the invowkmod
script: {file: "scripts/deploy.sh"}

script.file is explicit, not extension-detected: extensionless files are valid, and root/project invowkfiles should call local scripts through script.content.

When to Use External Scripts​

  • Inline: Quick, simple commands; keeps everything in one file
  • External: Complex module-bundled scripts; reusable across module commands; easier to edit with syntax highlighting

Runtime and Platform Constraints​

Each implementation specifies where and how it runs using the runtimes and platforms fields.

Runtimes​

Every implementation must specify at least one runtime:

runtimes: [
{name: "native"}, // System shell
{name: "virtual-sh"}, // Built-in POSIX shell
{name: "container", image: "debian:stable-slim"} // Container
]
platforms: [{name: "linux"}, {name: "macos"}]

The first runtime is the default. Users can override with --ivk-runtime:

# Uses default runtime (first in list)
invowk cmd myproject build

# Override to use container runtime
invowk cmd myproject build --ivk-runtime container

See Runtime Modes for details on each runtime.

Platforms​

Specify which operating systems the implementation supports. Every implementation must declare at least one platform:

runtimes: [{name: "native"}]
platforms: [
{name: "linux"},
{name: "macos"},
{name: "windows"}
]

Available platforms: linux, macos, windows

Multiple Implementations​

Commands can have multiple implementations for different scenarios:

Platform-Specific Implementations​

{
name: "clean"
implementations: [
// Unix implementation
{
script: {content: "rm -rf build/"}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
},
// Windows implementation
{
script: {content: "rmdir /s /q build"}
runtimes: [{name: "native"}]
platforms: [{name: "windows"}]
}
]
}

Invowk™ automatically selects the right implementation for the current platform.

Runtime-Specific Implementations​

{
name: "build"
implementations: [
// Fast native build
{
script: {content: "go build ./..."}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
},
// Reproducible container build
{
script: {content: "echo building in container"}
runtimes: [{name: "container", image: "debian:stable-slim"}]
platforms: [{name: "linux"}]
}
]
}

Combined Platform + Runtime​

{
name: "build"
implementations: [
// Linux/macOS with multiple runtime options
{
script: {content: "make build"}
runtimes: [
{name: "native"},
{name: "container", image: "debian:stable-slim"}
]
platforms: [{name: "linux"}, {name: "macos"}]
},
// Windows native only
{
script: {content: "msbuild /p:Configuration=Release"}
runtimes: [{name: "native"}]
platforms: [{name: "windows"}]
}
]
}

Platform-Specific Environment​

For platform-specific environment variables, use separate implementations per platform, each with its own env:

{
name: "deploy"
implementations: [
// Linux implementation with platform-specific env
{
script: {content: "echo \"Deploying to $PLATFORM with config at $CONFIG_PATH\""}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}]
env: {
vars: {
PLATFORM: "Linux"
CONFIG_PATH: "/etc/app/config.yaml"
}
}
},
// macOS implementation with platform-specific env
{
script: {content: "echo \"Deploying to $PLATFORM with config at $CONFIG_PATH\""}
runtimes: [{name: "native"}]
platforms: [{name: "macos"}]
env: {
vars: {
PLATFORM: "macOS"
CONFIG_PATH: "/usr/local/etc/app/config.yaml"
}
}
}
]
}

Implementation-Level Settings​

Implementations can have their own environment, working directory, and dependencies:

{
name: "build"
implementations: [
{
script: {content: "npm run build"}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]

// Implementation-specific env
env: {
vars: {
NODE_ENV: "production"
}
}

// Implementation-specific workdir
workdir: "./frontend"

// Implementation-specific dependencies
depends_on: {
tools: [{alternatives: ["node", "npm"]}]
filepaths: [{alternatives: ["package.json"]}]
}
}
]
}

These override command-level settings when this implementation is selected.

Implementation Selection​

When you run a command, Invowk selects an implementation based on:

  1. Current platform - Filters to implementations supporting your OS
  2. Requested runtime - If --ivk-runtime specified, uses that; otherwise uses the default
  3. First match wins - Uses the first implementation matching both criteria

Selection Examples​

Given this command:

{
name: "build"
implementations: [
{
script: {content: "make build"}
runtimes: [
{name: "native"},
{name: "virtual-sh", allowed_binaries: ["make"], binary_lookup_mode: "host"},
]
platforms: [{name: "linux"}, {name: "macos"}]
},
{
script: {content: "msbuild"}
runtimes: [{name: "native"}]
platforms: [{name: "windows"}]
}
]
}
PlatformCommandSelected
Linuxinvowk cmd myproject buildFirst impl, native runtime
Linuxinvowk cmd myproject build --ivk-runtime virtual-shFirst impl, virtual-sh runtime
Windowsinvowk cmd myproject buildSecond impl, native runtime
Windowsinvowk cmd myproject build --ivk-runtime virtual-shError: no matching impl

Command Listing​

The invowk cmd output shows available runtimes and platforms:

Available Commands
(* = default runtime)

From invowkfile:
build - Build the project [native*, virtual-sh] (linux, macos)
clean - Clean artifacts [native*] (linux, macos, windows)
docker-build - Container build [container*] (linux, macos, windows)
  • [native*, virtual-sh] - Supports native (default) and virtual-sh runtimes
  • (linux, macos) - Only available on Linux and macOS

Using CUE Templates​

Reduce repetition with CUE templates:

// Define reusable templates
_unixNative: {
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}

_allPlatforms: {
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}

cmds: [
{
name: "build"
implementations: [
_unixNative & {script: {content: "make build"}}
]
},
{
name: "test"
implementations: [
_unixNative & {script: {content: "make test"}}
]
},
{
name: "version"
implementations: [
_allPlatforms & {script: {content: "cat VERSION"}}
]
}
]

Best Practices​

  1. Start simple - One implementation is often enough
  2. Always specify platforms - Every implementation must declare at least one target platform
  3. Default runtime first - Put the most common runtime first in the list
  4. Use templates - Reduce repetition with CUE's templating
  5. Keep scripts focused - One task per command; chain with dependencies

Next Steps​

  • Runtime Modes - Deep dive into native, virtual-sh, virtual-lua, and container runtimes
  • Dependencies - Declare what your implementations need