Skip to content

Adding a New Command

Griffen Fargo edited this page Apr 10, 2026 · 1 revision

Adding a New Command

Step-by-step guide for extending the strut CLI with a new command.

Steps

1. Create the Command Handler

Create lib/cmd_<name>.sh:

#!/usr/bin/env bash
# ==================================================
# cmd_<name>.sh — <Description>
# ==================================================
# Dependencies: lib/utils.sh, lib/config.sh
# Provides: cmd_<name>

set -euo pipefail

cmd_<name>() {
  local stack="$1"
  local env_file="$2"
  shift 2

  # Parse command-specific args
  # ...

  log "Running <name> for stack: $stack"

  # Implementation
  # Use run_cmd for destructive operations (supports --dry-run)
  # Use validate_env_file before accessing env vars
  # Use build_ssh_opts for SSH commands
  # Use resolve_compose_cmd for Docker Compose commands
}

2. Source It in the Entrypoint

Add to the strut file, in the source block:

source "$LIB/cmd_<name>.sh"

3. Add to the Dispatch Block

Add to the case "$COMMAND" block in strut:

<name>) cmd_<name> "$STACK" "$ENV_FILE" "${CMD_ARGS[@]}" ;;

4. Add to Usage

Add to the usage() function in strut:

echo "  <name>   [--env <name>] [options]    Description of command"

5. Write Tests

Create tests/test_<name>.bats:

#!/usr/bin/env bats

setup() {
  TEST_TMP="$(mktemp -d)"
  # Override fail so it doesn't exit the test runner
  fail() { echo "$1" >&2; return 1; }
}

teardown() {
  rm -rf "$TEST_TMP"
}

@test "<name>: basic functionality" {
  # Test implementation
  run some_function
  [ "$status" -eq 0 ]
}

Checklist

  • lib/cmd_<name>.sh created with header comment and set -euo pipefail
  • Sourced in strut entrypoint
  • Added to dispatch case block
  • Added to usage() output
  • Tests in tests/test_<name>.bats
  • shellcheck passes
  • bats tests/ passes
  • No hardcoded org names, service names, or paths

Clone this wiki locally