#!/bin/bash
set -e # Exit immediately if a command exits with a non-zero status.
# Debug mode - set to true for verbose output
DEBUG=${DEBUG:-false}
# Debug logging function
debug_log() {
if [[ "$DEBUG" == "true" ]]; then
echo "$@" >&2 # Log debug messages to stderr
fi
}
# Get the name of the symlink when called through a symlink
LINK_NAME=$(basename "$0")
# Validate LINK_NAME format and extract command parts
if [[ "$LINK_NAME" == "gbox" ]]; then
# Handle direct gbox execution
if [[ "$1" == "--version" ]]; then
CMD_TYPE="version"
SUB_CMD=""
else
CMD_TYPE="$1"
SUB_CMD="$2"
shift
fi
debug_log "Direct gbox execution - CMD_TYPE: ${CMD_TYPE:-none}, SUB_CMD: ${SUB_CMD:-none}"
elif [[ "$LINK_NAME" =~ ^gbox-([^-]+)(-(.+))?$ ]]; then
CMD_TYPE="${BASH_REMATCH[1]}"
SUB_CMD="${BASH_REMATCH[3]}"
debug_log "Symlink execution - CMD_TYPE: $CMD_TYPE, SUB_CMD: ${SUB_CMD:-none}"
else
echo "Error: Invalid command format: $LINK_NAME" >&2
echo "This script should be called as 'gbox <command>' or through a symlink named 'gbox-<command>[-<subcommand>]'" >&2
exit 1
fi
# find_repo_root function with caching
find_repo_root() {
local cache_file="/tmp/gbox_repo_root"
# If cache file exists and is less than 1 hour old, use the cached value
if [[ -f "$cache_file" ]] && [[ $(find "$cache_file" -mmin -60 2>/dev/null) ]]; then
cat "$cache_file"
return 0
fi
# Method 1: Determine from actual script location
local script_path="${BASH_SOURCE[0]}"
# Follow symlinks to find the actual script path
while [[ -h "$script_path" ]]; do
local script_dir
script_dir="$( cd -P "$( dirname "$script_path" )" >/dev/null 2>&1 && pwd )"
script_path="$(readlink "$script_path")"
[[ "$script_path" != /* ]] && script_path="$script_dir/$script_path"
done
local SCRIPT_DIR
SCRIPT_DIR="$( cd -P "$( dirname "$script_path" )" >/dev/null 2>&1 && pwd )"
debug_log "Actual script directory: $SCRIPT_DIR"
local repo_root=""
if [[ "$SCRIPT_DIR" == */packages/cli/bin ]]; then
# Assumes structure: REPO_ROOT/packages/cli/bin
repo_root="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")"
else
# Method 2: Search upwards for .git directory from script location
local DIR="$SCRIPT_DIR"
while [[ "$DIR" != "/" && "$DIR" != "." ]]; do
if [[ -d "$DIR/.git" ]]; then
repo_root="$DIR"
break
fi
DIR="$(dirname "$DIR")"
done
# Method 3: Search upwards from current working directory as a fallback
if [[ -z "$repo_root" ]]; then
DIR="$(pwd)"
while [[ "$DIR" != "/" && "$DIR" != "." ]]; do
if [[ -d "$DIR/.git" ]]; then
repo_root="$DIR"
break
fi
DIR="$(dirname "$DIR")"
done
fi
fi
if [[ -z "$repo_root" ]]; then
echo "Error: Unable to determine repository root directory." >&2
exit 1
fi
# Cache the result to a temporary file
echo "$repo_root" > "$cache_file"
echo "$repo_root"
}
REPO_ROOT=$(find_repo_root)
debug_log "REPO_ROOT: $REPO_ROOT"
CLI_DIR="$REPO_ROOT/packages/cli"
MAIN_GO="$CLI_DIR/main.go"
# Ensure CLI directory and main.go exist
if [[ ! -d "$CLI_DIR" ]]; then
echo "Error: CLI directory not found at $CLI_DIR" >&2
exit 1
fi
if [[ ! -f "$MAIN_GO" ]]; then
echo "Error: main.go not found at $MAIN_GO" >&2
exit 1
fi
# Change to CLI directory for go run context
cd "$CLI_DIR"
debug_log "Running go implementation for $CMD_TYPE ${SUB_CMD:+$SUB_CMD }from $CLI_DIR"
# Build and execute go run command
# Using exec replaces the shell process with the go run process
if [[ -n "$SUB_CMD" ]]; then
exec go run "$MAIN_GO" "$CMD_TYPE" "$SUB_CMD" "$@"
else
exec go run "$MAIN_GO" "$CMD_TYPE" "$@"
fi