Skip to main content
Version: 0.2.0

Creating Modules

Learn how to create, structure, and organize modules for your commands.

Quick Create

Use module create to scaffold a new module:

# Simple module
invowk module create mytools

# RDNS naming
invowk module create com.company.devtools

# In specific directory
invowk module create mytools --path /path/to/modules

# Custom module ID + description
invowk module create mytools --module-id com.company.tools --description "Shared tools"

# With scripts directory
invowk module create mytools --scripts

Generated Structure

Basic module:

mytools.invowkmod/
├── invowkmod.cue
└── invowkfile.cue

With --scripts:

mytools.invowkmod/
├── invowkmod.cue
├── invowkfile.cue
└── scripts/

Module Metadata (invowkmod.cue)

The generated invowkmod.cue contains module identity and dependencies:

module: "mytools"
version: "1.0.0"
description: "Commands for mytools"

// Uncomment to add dependencies:
// requires: [
// {
// git_url: "https://github.com/example/utils.invowkmod.git"
// version: "^1.0.0"
// },
// ]

Template Invowkfile

The generated invowkfile.cue contains commands only:

cmds: [
{
name: "hello"
description: "Say hello"
implementations: [
{
script: """
echo "Hello from mytools!"
"""
runtimes: [{name: "virtual"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}
]
}
]

Manual Creation

You can also create modules manually:

mkdir mytools.invowkmod
touch mytools.invowkmod/invowkmod.cue
touch mytools.invowkmod/invowkfile.cue

Adding Scripts

Inline vs External

Choose based on complexity:

cmds: [
// Simple: inline script
{
name: "quick"
implementations: [{
script: "echo 'Quick task'"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
},

// Complex: external script
{
name: "complex"
implementations: [{
script: "scripts/complex-task.sh"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}
]

Script Organization

mytools.invowkmod/
├── invowkmod.cue
├── invowkfile.cue
└── scripts/
├── build.sh # Main scripts
├── deploy.sh
├── test.sh
└── lib/ # Shared utilities
├── logging.sh
└── validation.sh

Script Paths

Always use forward slashes:

// Good
script: "scripts/build.sh"
script: "scripts/lib/logging.sh"

// Bad - will fail on some platforms
script: "scriptsuild.sh"

// Bad - escapes module directory
script: "../outside.sh"

Environment Files

Include .env files in your module:

mytools.invowkmod/
├── invowkmod.cue
├── invowkfile.cue
├── .env # Default config
├── .env.example # Template for users
└── scripts/

Reference them:

env: {
files: [".env"]
}

Documentation

Include a README for users:

mytools.invowkmod/
├── invowkmod.cue
├── invowkfile.cue
├── README.md # Usage instructions
├── CHANGELOG.md # Version history
└── scripts/

Real-World Examples

Build Tools Module

com.company.buildtools.invowkmod/
├── invowkmod.cue
├── invowkfile.cue
├── scripts/
│ ├── build-go.sh
│ ├── build-node.sh
│ └── build-python.sh
├── templates/
│ ├── Dockerfile.go
│ ├── Dockerfile.node
│ └── Dockerfile.python
└── README.md
cmds: [
{
name: "go"
description: "Build Go project"
implementations: [{
script: "scripts/build-go.sh"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
},
{
name: "node"
description: "Build Node.js project"
implementations: [{
script: "scripts/build-node.sh"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
},
{
name: "python"
description: "Build Python project"
implementations: [{
script: "scripts/build-python.sh"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}
]

DevOps Module

org.devops.k8s.invowkmod/
├── invowkmod.cue
├── invowkfile.cue
├── scripts/
│ ├── deploy.sh
│ ├── rollback.sh
│ └── status.sh
├── manifests/
│ ├── deployment.yaml
│ └── service.yaml
└── .env.example

Best Practices

  1. Use RDNS naming: Prevents conflicts with other modules
  2. Keep scripts focused: One task per script
  3. Include documentation: README with usage examples
  4. Version your module: Set the version in invowkmod.cue
  5. Forward slashes only: Cross-platform compatibility
  6. Validate before sharing: Run module validate --deep

Validating Your Module

Before sharing, validate:

invowk module validate mytools.invowkmod --deep

See Validating for details.

Next Steps