@@ -28,6 +28,72 @@ print_header() {
2828 echo -e " ${PURPLE_BOLD} Optimize and Check${NC} "
2929}
3030
31+ # Bash-native JSON parsing helpers (no jq dependency).
32+ # Extract a simple numeric value from JSON by key.
33+ json_get_value () {
34+ local json=" $1 "
35+ local key=" $2 "
36+ local value
37+ value=$( echo " $json " | grep -o " \" ${key} \" [[:space:]]*:[[:space:]]*[0-9.]*" | head -1 | sed ' s/.*:[[:space:]]*//' )
38+ echo " ${value:- 0} "
39+ }
40+
41+ # Validate JSON has expected structure (basic check).
42+ json_validate () {
43+ local json=" $1 "
44+ # Check for required keys
45+ [[ " $json " == * ' "memory_used_gb"' * ]] &&
46+ [[ " $json " == * ' "optimizations"' * ]] &&
47+ [[ " $json " == * ' {' * ]] && [[ " $json " == * ' }' * ]]
48+ }
49+
50+ # Parse optimization items from JSON array.
51+ # Outputs pipe-delimited records: action|name|description|safe
52+ parse_optimization_items () {
53+ local json=" $1 "
54+ # Extract the optimizations array content
55+ local in_array=false
56+ local brace_count=0
57+ local current_item=" "
58+
59+ while IFS= read -r line; do
60+ # Detect start of optimizations array
61+ if [[ " $line " == * ' "optimizations"' * ' [' * ]]; then
62+ in_array=true
63+ continue
64+ fi
65+
66+ [[ " $in_array " != " true" ]] && continue
67+
68+ # Count braces to track object boundaries
69+ if [[ " $line " == * ' {' * ]]; then
70+ (( brace_count++ ))
71+ fi
72+
73+ if (( brace_count > 0 )) ; then
74+ current_item+=" $line "
75+ fi
76+
77+ if [[ " $line " == * ' }' * ]]; then
78+ (( brace_count-- ))
79+ if (( brace_count == 0 )) && [[ -n " $current_item " ]]; then
80+ # Extract fields from the collected item
81+ local action name desc safe
82+ action=$( echo " $current_item " | grep -o ' "action"[[:space:]]*:[[:space:]]*"[^"]*"' | sed ' s/.*"action"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' )
83+ name=$( echo " $current_item " | grep -o ' "name"[[:space:]]*:[[:space:]]*"[^"]*"' | sed ' s/.*"name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' )
84+ desc=$( echo " $current_item " | grep -o ' "description"[[:space:]]*:[[:space:]]*"[^"]*"' | sed ' s/.*"description"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' )
85+ safe=$( echo " $current_item " | grep -o ' "safe"[[:space:]]*:[[:space:]]*[a-z]*' | sed ' s/.*:[[:space:]]*//' )
86+
87+ [[ -n " $action " ]] && echo " ${action} |${name} |${desc} |${safe} "
88+ current_item=" "
89+ fi
90+ fi
91+
92+ # End of array
93+ [[ " $line " == * ' ]' * ]] && (( brace_count == 0 )) && break
94+ done <<< " $json"
95+ }
96+
3197run_system_checks () {
3298 # Skip checks in dry-run mode.
3399 if [[ " ${MOLE_DRY_RUN:- 0} " == " 1" ]]; then
@@ -139,12 +205,12 @@ show_optimization_summary() {
139205show_system_health () {
140206 local health_json=" $1 "
141207
142- local mem_used=$( echo " $health_json " | jq -r ' .memory_used_gb // 0 ' 2> /dev/null || echo " 0 " )
143- local mem_total=$( echo " $health_json " | jq -r ' .memory_total_gb // 0 ' 2> /dev/null || echo " 0 " )
144- local disk_used=$( echo " $health_json " | jq -r ' .disk_used_gb // 0 ' 2> /dev/null || echo " 0 " )
145- local disk_total=$( echo " $health_json " | jq -r ' .disk_total_gb // 0 ' 2> /dev/null || echo " 0 " )
146- local disk_percent=$( echo " $health_json " | jq -r ' .disk_used_percent // 0 ' 2> /dev/null || echo " 0 " )
147- local uptime=$( echo " $health_json " | jq -r ' .uptime_days // 0 ' 2> /dev/null || echo " 0 " )
208+ local mem_used=$( json_get_value " $health_json " " memory_used_gb " )
209+ local mem_total=$( json_get_value " $health_json " " memory_total_gb " )
210+ local disk_used=$( json_get_value " $health_json " " disk_used_gb " )
211+ local disk_total=$( json_get_value " $health_json " " disk_total_gb " )
212+ local disk_percent=$( json_get_value " $health_json " " disk_used_percent " )
213+ local uptime=$( json_get_value " $health_json " " uptime_days " )
148214
149215 mem_used=${mem_used:- 0}
150216 mem_total=${mem_total:- 0}
@@ -157,11 +223,6 @@ show_system_health() {
157223 " $mem_used " " $mem_total " " $disk_used " " $disk_total " " $uptime "
158224}
159225
160- parse_optimizations () {
161- local health_json=" $1 "
162- echo " $health_json " | jq -c ' .optimizations[]' 2> /dev/null
163- }
164-
165226announce_action () {
166227 local name=" $1 "
167228 local desc=" $2 "
@@ -406,12 +467,6 @@ main() {
406467 echo -e " ${YELLOW}${ICON_DRY_RUN} DRY RUN MODE${NC} , No files will be modified\n"
407468 fi
408469
409- if ! command -v jq > /dev/null 2>&1 ; then
410- echo -e " ${YELLOW}${ICON_ERROR}${NC} Missing dependency: jq"
411- echo -e " ${GRAY} Install with: ${GREEN} brew install jq${NC} "
412- exit 1
413- fi
414-
415470 if ! command -v bc > /dev/null 2>&1 ; then
416471 echo -e " ${YELLOW}${ICON_ERROR}${NC} Missing dependency: bc"
417472 echo -e " ${GRAY} Install with: ${GREEN} brew install bc${NC} "
@@ -431,13 +486,13 @@ main() {
431486 exit 1
432487 fi
433488
434- if ! echo " $health_json " | jq empty 2> /dev/null ; then
489+ if ! json_validate " $health_json " ; then
435490 if [[ -t 1 ]]; then
436491 stop_inline_spinner
437492 fi
438493 echo " "
439494 log_error " Invalid system health data format"
440- echo -e " ${GRAY}${ICON_REVIEW}${NC} Check if jq, awk, sysctl, and df commands are available"
495+ echo -e " ${GRAY}${ICON_REVIEW}${NC} Check if awk, sysctl, and df commands are available"
441496 exit 1
442497 fi
443498
@@ -463,17 +518,12 @@ main() {
463518 local -a confirm_items=()
464519 local opts_file
465520 opts_file=$( mktemp_file)
466- parse_optimizations " $health_json " > " $opts_file "
467-
468- while IFS= read -r opt_json; do
469- [[ -z " $opt_json " ]] && continue
521+ parse_optimization_items " $health_json " > " $opts_file "
470522
471- local name=$( echo " $opt_json " | jq -r ' .name' )
472- local desc=$( echo " $opt_json " | jq -r ' .description' )
473- local action=$( echo " $opt_json " | jq -r ' .action' )
474- local path=$( echo " $opt_json " | jq -r ' .path // ""' )
475- local safe=$( echo " $opt_json " | jq -r ' .safe' )
523+ while IFS=' |' read -r action name desc safe; do
524+ [[ -z " $action " ]] && continue
476525
526+ local path=" "
477527 local item=" ${name} |${desc} |${action} |${path} "
478528
479529 if [[ " $safe " == " true" ]]; then
0 commit comments