Files
sf-cli-wrapper/utils/utils.sh
reynold 4020d881f1 fix: resolve sf-logs-tail utils.sh dependency by reorganizing directory structure
- Renamed misc/ directory to utils/ for better organization
- Updated sf-logs-tail to source utils/utils.sh correctly
- This fixes the 'No such file or directory' error when running sf-logs-tail
- The utils directory contains cross-platform timeout functions needed for macOS compatibility
2025-08-28 22:57:07 +08:00

108 lines
2.9 KiB
Bash
Executable File

#!/bin/bash
# Shared utilities for SF CLI wrapper scripts
# Provides cross-platform compatibility helpers
# Portable timeout function for macOS and Linux compatibility
# Usage: portable_timeout MINUTES command [args...]
# Returns exit code 124 on timeout (matching GNU timeout behavior)
portable_timeout() {
local duration_minutes="$1"
shift
# Try GNU timeout first (available on Linux by default)
if command -v timeout >/dev/null 2>&1; then
timeout "${duration_minutes}m" "$@"
return $?
fi
# Try gtimeout (macOS with GNU coreutils installed)
if command -v gtimeout >/dev/null 2>&1; then
gtimeout "${duration_minutes}m" "$@"
return $?
fi
# Fallback implementation for macOS without GNU coreutils
# Start the command in background
"$@" &
local cmd_pid=$!
# Start timeout watcher in background
(
sleep "${duration_minutes}m"
kill "$cmd_pid" 2>/dev/null
) &
local watcher_pid=$!
# Wait for the command to finish
wait "$cmd_pid" 2>/dev/null
local cmd_exit_code=$?
# Clean up watcher if command finished normally
kill "$watcher_pid" 2>/dev/null
wait "$watcher_pid" 2>/dev/null
# Check if command was killed (timeout occurred)
if ! kill -0 "$cmd_pid" 2>/dev/null; then
# Command no longer exists, check if it was our timeout
if [[ $cmd_exit_code -ne 0 ]]; then
# Command may have been killed by timeout, return 124
return 124
fi
fi
return $cmd_exit_code
}
# Portable timeout function for seconds (for tests that need shorter timeouts)
# Usage: portable_timeout_seconds SECONDS command [args...]
portable_timeout_seconds() {
local duration_seconds="$1"
shift
# Try GNU timeout first
if command -v timeout >/dev/null 2>&1; then
timeout "${duration_seconds}s" "$@"
return $?
fi
# Try gtimeout
if command -v gtimeout >/dev/null 2>&1; then
gtimeout "${duration_seconds}s" "$@"
return $?
fi
# Fallback implementation
"$@" &
local cmd_pid=$!
# Start timeout watcher in background
(
sleep "$duration_seconds"
kill "$cmd_pid" 2>/dev/null
) &
local watcher_pid=$!
# Wait for the command to finish
wait "$cmd_pid" 2>/dev/null
local cmd_exit_code=$?
# Clean up watcher if command finished normally
kill "$watcher_pid" 2>/dev/null
wait "$watcher_pid" 2>/dev/null
# Check if command was killed (timeout occurred)
if ! kill -0 "$cmd_pid" 2>/dev/null; then
if [[ $cmd_exit_code -ne 0 ]]; then
return 124
fi
fi
return $cmd_exit_code
}
# Function to get the directory of the calling script
# Usage: SCRIPT_DIR=$(get_script_dir)
get_script_dir() {
cd "$(dirname "${BASH_SOURCE[1]}")" && pwd
}