Something went wrong. Try again.
extentions for bash language
Something went wrong. Try again.
26 kB · 951 lines
Shell
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951#!/bin/bash
# Development Tools Module# Provides debugging, profiling, and code analysis utilities
module_version devtools 1.0.0
# Debugging utilitiesdeclare -a DEBUG_BREAKPOINTS=()declare -i DEBUG_ENABLED=0declare -i DEBUG_VERBOSE=0declare -i DEBUG_STEP_MODE=0declare -i DEBUG_CURRENT_LINE=0declare -g DEBUG_LEVEL=1declare -g DEBUG_FILE=""
# Enable debuggingenable_debug() { local verbose="${1:-0}" local level="${2:-1}" local file="${3:-debug.log}" DEBUG_ENABLED=1 DEBUG_VERBOSE=$verbose DEBUG_LEVEL=$level DEBUG_FILE=$file if [[ $DEBUG_VERBOSE -eq 1 ]]; then echo "Debug mode enabled (verbose: $verbose, level: $level, log: $file)" fi # Set up debug trap trap 'debug_trap $LINENO "$BASH_COMMAND"' DEBUG}
# Disable debuggingdisable_debug() { DEBUG_ENABLED=0 DEBUG_STEP_MODE=0 DEBUG_BREAKPOINTS=() # Remove debug trap trap - DEBUG if [[ $DEBUG_VERBOSE -eq 1 ]]; then echo "Debug mode disabled" fi}
# Debug loggingdebug_log() { local level="$1" local message="$2" local timestamp timestamp=$(date "+%Y-%m-%d %H:%M:%S") if [[ $DEBUG_ENABLED -eq 1 ]] && [[ $level -le $DEBUG_LEVEL ]]; then local log_entry="[$timestamp] [DEBUG:$level] $message" echo "$log_entry" | tee -a "$DEBUG_FILE" >&2 fi}
# Debug trap handlerdebug_trap() { local line_no="$1" local command="$2" DEBUG_CURRENT_LINE=$line_no # Check if we hit a breakpoint if [[ " ${DEBUG_BREAKPOINTS[@]} " =~ " $line_no " ]]; then echo "Breakpoint hit at line $line_no" echo "Command: $command" echo "Stack:" local frame=0 while caller $frame; do ((frame++)) done echo if [[ $DEBUG_STEP_MODE -eq 1 ]]; then debug_prompt fi fi if [[ $DEBUG_VERBOSE -eq 1 ]]; then echo "DEBUG: Line $line_no: $command" fi}
# Set breakpointset_breakpoint() { local line_no="$1" if [[ -n "$line_no" && "$line_no" =~ ^[0-9]+$ ]]; then DEBUG_BREAKPOINTS+=("$line_no") echo "Breakpoint set at line $line_no" else echo "Invalid line number: $line_no" fi}
# Remove breakpointremove_breakpoint() { local line_no="$1" local -a new_breakpoints=() for bp in "${DEBUG_BREAKPOINTS[@]}"; do if [[ "$bp" != "$line_no" ]]; then new_breakpoints+=("$bp") fi done DEBUG_BREAKPOINTS=("${new_breakpoints[@]}") echo "Breakpoint removed from line $line_no"}
# List breakpointslist_breakpoints() { if [[ ${#DEBUG_BREAKPOINTS[@]} -eq 0 ]]; then echo "No breakpoints set" else echo "Breakpoints:" for bp in "${DEBUG_BREAKPOINTS[@]}"; do echo " Line $bp" done fi}
# Debug promptdebug_prompt() { while true; do echo -n "debug> " read -r cmd case "$cmd" in "c"|"continue") break ;; "s"|"step") DEBUG_STEP_MODE=1 break ;; "n"|"next") DEBUG_STEP_MODE=0 break ;; "l"|"list") debug_list_variables ;; "b"|"backtrace") debug_backtrace ;; "h"|"help") debug_help ;; "q"|"quit") exit 0 ;; *) echo "Unknown command: $cmd" debug_help ;; esac done}
# List variables in debug contextdebug_list_variables() { echo "Variables:" # List environment variables env | head -20 echo "..."}
# Show backtracedebug_backtrace() { echo "Backtrace:" local frame=0 while caller $frame; do ((frame++)) done}
# Debug helpdebug_help() { echo "Debug commands:" echo " c, continue - Continue execution" echo " s, step - Step to next line" echo " n, next - Continue to next breakpoint" echo " l, list - List variables" echo " b, backtrace - Show backtrace" echo " h, help - Show this help" echo " q, quit - Quit debugging"}
# Breakpoint (for compatibility)breakpoint() { local condition="$1" local message="${2:-Breakpoint hit}" if [[ $DEBUG_ENABLED -eq 1 ]]; then if [[ -n "$condition" ]]; then if ! eval "$condition"; then return 0 fi fi debug_log 1 "$message" echo "=== BREAKPOINT ===" echo "Function: ${FUNCNAME[1]}" echo "Line: ${BASH_LINENO[0]}" echo "File: ${BASH_SOURCE[1]}" echo "Stack:" for i in "${!FUNCNAME[@]}"; do echo " $i: ${FUNCNAME[$i]} (${BASH_SOURCE[$i]}:${BASH_LINENO[$i]})" done echo "==================" # Interactive debugging while true; do echo -n "debug> " read -r cmd case "$cmd" in "c"|"continue") break ;; "v"|"vars") echo "Local variables:" set | grep -E "^[a-zA-Z_][a-zA-Z0-9_]*=" | head -10 ;; "s"|"stack") echo "Call stack:" for i in "${!FUNCNAME[@]}"; do echo " $i: ${FUNCNAME[$i]}" done ;; "q"|"quit") exit 1 ;; "h"|"help") echo "Commands: c(continue), v(vars), s(stack), q(quit), h(help)" ;; *) echo "Unknown command: $cmd" ;; esac done fi}
# Variable watcherwatch_variable() { local var_name="$1" local old_value="${!var_name}" while true; do local new_value="${!var_name}" if [[ "$new_value" != "$old_value" ]]; then echo "Variable $var_name changed: '$old_value' -> '$new_value'" old_value="$new_value" fi sleep 0.1 done}
# Function tracertrace_function() { local func_name="$1" local -n result_ref="$2" # Save original function if declare -f "$func_name" >/dev/null; then eval "original_$func_name() { $(declare -f "$func_name" | tail -n +2); }" fi # Create traced version eval "$func_name() { echo \"ENTER: $func_name \$@\" local start_time=\$(date +%s%N) original_$func_name \"\$@\" local result=\$? local end_time=\$(date +%s%N) local duration=\$(((end_time - start_time) / 1000000)) echo \"EXIT: $func_name (result: \$result, duration: \${duration}ms)\" return \$result }" result_ref="Function $func_name is now being traced"}
# Remove function traceruntrace_function() { local func_name="$1" if declare -f "original_$func_name" >/dev/null; then eval "$func_name() { $(declare -f "original_$func_name" | tail -n +2); }" unset -f "original_$func_name" echo "Function $func_name is no longer being traced" fi}
# Profiling utilitiesdeclare -A PROFILE_DATAdeclare -i PROFILE_ENABLED=0declare -i PROFILE_START_TIME=0declare -g PROFILER_ENABLED=0declare -g PROFILER_DATA=()
# Enable profilingenable_profile() { PROFILE_ENABLED=1 PROFILER_ENABLED=1 PROFILE_START_TIME=$(date +%s%N) PROFILER_START_TIME=$(date +%s.%N) PROFILE_DATA=() PROFILER_DATA=() # Set up profiling trap trap 'profile_trap $LINENO "$BASH_COMMAND"' DEBUG echo "Profiling enabled"}
# Disable profilingdisable_profile() { PROFILE_ENABLED=0 PROFILER_ENABLED=0 # Remove profiling trap trap - DEBUG echo "Profiling disabled"}
# Profile trap handlerprofile_trap() { local line_no="$1" local command="$2" local current_time=$(date +%s%N) local duration=$((current_time - PROFILE_START_TIME)) if [[ $PROFILE_ENABLED -eq 1 ]]; then PROFILE_DATA["$line_no"]="${PROFILE_DATA[$line_no]:-0} $duration" fi if [[ $PROFILER_ENABLED -eq 1 ]]; then PROFILER_DATA+=("$line_no:$duration") debug_log 2 "Profile: Line $line_no took ${duration}ns" fi}
# Generate profile reportgenerate_profile_report() { local output_file="${1:-profile_report.txt}" { echo "Profile Report - $(date)" echo "========================" echo echo "Line execution counts:" for line_no in "${!PROFILE_DATA[@]}"; do local times="${PROFILE_DATA[$line_no]}" local count=$(echo "$times" | wc -w) echo "Line $line_no: $count executions" done echo echo "Total execution time: $(((date +%s%N) - PROFILE_START_TIME) / 1000000)ms" } > "$output_file" echo "Profile report generated: $output_file"}
# Function profilerprofile_function() { local func_name="$1" local iterations="${2:-100}" local -n result_ref="$3" if ! declare -f "$func_name" >/dev/null; then echo "Function not found: $func_name" return 1 fi echo "Profiling function: $func_name ($iterations iterations)" local total_time=0 local min_time=999999999 local max_time=0 for ((i=0; i<iterations; i++)); do local start_time=$(date +%s%N) "$func_name" >/dev/null 2>&1 local end_time=$(date +%s%N) local duration=$(((end_time - start_time) / 1000000)) # Convert to ms total_time=$((total_time + duration)) if [[ $duration -lt $min_time ]]; then min_time=$duration fi if [[ $duration -gt $max_time ]]; then max_time=$duration fi done local avg_time=$((total_time / iterations)) result_ref["function"]="$func_name" result_ref["iterations"]=$iterations result_ref["total_ms"]=$total_time result_ref["avg_ms"]=$avg_time result_ref["min_ms"]=$min_time result_ref["max_ms"]=$max_time echo "Function: $func_name" echo "Iterations: $iterations" echo "Total time: ${total_time}ms" echo "Average: ${avg_time}ms" echo "Min: ${min_time}ms" echo "Max: ${max_time}ms"}
# Function profiler (for compatibility)profile_function_compat() { local func_name="$1" local start_time start_time=$(date +%s.%N) # Call the function "$@" local end_time end_time=$(date +%s.%N) local duration=$(echo "$end_time - $start_time" | bc -l) if [[ $PROFILER_ENABLED -eq 1 ]]; then PROFILER_DATA+=("$func_name:$duration") debug_log 2 "Profile: $func_name took ${duration}s" fi}
# Memory usage profilerprofile_memory() { local command="$1" local -n result_ref="$2" echo "Profiling memory usage for: $command" # Get initial memory local initial_mem=$(get_memory_usage) local initial_pid=$$ # Run command eval "$command" >/dev/null 2>&1 local exit_code=$? # Get final memory local final_mem=$(get_memory_usage) result_ref["command"]="$command" result_ref["initial_kb"]=$initial_mem result_ref["final_kb"]=$final_mem result_ref["delta_kb"]=$((final_mem - initial_mem)) result_ref["exit_code"]=$exit_code echo "Command: $command" echo "Initial memory: ${initial_mem}KB" echo "Final memory: ${final_mem}KB" echo "Memory delta: $((final_mem - initial_mem))KB" echo "Exit code: $exit_code"}
# Get memory usageget_memory_usage() { local pid="${1:-$$}" if command -v ps > /dev/null; then ps -o rss= -p "$pid" | tr -d ' ' else echo "0" fi}
# Performance monitormonitor_performance() { local command="$1" local interval="${2:-1}" echo "Monitoring performance of: $command" echo "Time(s) | CPU% | Memory(MB) | Status" echo "$(repeat_str "-" 40)" local start_time=$(date +%s) local pid # Start command in background eval "$command" & pid=$! while kill -0 "$pid" 2>/dev/null; do local elapsed=$(($(date +%s) - start_time)) local cpu_usage=$(ps -o %cpu= -p "$pid" 2>/dev/null | tr -d ' ') local memory_kb=$(ps -o rss= -p "$pid" 2>/dev/null | tr -d ' ') local memory_mb=$(echo "scale=2; $memory_kb / 1024" | bc -l 2>/dev/null || echo "0") printf "%7s | %4s | %10s | Running\n" "$elapsed" "${cpu_usage:-0}" "${memory_mb:-0}" sleep "$interval" done local final_elapsed=$(($(date +%s) - start_time)) printf "%7s | %4s | %10s | Completed\n" "$final_elapsed" "0" "0"}
# Code analysis utilitiesanalyze_script() { local script_file="$1" local -n result_ref="$2" if [[ ! -f "$script_file" ]]; then echo "Script file not found: $script_file" return 1 fi echo "Analyzing script: $script_file" # Count lines local total_lines=$(wc -l < "$script_file") local non_empty_lines=$(grep -c . "$script_file") local comment_lines=$(grep -c '^[[:space:]]*#' "$script_file") # Count functions local function_count=$(grep -c '^function \|^ *[a-zA-Z_][a-zA-Z0-9_]*() ' "$script_file") # Count variables local variable_count=$(grep -c '^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*=' "$script_file") # Check for common issues local issues=() # Check for unused variables (basic) if grep -q '^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*=' "$script_file"; then local declared_vars=$(grep '^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*=' "$script_file" | sed 's/^[[:space:]]*\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/' | sort -u) for var in $declared_vars; do if ! grep -q "\$$var" "$script_file"; then issues+=("Potentially unused variable: $var") fi done fi # Check for functions without return if grep -q '^function \|^ *[a-zA-Z_][a-zA-Z0-9_]*() ' "$script_file"; then local func_without_return=$(grep -A 10 '^function \|^ *[a-zA-Z_][a-zA-Z0-9_]*() ' "$script_file" | grep -B 10 -E '^[[:space:]]*}' | grep -E '^function \|^ *[a-zA-Z_][a-zA-Z0-9_]*() ' | wc -l) if [[ $func_without_return -gt 0 ]]; then issues+=("$func_without_return functions may not have explicit return") fi fi result_ref["file"]="$script_file" result_ref["total_lines"]=$total_lines result_ref["non_empty_lines"]=$non_empty_lines result_ref["comment_lines"]=$comment_lines result_ref["function_count"]=$function_count result_ref["variable_count"]=$variable_count result_ref["issues"]="${issues[*]}" echo "Analysis results for $script_file:" echo "Total lines: $total_lines" echo "Non-empty lines: $non_empty_lines" echo "Comment lines: $comment_lines" echo "Functions: $function_count" echo "Variables: $variable_count" if [[ ${#issues[@]} -gt 0 ]]; then echo "Issues found:" for issue in "${issues[@]}"; do echo " - $issue" done fi}
# Code analyzer (for compatibility)analyze_code() { local file="$1" if [[ ! -f "$file" ]]; then error "File not found: $file" return 1 fi echo "Code Analysis for: $file" echo "$(repeat_str "=" 50)" # Basic stats local lines=$(wc -l < "$file") local functions=$(grep -c "^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*(" "$file") local comments=$(grep -c "^[[:space:]]*#" "$file") local empty_lines=$(grep -c "^[[:space:]]*$" "$file") echo "Lines: $lines" echo "Functions: $functions" echo "Comments: $comments" echo "Empty lines: $empty_lines" echo "Code density: $(echo "scale=1; ($lines - $comments - $empty_lines) * 100 / $lines" | bc -l)%" echo # Function analysis echo "Functions:" echo "$(repeat_str "-" 30)" grep -n "^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*(" "$file" | while read -r line; do local line_num=$(echo "$line" | cut -d':' -f1) local func_def=$(echo "$line" | cut -d':' -f2-) echo " $line_num: $func_def" done echo # Potential issues echo "Potential Issues:" echo "$(repeat_str "-" 30)" # Check for common issues if grep -q "eval " "$file"; then echo " ⚠ Uses eval (potential security risk)" fi if grep -q "\$.*\|.*\$" "$file"; then echo " ⚠ Uses pipe to subshell (performance impact)" fi if grep -q "rm -rf " "$file"; then echo " ⚠ Uses rm -rf (destructive operation)" fi if grep -q "chmod +x " "$file"; then echo " ⚠ Uses chmod +x (security consideration)" fi}
# Check script syntaxcheck_syntax() { local script_file="$1" local -n result_ref="$2" if [[ ! -f "$script_file" ]]; then echo "Script file not found: $script_file" return 1 fi echo "Checking syntax for: $script_file" local syntax_output syntax_output=$(bash -n "$script_file" 2>&1) local syntax_result=$? result_ref["file"]="$script_file" result_ref["syntax_result"]=$syntax_result result_ref["syntax_output"]="$syntax_output" if [[ $syntax_result -eq 0 ]]; then echo "Syntax check passed" else echo "Syntax errors found:" echo "$syntax_output" fi return $syntax_result}
# Code formatterformat_code() { local script_file="$1" local output_file="${2:-${script_file%.sh}_formatted.sh}" local indent_size="${3:-4}" if [[ ! -f "$script_file" ]]; then echo "Script file not found: $script_file" return 1 fi echo "Formatting code: $script_file -> $output_file" # Basic formatting rules sed " # Remove trailing whitespace s/[[:space:]]*$// # Ensure consistent spacing around operators s/\([^=]\)=\([^=]\)/\1 = \2/g s/\([^+]\)\+\([^+]\)/\1 + \2/g s/\([^-]\)-\([^-]\)/\1 - \2/g s/\([^*]\)\*\([^*]\)/\1 * \2/g s/\([^/]\)\/\([^/]\)/\1 \/ \2/g # Add spacing after semicolons s/;/; /g " "$script_file" > "$output_file" echo "Code formatted: $output_file"}
# Code formatter (for compatibility)format_code_compat() { local file="$1" local backup="${2:-1}" if [[ ! -f "$file" ]]; then error "File not found: $file" return 1 fi if [[ "$backup" == "1" ]]; then cp "$file" "$file.backup" echo "Backup created: $file.backup" fi # Format the code local temp_file=$(mktemp) # Remove trailing whitespace sed 's/[[:space:]]*$//' "$file" > "$temp_file" # Ensure proper spacing around operators sed -i 's/=\([^=]\)/= \1/g' "$temp_file" sed -i 's/\([^=]\)=/\1 =/g' "$temp_file" # Add proper indentation (basic) sed -i 's/^ / /g' "$temp_file" # Move formatted file back mv "$temp_file" "$file" echo "Code formatted: $file"}
# Lint scriptlint_script() { local script_file="$1" local -n result_ref="$2" if [[ ! -f "$script_file" ]]; then echo "Script file not found: $script_file" return 1 fi echo "Linting script: $script_file" local -a lint_issues=() local line_num=0 while IFS= read -r line; do ((line_num++)) # Check for common issues if [[ "$line" =~ ^[[:space:]]*echo[[:space:]]+.*\$[A-Za-z_][A-Za-z0-9_]*[[:space:]]*$ ]]; then lint_issues+=("Line $line_num: Unquoted variable in echo") fi if [[ "$line" =~ ^[[:space:]]*rm[[:space:]]+-rf[[:space:]]+/ ]]; then lint_issues+=("Line $line_num: Dangerous rm -rf / command") fi if [[ "$line" =~ ^[[:space:]]*eval[[:space:]]+ ]]; then lint_issues+=("Line $line_num: Use of eval (potential security risk)") fi if [[ "$line" =~ ^[[:space:]]*chmod[[:space:]]+777 ]]; then lint_issues+=("Line $line_num: World-writable permissions (security risk)") fi done < "$script_file" result_ref["file"]="$script_file" result_ref["issues"]="${lint_issues[*]}" result_ref["issue_count"]=${#lint_issues[@]} echo "Lint results for $script_file:" if [[ ${#lint_issues[@]} -eq 0 ]]; then echo "No issues found" else echo "Issues found (${#lint_issues[@]}):" for issue in "${lint_issues[@]}"; do echo " - $issue" done fi}
# Linter (for compatibility)lint_code() { local file="$1" local errors=0 echo "Linting: $file" echo "$(repeat_str "=" 40)" # Check shebang if ! head -n1 "$file" | grep -q "^#!"; then echo "✗ Missing shebang" ((errors++)) else echo "✓ Shebang present" fi # Check for common issues local issues=( "eval.*\\$.*:Use of eval with variables" "rm -rf.*\\$:Destructive operation with variable" "chmod +x.*\\$:Permission change with variable" "^[[:space:]]*echo.*>>.*\\$:Appending to variable file" "^[[:space:]]*\\$.*\\|.*\\$:Pipe to subshell" ) for issue in "${issues[@]}"; do local pattern=$(echo "$issue" | cut -d':' -f1) local message=$(echo "$issue" | cut -d':' -f2) if grep -qE "$pattern" "$file"; then echo "⚠ $message" ((errors++)) fi done # Check function naming while IFS= read -r line; do if [[ "$line" =~ ^[[:space:]]*([a-zA-Z_][a-zA-Z0-9_]*)[[:space:]]*\( ]]; then local func_name="${BASH_REMATCH[1]}" if [[ ! "$func_name" =~ ^[a-z_][a-z0-9_]*$ ]]; then echo "⚠ Function name should be lowercase: $func_name" ((errors++)) fi fi done < "$file" echo if [[ $errors -eq 0 ]]; then echo "✓ No issues found" else echo "✗ $errors potential issues found" fi return $errors}
# Performance benchmarkbenchmark_script() { local script_file="$1" local iterations="${2:-10}" local -n result_ref="$3" if [[ ! -f "$script_file" ]]; then echo "Script file not found: $script_file" return 1 fi echo "Benchmarking script: $script_file ($iterations iterations)" local total_time=0 local min_time=999999999 local max_time=0 for ((i=0; i<iterations; i++)); do local start_time=$(date +%s%N) bash "$script_file" >/dev/null 2>&1 local end_time=$(date +%s%N) local duration=$(((end_time - start_time) / 1000000)) # Convert to ms total_time=$((total_time + duration)) if [[ $duration -lt $min_time ]]; then min_time=$duration fi if [[ $duration -gt $max_time ]]; then max_time=$duration fi done local avg_time=$((total_time / iterations)) result_ref["script"]="$script_file" result_ref["iterations"]=$iterations result_ref["total_ms"]=$total_time result_ref["avg_ms"]=$avg_time result_ref["min_ms"]=$min_time result_ref["max_ms"]=$max_time echo "Benchmark results for $script_file:" echo "Iterations: $iterations" echo "Total time: ${total_time}ms" echo "Average: ${avg_time}ms" echo "Min: ${min_time}ms" echo "Max: ${max_time}ms"}
# Development serverdev_server() { local port="${1:-8080}" local watch_dir="${2:-.}" local command="${3:-echo 'File changed'}" echo "Development server started on port $port" echo "Watching directory: $watch_dir" echo "Command: $command" echo "Press Ctrl+C to stop" echo while true; do if command -v inotifywait >/dev/null 2>&1; then inotifywait -r -e modify,create,delete "$watch_dir" 2>/dev/null echo "Files changed. Running command..." eval "$command" else # Fallback to simple polling sleep 2 echo "Polling for changes..." eval "$command" fi done}
# Development server (for compatibility)dev_server_compat() { local port="${1:-8080}" local watch_dir="${2:-.}" local command="${3:-bash}" echo "Development Server" echo "Port: $port" echo "Watch directory: $watch_dir" echo "Command: $command" echo "$(repeat_str "=" 40)" # Simple file watcher (requires inotify-tools) if command -v inotifywait > /dev/null; then while true; do echo "Watching for changes..." inotifywait -r -e modify,create,delete "$watch_dir" 2>/dev/null echo "Files changed. Restarting..." eval "$command" done else echo "inotifywait not found. Install inotify-tools for file watching." echo "Running command once..." eval "$command" fi}
# Export module functionsexport_module devtools \ enable_debug disable_debug debug_log breakpoint set_breakpoint remove_breakpoint list_breakpoints debug_prompt \ watch_variable trace_function untrace_function \ enable_profile disable_profile generate_profile_report profile_function profile_function_compat profile_memory \ analyze_script analyze_code check_syntax format_code format_code_compat lint_script lint_code benchmark_script \ get_memory_usage monitor_performance \ dev_server dev_server_compat