#!/usr/bin/env bash
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
if [ "$FORCE_COLOR" != "1" ] && ([ -n "$MAKEFLAGS" ] || [ "$TERM" = "dumb" ] || [ ! -t 1 ]); then
RED=''
GREEN=''
YELLOW=''
BLUE=''
NC=''
fi
RUN_TESTSUITE=false
SKIP_TESTS=false
VERBOSE=false
USE_GLOBAL_ENV=false
print_step() {
printf "${BLUE}==>${NC} %s\n" "$1"
}
print_success() {
printf "${GREEN}✓${NC} %s\n" "$1"
}
print_warning() {
printf "${YELLOW}⚠${NC} %s\n" "$1"
}
print_error() {
printf "${RED}✗${NC} %s\n" "$1"
}
setup_venv() {
local venv_path="$1"
if [ -d "$venv_path" ]; then
if [ ! -f "$venv_path/bin/activate" ]; then
print_warning "Removing incomplete virtual environment (missing activate)..."
rm -rf "$venv_path"
else
if ! (source "$venv_path/bin/activate" && python -m pip --version > /dev/null 2>&1); then
print_warning "Removing broken virtual environment (pip not working)..."
rm -rf "$venv_path"
fi
fi
fi
if [ ! -d "$venv_path" ]; then
print_step "Creating Python virtual environment..."
if python3 -m venv "$venv_path" --upgrade-deps; then
print_success "Virtual environment created at $venv_path"
else
print_error "Failed to create virtual environment"
return 1
fi
else
print_step "Using existing virtual environment at $venv_path"
fi
if [ ! -f "$venv_path/bin/activate" ]; then
print_error "Virtual environment activate script not found at $venv_path/bin/activate"
return 1
fi
chmod +x "$venv_path/bin/activate"
source "$venv_path/bin/activate"
if [ -z "$VIRTUAL_ENV" ]; then
print_error "Failed to activate virtual environment"
return 1
fi
print_step "Upgrading pip in virtual environment..."
if python -m pip install --upgrade pip > /dev/null 2>&1; then
print_success "Pip upgraded successfully"
else
print_warning "Failed to upgrade pip - continuing anyway"
fi
return 0
}
cleanup_venv() {
if [ -n "$VIRTUAL_ENV" ]; then
deactivate 2>/dev/null || true
fi
}
trap cleanup_venv EXIT INT TERM
usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "A comprehensive script for formatting, testing, and building superfile"
echo ""
echo "OPTIONS:"
echo " -t, --testsuite Run integration testsuite after unit tests"
echo " -s, --skip-tests Skip unit tests (only format, lint, and build)"
echo " -v, --verbose Enable verbose output"
echo " --use-global-env Use global Python environment instead of virtual environment"
echo " -h, --help Show this help message"
echo ""
echo "STEPS PERFORMED:"
echo " 1. Tidy Go modules"
echo " 2. Format code with 'go fmt'"
echo " 3. Run golangci-lint"
echo " 4. Run unit tests (unless --skip-tests)"
echo " 5. Run integration testsuite (if --testsuite)"
echo " 6. Build spf binary"
}
while [[ $# -gt 0 ]]; do
case $1 in
-t|--testsuite)
RUN_TESTSUITE=true
shift
;;
-s|--skip-tests)
SKIP_TESTS=true
shift
;;
-v|--verbose)
VERBOSE=true
shift
;;
--use-global-env)
USE_GLOBAL_ENV=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1"
usage
exit 1
;;
esac
done
VERBOSE_FLAG=""
if [ "$VERBOSE" = true ]; then
VERBOSE_FLAG="-v"
fi
printf "${BLUE}🚀 Starting superfile development workflow${NC}\n"
echo ""
print_step "Tidying Go modules..."
if go mod tidy $VERBOSE_FLAG; then
print_success "Go modules tidied"
else
print_error "Failed to tidy Go modules"
exit 1
fi
print_step "Formatting Go code..."
if go fmt ./...; then
print_success "Code formatted"
else
print_error "Failed to format code"
exit 1
fi
print_step "Running golangci-lint..."
if golangci-lint run; then
print_success "Linting passed"
else
print_error "Linting failed"
exit 1
fi
if [ "$SKIP_TESTS" = false ]; then
print_step "Running unit tests..."
if [ "$VERBOSE" = true ]; then
if go test -v ./...; then
print_success "Unit tests passed"
else
print_error "Unit tests failed"
exit 1
fi
else
if go test ./...; then
print_success "Unit tests passed"
else
print_error "Unit tests failed"
exit 1
fi
fi
else
print_warning "Skipping unit tests"
fi
if [ "$RUN_TESTSUITE" = true ]; then
print_step "Running integration testsuite..."
if ! command -v python3 &> /dev/null; then
print_error "Python3 is required for testsuite but not found"
exit 1
fi
if [ ! -f "testsuite/requirements.txt" ]; then
print_error "testsuite/requirements.txt not found"
exit 1
fi
cd testsuite
if [ "$USE_GLOBAL_ENV" = true ]; then
print_step "Installing testsuite requirements globally..."
print_warning "Using global Python environment - consider removing --use-global-env flag to use virtual environment"
if python3 -m pip install -r requirements.txt > /dev/null 2>&1; then
print_success "Testsuite requirements installed globally"
else
print_warning "Failed to install testsuite requirements - continuing anyway"
fi
else
VENV_PATH="./venv"
if ! setup_venv "$VENV_PATH"; then
print_error "Failed to setup virtual environment"
cd ..
exit 1
fi
print_step "Installing testsuite requirements in virtual environment..."
if python -m pip install -r requirements.txt > /dev/null 2>&1; then
print_success "Testsuite requirements installed in virtual environment"
else
print_error "Failed to install testsuite requirements in virtual environment"
cd ..
exit 1
fi
fi
if [ "$VERBOSE" = true ]; then
if python3 main.py --debug; then
print_success "Integration testsuite passed"
else
print_error "Integration testsuite failed"
cd ..
exit 1
fi
else
if python3 main.py; then
print_success "Integration testsuite passed"
else
print_error "Integration testsuite failed"
cd ..
exit 1
fi
fi
cd ..
fi
print_step "Building spf binary..."
if [ "$(go env GOOS)" = "darwin" ]; then
BUILD_CMD=(env CGO_ENABLED=1 go build -o ./bin/spf)
else
BUILD_CMD=(env CGO_ENABLED=0 go build -o ./bin/spf)
fi
if "${BUILD_CMD[@]}"; then
print_success "Build completed successfully"
else
print_error "Build failed"
exit 1
fi
echo ""
printf "${GREEN}🎉 All steps completed successfully!${NC}\n"
printf "${BLUE}Binary location:${NC} ./bin/spf\n"
if [ -f "./bin/spf" ]; then
BINARY_SIZE=$(du -h ./bin/spf | cut -f1)
printf "${BLUE}Binary size:${NC} $BINARY_SIZE\n"
fi