diff --git a/README.md b/README.md index 1709e4d..9b7f37e 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ brew install mole curl -fsSL https://raw.githubusercontent.com/tw93/mole/main/install.sh | bash ``` -**Windows:** Mole is designed for macOS, but we offer an experimental Windows version based on user demand. See the [windows branch](https://github.com/tw93/Mole/tree/windows) — for early adopters only. +**Windows:** Mole is designed for macOS, but we offer an experimental Windows version based on user demand. See the [windows branch](https://github.com/tw93/Mole/tree/windows), for early adopters only. **Run:** @@ -210,7 +210,7 @@ Select Categories to Clean - 18.5GB (8 selected) ● backend-service 2.5GB | node_modules ``` -> **Use with caution:** This will permanently delete selected artifacts. Review carefully before confirming. Recent projects — less than 7 days old — are marked and unselected by default. +> **Use with caution:** This will permanently delete selected artifacts. Review carefully before confirming. Recent projects, less than 7 days old, are marked and unselected by default.
Custom Scan Paths @@ -282,4 +282,4 @@ Join thousands of users worldwide who trust Mole to keep their Macs clean and op ## License -MIT License — feel free to enjoy and participate in open source. +MIT License, feel free to enjoy and participate in open source. diff --git a/bin/clean.sh b/bin/clean.sh index 93262a3..4320106 100755 --- a/bin/clean.sh +++ b/bin/clean.sh @@ -381,7 +381,7 @@ safe_clean() { stop_section_spinner fi - debug_log "Cleaning: $description (${#existing_paths[@]} items)" + debug_log "Cleaning: $description, ${#existing_paths[@]} items" # Enhanced debug output with risk level and details if [[ "${MO_DEBUG:-}" == "1" && ${#existing_paths[@]} -gt 0 ]]; then @@ -612,7 +612,7 @@ safe_clean() { debug_log "Permission denied while cleaning: $description" fi if [[ $removal_failed_count -gt 0 && "$DRY_RUN" != "true" ]]; then - debug_log "Skipped $removal_failed_count items (permission denied or in use) for: $description" + debug_log "Skipped $removal_failed_count items, permission denied or in use, for: $description" fi if [[ $removed_any -eq 1 ]]; then @@ -627,7 +627,7 @@ safe_clean() { fi if [[ "$DRY_RUN" == "true" ]]; then - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} $label ${YELLOW}($size_human dry)${NC}" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} $label${NC}, ${YELLOW}$size_human dry${NC}" local paths_temp=$(create_temp_file) @@ -678,7 +678,7 @@ safe_clean() { ' | while IFS='|' read -r display_path total_size child_count; do local size_human=$(bytes_to_human "$((total_size * 1024))") if [[ $child_count -gt 1 ]]; then - echo "$display_path # $size_human ($child_count items)" >> "$EXPORT_LIST_FILE" + echo "$display_path # $size_human, $child_count items" >> "$EXPORT_LIST_FILE" else echo "$display_path # $size_human" >> "$EXPORT_LIST_FILE" fi @@ -687,7 +687,7 @@ safe_clean() { rm -f "$paths_temp" fi else - echo -e " ${GREEN}${ICON_SUCCESS}${NC} $label ${GREEN}($size_human)${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} $label${NC}, ${GREEN}$size_human${NC}" fi ((files_cleaned += total_count)) ((total_size_cleaned += total_size_kb)) @@ -711,7 +711,7 @@ start_cleanup() { fi if [[ "$DRY_RUN" == "true" ]]; then - echo -e "${YELLOW}Dry Run Mode${NC} - Preview only, no deletions" + echo -e "${YELLOW}Dry Run Mode${NC}, Preview only, no deletions" echo "" SYSTEM_CLEAN=false @@ -737,7 +737,7 @@ EOF echo -e "${GREEN}${ICON_SUCCESS}${NC} Admin access already available" echo "" else - echo -ne "${PURPLE}${ICON_ARROW}${NC} System caches need sudo — ${GREEN}Enter${NC} continue, ${GRAY}Space${NC} skip: " + echo -ne "${PURPLE}${ICON_ARROW}${NC} System caches need sudo. ${GREEN}Enter${NC} continue, ${GRAY}Space${NC} skip: " local choice choice=$(read_key) @@ -774,10 +774,10 @@ EOF echo "Running in non-interactive mode" if sudo -n true 2> /dev/null; then SYSTEM_CLEAN=true - echo " ${ICON_LIST} System-level cleanup enabled (sudo session active)" + echo " ${ICON_LIST} System-level cleanup enabled, sudo session active" else SYSTEM_CLEAN=false - echo " ${ICON_LIST} System-level cleanup skipped (requires sudo)" + echo " ${ICON_LIST} System-level cleanup skipped, requires sudo" fi echo " ${ICON_LIST} User-level cleanup will proceed automatically" echo "" @@ -790,7 +790,7 @@ perform_cleanup() { if [[ "${MOLE_TEST_MODE:-0}" == "1" ]]; then test_mode_enabled=true if [[ "$DRY_RUN" == "true" ]]; then - echo -e "${YELLOW}Dry Run Mode${NC} - Preview only, no deletions" + echo -e "${YELLOW}Dry Run Mode${NC}, Preview only, no deletions" echo "" fi echo -e "${GREEN}${ICON_LIST}${NC} User app cache" @@ -1054,7 +1054,7 @@ perform_cleanup() { else summary_status="info" if [[ "$DRY_RUN" == "true" ]]; then - summary_details+=("No significant reclaimable space detected (system already clean).") + summary_details+=("No significant reclaimable space detected, system already clean.") else summary_details+=("System was already clean; no additional space freed.") fi diff --git a/bin/completion.sh b/bin/completion.sh index b3d345c..0a187e3 100755 --- a/bin/completion.sh +++ b/bin/completion.sh @@ -84,7 +84,7 @@ if [[ $# -eq 0 ]]; then echo -e "${GREEN}${ICON_SUCCESS}${NC} Removed stale completion entries from $config_file" echo "" fi - log_error "mole not found in PATH - install Mole before enabling completion" + log_error "mole not found in PATH, install Mole before enabling completion" exit 1 fi diff --git a/bin/installer.sh b/bin/installer.sh index 8eed412..f088c19 100755 --- a/bin/installer.sh +++ b/bin/installer.sh @@ -387,7 +387,7 @@ select_installers() { scroll_indicator=" ${GRAY}[${current_pos}/${total_items}]${NC}" fi - printf "${PURPLE_BOLD}Select Installers to Remove${NC}%s ${GRAY}- ${selected_human} ($selected_count selected)${NC}\n" "$scroll_indicator" + printf "${PURPLE_BOLD}Select Installers to Remove${NC}%s ${GRAY}, ${selected_human}, ${selected_count} selected${NC}\n" "$scroll_indicator" printf "%s\n" "$clear_line" # Calculate visible range @@ -546,13 +546,13 @@ delete_selected_installers() { local file_size="${INSTALLER_SIZES[$idx]}" local size_human size_human=$(bytes_to_human "$file_size") - echo -e " ${GREEN}${ICON_SUCCESS}${NC} $(basename "$file_path") ${GRAY}(${size_human})${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} $(basename "$file_path") ${GRAY}, ${size_human}${NC}" fi done # Confirm deletion echo "" - echo -ne "${PURPLE}${ICON_ARROW}${NC} Delete ${#selected_indices[@]} installer(s) (${confirm_human}) ${GREEN}Enter${NC} confirm, ${GRAY}ESC${NC} cancel: " + echo -ne "${PURPLE}${ICON_ARROW}${NC} Delete ${#selected_indices[@]} installers, ${confirm_human} ${GREEN}Enter${NC} confirm, ${GRAY}ESC${NC} cancel: " IFS= read -r -s -n1 confirm || confirm="" case "$confirm" in @@ -655,7 +655,7 @@ show_summary() { local freed_mb freed_mb=$(echo "$total_size_freed_kb" | awk '{printf "%.2f", $1/1024}') - summary_details+=("Removed ${GREEN}$total_deleted${NC} installer(s), freed ${GREEN}${freed_mb}MB${NC}") + summary_details+=("Removed ${GREEN}$total_deleted${NC} installers, freed ${GREEN}${freed_mb}MB${NC}") summary_details+=("Your Mac is cleaner now!") else summary_details+=("No installers were removed") diff --git a/bin/optimize.sh b/bin/optimize.sh index 0413b5a..9fe3864 100755 --- a/bin/optimize.sh +++ b/bin/optimize.sh @@ -78,7 +78,7 @@ show_optimization_summary() { local total_applied=$((safe_count + confirm_count)) if [[ "${MOLE_DRY_RUN:-0}" == "1" ]]; then - summary_title="Dry Run Complete - No Changes Made" + summary_title="Dry Run Complete, No Changes Made" summary_details+=("Would apply ${YELLOW}${total_applied:-0}${NC} optimizations") summary_details+=("Run without ${YELLOW}--dry-run${NC} to apply these changes") else @@ -115,9 +115,9 @@ show_optimization_summary() { fi if [[ -n "$key_stat" ]]; then - summary_details+=("Applied ${GREEN}${total_applied:-0}${NC} optimizations — ${key_stat}") + summary_details+=("Applied ${GREEN}${total_applied:-0}${NC} optimizations, ${key_stat}") else - summary_details+=("Applied ${GREEN}${total_applied:-0}${NC} optimizations — all services tuned") + summary_details+=("Applied ${GREEN}${total_applied:-0}${NC} optimizations, all services tuned") fi local summary_line3="" @@ -126,11 +126,11 @@ show_optimization_summary() { if [[ -n "${AUTO_FIX_DETAILS:-}" ]]; then local detail_join detail_join=$(echo "${AUTO_FIX_DETAILS}" | paste -sd ", " -) - [[ -n "$detail_join" ]] && summary_line3+=" — ${detail_join}" + [[ -n "$detail_join" ]] && summary_line3+=": ${detail_join}" fi summary_details+=("$summary_line3") fi - summary_details+=("System fully optimized — faster, more secure and responsive") + summary_details+=("System fully optimized") fi print_summary_block "$summary_title" "${summary_details[@]}" @@ -226,12 +226,12 @@ cleanup_path() { if [[ "$removed" == "true" ]]; then if [[ -n "$size_display" ]]; then - echo -e "${GREEN}${ICON_SUCCESS}${NC} $label ${GREEN}(${size_display})${NC}" + echo -e "${GREEN}${ICON_SUCCESS}${NC} $label${NC}, ${GREEN}${size_display}${NC}" else echo -e "${GREEN}${ICON_SUCCESS}${NC} $label" fi else - echo -e "${GRAY}${ICON_WARNING}${NC} Skipped $label ${GRAY}(grant Full Disk Access to your terminal and retry)${NC}" + echo -e "${GRAY}${ICON_WARNING}${NC} Skipped $label${GRAY}, grant Full Disk Access to your terminal and retry${NC}" fi } @@ -252,7 +252,7 @@ collect_security_fix_actions() { fi if [[ "${GATEKEEPER_DISABLED:-}" == "true" ]]; then if ! is_whitelisted "gatekeeper"; then - SECURITY_FIXES+=("gatekeeper|Enable Gatekeeper (App download protection)") + SECURITY_FIXES+=("gatekeeper|Enable Gatekeeper, app download protection") fi fi if touchid_supported && ! touchid_configured; then @@ -304,7 +304,7 @@ apply_firewall_fix() { FIREWALL_DISABLED=false return 0 fi - echo -e " ${GRAY}${ICON_WARNING}${NC} Failed to enable firewall (check permissions)" + echo -e " ${GRAY}${ICON_WARNING}${NC} Failed to enable firewall, check permissions" return 1 } @@ -327,7 +327,7 @@ apply_touchid_fix() { perform_security_fixes() { if ! ensure_sudo_session "Security changes require admin access"; then - echo -e "${GRAY}${ICON_WARNING}${NC} Skipped security fixes (sudo denied)" + echo -e "${GRAY}${ICON_WARNING}${NC} Skipped security fixes, sudo denied" return 1 fi @@ -391,7 +391,7 @@ main() { # Dry-run indicator. if [[ "${MOLE_DRY_RUN:-0}" == "1" ]]; then - echo -e "${YELLOW}${ICON_DRY_RUN} DRY RUN MODE${NC} - No files will be modified\n" + echo -e "${YELLOW}${ICON_DRY_RUN} DRY RUN MODE${NC}, No files will be modified\n" fi if ! command -v jq > /dev/null 2>&1; then diff --git a/bin/purge.sh b/bin/purge.sh index b169a77..eb3af0b 100755 --- a/bin/purge.sh +++ b/bin/purge.sh @@ -220,7 +220,7 @@ perform_purge() { # Show help message show_help() { - echo -e "${PURPLE_BOLD}Mole Purge${NC} - Clean old project build artifacts" + echo -e "${PURPLE_BOLD}Mole Purge${NC}, Clean old project build artifacts" echo "" echo -e "${YELLOW}Usage:${NC} mo purge [options]" echo "" @@ -231,7 +231,7 @@ show_help() { echo "" echo -e "${YELLOW}Default Paths:${NC}" for path in "${DEFAULT_PURGE_SEARCH_PATHS[@]}"; do - echo " - $path" + echo " * $path" done } diff --git a/bin/touchid.sh b/bin/touchid.sh index 4dce339..9f84dd0 100755 --- a/bin/touchid.sh +++ b/bin/touchid.sh @@ -141,7 +141,7 @@ enable_touchid() { sudo mv "$temp_file" "$PAM_SUDO_FILE" log_success "Touch ID migrated to sudo_local" else - log_success "Touch ID enabled (via sudo_local) - try: sudo ls" + log_success "Touch ID enabled, via sudo_local, try: sudo ls" fi return 0 else @@ -188,7 +188,7 @@ enable_touchid() { # Apply the changes if sudo mv "$temp_file" "$PAM_SUDO_FILE" 2> /dev/null; then - log_success "Touch ID enabled - try: sudo ls" + log_success "Touch ID enabled, try: sudo ls" return 0 else log_error "Failed to enable Touch ID" @@ -219,7 +219,7 @@ disable_touchid() { grep -v "pam_tid.so" "$PAM_SUDO_FILE" > "$temp_file" sudo mv "$temp_file" "$PAM_SUDO_FILE" fi - echo -e "${GREEN}${ICON_SUCCESS} Touch ID disabled (removed from sudo_local)${NC}" + echo -e "${GREEN}${ICON_SUCCESS} Touch ID disabled, removed from sudo_local${NC}" echo "" return 0 else diff --git a/bin/uninstall.sh b/bin/uninstall.sh index 94cbf66..13b20cc 100755 --- a/bin/uninstall.sh +++ b/bin/uninstall.sh @@ -496,7 +496,7 @@ main() { rm -f "$apps_file" continue fi - echo -e "${BLUE}${ICON_CONFIRM}${NC} Selected ${selection_count} app(s):" + echo -e "${BLUE}${ICON_CONFIRM}${NC} Selected ${selection_count} apps:" local -a summary_rows=() local max_name_display_width=0 local max_size_width=0 diff --git a/bin/uninstall_lib.sh b/bin/uninstall_lib.sh index 75e0ad0..26a94cc 100755 --- a/bin/uninstall_lib.sh +++ b/bin/uninstall_lib.sh @@ -565,7 +565,7 @@ main() { continue fi # Show selected apps with clean alignment - echo -e "${BLUE}${ICON_CONFIRM}${NC} Selected ${selection_count} app(s):" + echo -e "${BLUE}${ICON_CONFIRM}${NC} Selected ${selection_count} apps:" local -a summary_rows=() local max_name_width=0 local max_size_width=0 diff --git a/cmd/analyze/main.go b/cmd/analyze/main.go index 0978187..e06bc41 100644 --- a/cmd/analyze/main.go +++ b/cmd/analyze/main.go @@ -332,9 +332,9 @@ func (m *model) scheduleOverviewScans() tea.Cmd { if len(pendingIndices) > 0 { firstEntry := m.entries[pendingIndices[0]] if len(pendingIndices) == 1 { - m.status = fmt.Sprintf("Scanning %s... (%d left)", firstEntry.Name, remaining) + m.status = fmt.Sprintf("Scanning %s..., %d left", firstEntry.Name, remaining) } else { - m.status = fmt.Sprintf("Scanning %d directories... (%d left)", len(pendingIndices), remaining) + m.status = fmt.Sprintf("Scanning %d directories..., %d left", len(pendingIndices), remaining) } } @@ -736,7 +736,7 @@ func (m model) updateKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) { if len(m.largeMultiSelected) > 0 { count := len(m.largeMultiSelected) if count > maxBatchOpen { - m.status = fmt.Sprintf("Too many items to open (max %d, selected %d)", maxBatchOpen, count) + m.status = fmt.Sprintf("Too many items to open, max %d, selected %d", maxBatchOpen, count) return m, nil } for path := range m.largeMultiSelected { @@ -761,7 +761,7 @@ func (m model) updateKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) { if len(m.multiSelected) > 0 { count := len(m.multiSelected) if count > maxBatchOpen { - m.status = fmt.Sprintf("Too many items to open (max %d, selected %d)", maxBatchOpen, count) + m.status = fmt.Sprintf("Too many items to open, max %d, selected %d", maxBatchOpen, count) return m, nil } for path := range m.multiSelected { @@ -790,7 +790,7 @@ func (m model) updateKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) { if len(m.largeMultiSelected) > 0 { count := len(m.largeMultiSelected) if count > maxBatchReveal { - m.status = fmt.Sprintf("Too many items to reveal (max %d, selected %d)", maxBatchReveal, count) + m.status = fmt.Sprintf("Too many items to reveal, max %d, selected %d", maxBatchReveal, count) return m, nil } for path := range m.largeMultiSelected { @@ -815,7 +815,7 @@ func (m model) updateKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) { if len(m.multiSelected) > 0 { count := len(m.multiSelected) if count > maxBatchReveal { - m.status = fmt.Sprintf("Too many items to reveal (max %d, selected %d)", maxBatchReveal, count) + m.status = fmt.Sprintf("Too many items to reveal, max %d, selected %d", maxBatchReveal, count) return m, nil } for path := range m.multiSelected { @@ -860,7 +860,7 @@ func (m model) updateKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) { } } } - m.status = fmt.Sprintf("%d selected (%s)", count, humanizeBytes(totalSize)) + m.status = fmt.Sprintf("%d selected, %s", count, humanizeBytes(totalSize)) } else { m.status = fmt.Sprintf("Scanned %s", humanizeBytes(m.totalSize)) } @@ -886,7 +886,7 @@ func (m model) updateKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) { } } } - m.status = fmt.Sprintf("%d selected (%s)", count, humanizeBytes(totalSize)) + m.status = fmt.Sprintf("%d selected, %s", count, humanizeBytes(totalSize)) } else { m.status = fmt.Sprintf("Scanned %s", humanizeBytes(m.totalSize)) } @@ -1011,7 +1011,7 @@ func (m model) enterSelectedDir() (tea.Model, tea.Cmd) { } return m, tea.Batch(m.scanCmd(m.path), tickCmd()) } - m.status = fmt.Sprintf("File: %s (%s)", selected.Name, humanizeBytes(selected.Size)) + m.status = fmt.Sprintf("File: %s, %s", selected.Name, humanizeBytes(selected.Size)) return m, nil } diff --git a/cmd/analyze/scanner.go b/cmd/analyze/scanner.go index efd55b6..5a0cde3 100644 --- a/cmd/analyze/scanner.go +++ b/cmd/analyze/scanner.go @@ -594,7 +594,7 @@ func getDirectorySizeFromDuWithExclude(path string, excludePath string) (int64, return 0, fmt.Errorf("du timeout after %v", duTimeout) } if stderr.Len() > 0 { - return 0, fmt.Errorf("du failed: %v (%s)", err, stderr.String()) + return 0, fmt.Errorf("du failed: %v, %s", err, stderr.String()) } return 0, fmt.Errorf("du failed: %v", err) } diff --git a/cmd/analyze/view.go b/cmd/analyze/view.go index 726f1a9..5f82820 100644 --- a/cmd/analyze/view.go +++ b/cmd/analyze/view.go @@ -86,7 +86,7 @@ func (m model) View() string { if m.scanning && percent >= 100 { percent = 99 } - progressPrefix = fmt.Sprintf(" %s(%.0f%%)%s", colorCyan, percent, colorReset) + progressPrefix = fmt.Sprintf(" %s%.0f%%%s", colorCyan, percent, colorReset) } fmt.Fprintf(&b, "%s%s%s%s Scanning%s: %s%s files%s, %s%s dirs%s, %s%s%s\n", @@ -342,7 +342,7 @@ func (m model) View() string { } else if m.showLargeFiles { selectCount := len(m.largeMultiSelected) if selectCount > 0 { - fmt.Fprintf(&b, "%s↑↓← | Space Select | R Refresh | O Open | F File | ⌫ Del(%d) | ← Back | Q Quit%s\n", colorGray, selectCount, colorReset) + fmt.Fprintf(&b, "%s↑↓← | Space Select | R Refresh | O Open | F File | ⌫ Del %d | ← Back | Q Quit%s\n", colorGray, selectCount, colorReset) } else { fmt.Fprintf(&b, "%s↑↓← | Space Select | R Refresh | O Open | F File | ⌫ Del | ← Back | Q Quit%s\n", colorGray, colorReset) } @@ -351,13 +351,13 @@ func (m model) View() string { selectCount := len(m.multiSelected) if selectCount > 0 { if largeFileCount > 0 { - fmt.Fprintf(&b, "%s↑↓←→ | Space Select | Enter | R Refresh | O Open | F File | ⌫ Del(%d) | T Top(%d) | Q Quit%s\n", colorGray, selectCount, largeFileCount, colorReset) + fmt.Fprintf(&b, "%s↑↓←→ | Space Select | Enter | R Refresh | O Open | F File | ⌫ Del %d | T Top %d | Q Quit%s\n", colorGray, selectCount, largeFileCount, colorReset) } else { - fmt.Fprintf(&b, "%s↑↓←→ | Space Select | Enter | R Refresh | O Open | F File | ⌫ Del(%d) | Q Quit%s\n", colorGray, selectCount, colorReset) + fmt.Fprintf(&b, "%s↑↓←→ | Space Select | Enter | R Refresh | O Open | F File | ⌫ Del %d | Q Quit%s\n", colorGray, selectCount, colorReset) } } else { if largeFileCount > 0 { - fmt.Fprintf(&b, "%s↑↓←→ | Space Select | Enter | R Refresh | O Open | F File | ⌫ Del | T Top(%d) | Q Quit%s\n", colorGray, largeFileCount, colorReset) + fmt.Fprintf(&b, "%s↑↓←→ | Space Select | Enter | R Refresh | O Open | F File | ⌫ Del | T Top %d | Q Quit%s\n", colorGray, largeFileCount, colorReset) } else { fmt.Fprintf(&b, "%s↑↓←→ | Space Select | Enter | R Refresh | O Open | F File | ⌫ Del | Q Quit%s\n", colorGray, colorReset) } @@ -390,12 +390,12 @@ func (m model) View() string { } if deleteCount > 1 { - fmt.Fprintf(&b, "%sDelete:%s %d items (%s) %sPress Enter to confirm | ESC cancel%s\n", + fmt.Fprintf(&b, "%sDelete:%s %d items, %s %sPress Enter to confirm | ESC cancel%s\n", colorRed, colorReset, deleteCount, humanizeBytes(totalDeleteSize), colorGray, colorReset) } else { - fmt.Fprintf(&b, "%sDelete:%s %s (%s) %sPress Enter to confirm | ESC cancel%s\n", + fmt.Fprintf(&b, "%sDelete:%s %s, %s %sPress Enter to confirm | ESC cancel%s\n", colorRed, colorReset, m.deleteTarget.Name, humanizeBytes(m.deleteTarget.Size), colorGray, colorReset) diff --git a/cmd/status/view.go b/cmd/status/view.go index 010e11a..b66befd 100644 --- a/cmd/status/view.go +++ b/cmd/status/view.go @@ -145,7 +145,7 @@ func renderHeader(m MetricsSnapshot, errMsg string, animFrame int, termWidth int cpuInfo := m.Hardware.CPUModel // Append GPU core count when available. if len(m.GPU) > 0 && m.GPU[0].CoreCount > 0 { - cpuInfo += fmt.Sprintf(" (%dGPU)", m.GPU[0].CoreCount) + cpuInfo += fmt.Sprintf(", %dGPU", m.GPU[0].CoreCount) } infoParts = append(infoParts, cpuInfo) } @@ -218,7 +218,7 @@ func renderCPUCard(cpu CPUStatus, thermal ThermalStatus) cardData { lines = append(lines, fmt.Sprintf("Total %s %s", usageBar, headerText)) if cpu.PerCoreEstimated { - lines = append(lines, subtleStyle.Render("Per-core data unavailable (using averaged load)")) + lines = append(lines, subtleStyle.Render("Per-core data unavailable, using averaged load")) } else if len(cpu.PerCore) > 0 { type coreUsage struct { idx int @@ -239,10 +239,10 @@ func renderCPUCard(cpu CPUStatus, thermal ThermalStatus) cardData { // Load line at the end if cpu.PCoreCount > 0 && cpu.ECoreCount > 0 { - lines = append(lines, fmt.Sprintf("Load %.2f / %.2f / %.2f (%dP+%dE)", + lines = append(lines, fmt.Sprintf("Load %.2f / %.2f / %.2f, %dP+%dE", cpu.Load1, cpu.Load5, cpu.Load15, cpu.PCoreCount, cpu.ECoreCount)) } else { - lines = append(lines, fmt.Sprintf("Load %.2f / %.2f / %.2f (%d cores)", + lines = append(lines, fmt.Sprintf("Load %.2f / %.2f / %.2f, %d cores", cpu.Load1, cpu.Load5, cpu.Load15, cpu.LogicalCPU)) } @@ -270,7 +270,7 @@ func renderMemoryCard(mem MemoryStatus) cardData { if mem.SwapTotal > 0 { swapPercent = (float64(mem.SwapUsed) / float64(mem.SwapTotal)) * 100.0 } - swapText := fmt.Sprintf("(%s/%s)", humanBytesCompact(mem.SwapUsed), humanBytesCompact(mem.SwapTotal)) + swapText := fmt.Sprintf("%s/%s", humanBytesCompact(mem.SwapUsed), humanBytesCompact(mem.SwapTotal)) lines = append(lines, fmt.Sprintf("Swap %s %5.1f%% %s", progressBar(swapPercent), swapPercent, swapText)) lines = append(lines, fmt.Sprintf("Total %s / %s", humanBytes(mem.Used), humanBytes(mem.Total))) @@ -361,7 +361,7 @@ func formatDiskLine(label string, d DiskStatus) string { bar := progressBar(d.UsedPercent) used := humanBytesShort(d.Used) total := humanBytesShort(d.Total) - return fmt.Sprintf("%-6s %s %5.1f%% (%s/%s)", label, bar, d.UsedPercent, used, total) + return fmt.Sprintf("%-6s %s %5.1f%%, %s/%s", label, bar, d.UsedPercent, used, total) } func ioBar(rate float64) string { diff --git a/install.sh b/install.sh index b7d05be..6dc2cef 100755 --- a/install.sh +++ b/install.sh @@ -165,7 +165,7 @@ resolve_source_dir() { url="https://github.com/tw93/mole/archive/refs/tags/${branch}.tar.gz" fi - start_line_spinner "Fetching Mole source (${branch})..." + start_line_spinner "Fetching Mole source, ${branch}..." if command -v curl > /dev/null 2>&1; then if curl -fsSL --connect-timeout 10 --max-time 60 -o "$tmp/mole.tar.gz" "$url" 2> /dev/null; then if tar -xzf "$tmp/mole.tar.gz" -C "$tmp" 2> /dev/null; then @@ -509,7 +509,7 @@ download_binary() { log_success "Downloaded ${binary_name} binary" else if [[ -t 1 ]]; then stop_line_spinner; fi - log_warning "Could not download ${binary_name} binary (v${version}), trying local build" + log_warning "Could not download ${binary_name} binary, v${version}, trying local build" if build_binary_from_source "$binary_name" "$target_path"; then return 0 fi @@ -659,9 +659,9 @@ print_usage_summary() { local message="Mole ${action} successfully" if [[ "$action" == "updated" && -n "$previous_version" && -n "$new_version" && "$previous_version" != "$new_version" ]]; then - message+=" (${previous_version} -> ${new_version})" + message+=", ${previous_version} -> ${new_version}" elif [[ -n "$new_version" ]]; then - message+=" (version ${new_version})" + message+=", version ${new_version}" fi log_confirm "$message" @@ -763,7 +763,7 @@ perform_update() { fi if [[ "$installed_version" == "$target_version" ]]; then - echo -e "${GREEN}${ICON_SUCCESS}${NC} Already on latest version ($installed_version)" + echo -e "${GREEN}${ICON_SUCCESS}${NC} Already on latest version, $installed_version" exit 0 fi @@ -794,7 +794,7 @@ perform_update() { updated_version="$target_version" fi - echo -e "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version ($updated_version)" + echo -e "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version, $updated_version" } parse_args "$@" diff --git a/lib/clean/apps.sh b/lib/clean/apps.sh index 3511b78..f3e084b 100644 --- a/lib/clean/apps.sh +++ b/lib/clean/apps.sh @@ -46,9 +46,9 @@ clean_ds_store_tree() { local size_human size_human=$(bytes_to_human "$total_bytes") if [[ "$DRY_RUN" == "true" ]]; then - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} $label ${YELLOW}($file_count files, $size_human dry)${NC}" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} $label${NC}, ${YELLOW}$file_count files, $size_human dry${NC}" else - echo -e " ${GREEN}${ICON_SUCCESS}${NC} $label ${GREEN}($file_count files, $size_human)${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} $label${NC}, ${GREEN}$file_count files, $size_human${NC}" fi local size_kb=$(((total_bytes + 1023) / 1024)) ((files_cleaned += file_count)) @@ -70,7 +70,7 @@ scan_installed_apps() { current_time=$(get_epoch_seconds) local age=$((current_time - cache_mtime)) if [[ $age -lt $cache_age_seconds ]]; then - debug_log "Using cached app list (age: ${age}s)" + debug_log "Using cached app list, age: ${age}s" if [[ -r "$cache_file" ]] && [[ -s "$cache_file" ]]; then if cat "$cache_file" > "$installed_bundles" 2> /dev/null; then return 0 @@ -82,7 +82,7 @@ scan_installed_apps() { fi fi fi - debug_log "Scanning installed applications (cache expired or missing)" + debug_log "Scanning installed applications, cache expired or missing" local -a app_dirs=( "/Applications" "/System/Applications" @@ -310,7 +310,7 @@ clean_orphaned_app_data() { stop_section_spinner if [[ $orphaned_count -gt 0 ]]; then local orphaned_mb=$(echo "$total_orphaned_kb" | awk '{printf "%.1f", $1/1024}') - echo " ${GREEN}${ICON_SUCCESS}${NC} Cleaned $orphaned_count items (~${orphaned_mb}MB)" + echo " ${GREEN}${ICON_SUCCESS}${NC} Cleaned $orphaned_count items, about ${orphaned_mb}MB" note_activity fi rm -f "$installed_bundles" @@ -512,7 +512,7 @@ clean_orphaned_system_services() { else orphaned_kb_display="${total_orphaned_kb}KB" fi - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Cleaned $orphaned_count orphaned services (~$orphaned_kb_display)" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Cleaned $orphaned_count orphaned services, about $orphaned_kb_display" note_activity fi diff --git a/lib/clean/brew.sh b/lib/clean/brew.sh index 9939cb0..6ccf2d6 100644 --- a/lib/clean/brew.sh +++ b/lib/clean/brew.sh @@ -86,9 +86,9 @@ clean_homebrew() { freed_space=$(printf '%s\n' "$brew_output" | grep -o "[0-9.]*[KMGT]B freed" 2> /dev/null | tail -1 || true) if [[ $removed_count -gt 0 ]] || [[ -n "$freed_space" ]]; then if [[ -n "$freed_space" ]]; then - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Homebrew cleanup ${GREEN}($freed_space)${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Homebrew cleanup${NC}, ${GREEN}$freed_space${NC}" else - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Homebrew cleanup (${removed_count} items)" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Homebrew cleanup, ${removed_count} items" fi fi elif [[ $brew_exit -eq 124 ]]; then @@ -102,7 +102,7 @@ clean_homebrew() { local removed_packages removed_packages=$(printf '%s\n' "$autoremove_output" | grep -c "^Uninstalling" 2> /dev/null || true) if [[ $removed_packages -gt 0 ]]; then - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Removed orphaned dependencies (${removed_packages} packages)" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Removed orphaned dependencies, ${removed_packages} packages" fi elif [[ $autoremove_exit -eq 124 ]]; then echo -e " ${GRAY}${ICON_WARNING}${NC} Autoremove timed out · run ${GRAY}brew autoremove${NC} manually" diff --git a/lib/clean/caches.sh b/lib/clean/caches.sh index 2fdfe87..b5ecdcf 100644 --- a/lib/clean/caches.sh +++ b/lib/clean/caches.sh @@ -22,7 +22,7 @@ check_tcc_permissions() { echo "" echo -e "${BLUE}First-time setup${NC}" echo -e "${GRAY}macOS will request permissions to access Library folders.${NC}" - echo -e "${GRAY}You may see ${GREEN}${#tcc_dirs[@]} permission dialogs${NC}${GRAY} - please approve them all.${NC}" + echo -e "${GRAY}You may see ${GREEN}${#tcc_dirs[@]} permission dialogs${NC}${GRAY}, please approve them all.${NC}" echo "" echo -ne "${PURPLE}${ICON_ARROW}${NC} Press ${GREEN}Enter${NC} to continue: " read -r @@ -75,12 +75,12 @@ clean_service_worker_cache() { local cleaned_mb=$((cleaned_size / 1024)) if [[ "$DRY_RUN" != "true" ]]; then if [[ $protected_count -gt 0 ]]; then - echo -e " ${GREEN}${ICON_SUCCESS}${NC} $browser_name Service Worker (${cleaned_mb}MB, ${protected_count} protected)" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} $browser_name Service Worker, ${cleaned_mb}MB, ${protected_count} protected" else - echo -e " ${GREEN}${ICON_SUCCESS}${NC} $browser_name Service Worker (${cleaned_mb}MB)" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} $browser_name Service Worker, ${cleaned_mb}MB" fi else - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} $browser_name Service Worker (would clean ${cleaned_mb}MB, ${protected_count} protected)" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} $browser_name Service Worker, would clean ${cleaned_mb}MB, ${protected_count} protected" fi note_activity if [[ "$spinner_was_running" == "true" ]]; then diff --git a/lib/clean/project.sh b/lib/clean/project.sh index a34e49c..e1ffa25 100644 --- a/lib/clean/project.sh +++ b/lib/clean/project.sh @@ -606,7 +606,7 @@ select_purge_categories() { fi printf "%s\n" "$clear_line" - printf "%s${PURPLE_BOLD}Select Categories to Clean${NC}%s ${GRAY}- ${selected_gb}GB ($selected_count selected)${NC}\n" "$clear_line" "$scroll_indicator" + printf "%s${PURPLE_BOLD}Select Categories to Clean${NC}%s ${GRAY}, ${selected_gb}GB, ${selected_count} selected${NC}\n" "$clear_line" "$scroll_indicator" printf "%s\n" "$clear_line" IFS=',' read -r -a recent_flags <<< "${PURGE_RECENT_CATEGORIES:-}" @@ -1135,7 +1135,7 @@ clean_project_artifacts() { fi if [[ -t 1 ]]; then stop_inline_spinner - echo -e "${GREEN}${ICON_SUCCESS}${NC} $project_path - $artifact_type ${GREEN}($size_human)${NC}" + echo -e "${GREEN}${ICON_SUCCESS}${NC} $project_path, $artifact_type${NC}, ${GREEN}$size_human${NC}" fi done # Update count diff --git a/lib/clean/system.sh b/lib/clean/system.sh index f06dd0c..e3d282e 100644 --- a/lib/clean/system.sh +++ b/lib/clean/system.sh @@ -39,18 +39,18 @@ clean_deep_system() { if [[ -d "/macOS Install Data" ]]; then local mtime=$(get_file_mtime "/macOS Install Data") local age_days=$((($(get_epoch_seconds) - mtime) / 86400)) - debug_log "Found macOS Install Data (age: ${age_days} days)" + debug_log "Found macOS Install Data, age ${age_days} days" if [[ $age_days -ge 30 ]]; then local size_kb=$(get_path_size_kb "/macOS Install Data") if [[ -n "$size_kb" && "$size_kb" -gt 0 ]]; then local size_human=$(bytes_to_human "$((size_kb * 1024))") - debug_log "Cleaning macOS Install Data: $size_human (${age_days} days old)" + debug_log "Cleaning macOS Install Data: $size_human, ${age_days} days old" if safe_sudo_remove "/macOS Install Data"; then - log_success "macOS Install Data ($size_human)" + log_success "macOS Install Data, $size_human" fi fi else - debug_log "Keeping macOS Install Data (only ${age_days} days old, needs 30+)" + debug_log "Keeping macOS Install Data, only ${age_days} days old, needs 30+" fi fi start_section_spinner "Scanning system caches..." @@ -70,13 +70,13 @@ clean_deep_system() { local current_time current_time=$(get_epoch_seconds) if [[ $((current_time - last_update_time)) -ge $update_interval ]]; then - start_section_spinner "Scanning system caches... ($found_count found)" + start_section_spinner "Scanning system caches... $found_count found" last_update_time=$current_time fi fi done < <(run_with_timeout 5 command find /private/var/folders -type d -name "*.code_sign_clone" -path "*/X/*" -print0 2> /dev/null || true) stop_section_spinner - [[ $code_sign_cleaned -gt 0 ]] && log_success "Browser code signature caches ($code_sign_cleaned items)" + [[ $code_sign_cleaned -gt 0 ]] && log_success "Browser code signature caches, $code_sign_cleaned items" start_section_spinner "Cleaning system diagnostic logs..." local diag_cleaned=0 @@ -178,7 +178,7 @@ clean_time_machine_failed_backups() { local backup_name=$(basename "$inprogress_file") local size_human=$(bytes_to_human "$((size_kb * 1024))") if [[ "$DRY_RUN" == "true" ]]; then - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Incomplete backup: $backup_name ${YELLOW}($size_human dry)${NC}" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Incomplete backup: $backup_name${NC}, ${YELLOW}$size_human dry${NC}" ((tm_cleaned++)) note_activity continue @@ -188,7 +188,7 @@ clean_time_machine_failed_backups() { continue fi if tmutil delete "$inprogress_file" 2> /dev/null; then - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Incomplete backup: $backup_name ${GREEN}($size_human)${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Incomplete backup: $backup_name${NC}, ${GREEN}$size_human${NC}" ((tm_cleaned++)) ((files_cleaned++)) ((total_size_cleaned += size_kb)) @@ -224,7 +224,7 @@ clean_time_machine_failed_backups() { local backup_name=$(basename "$inprogress_file") local size_human=$(bytes_to_human "$((size_kb * 1024))") if [[ "$DRY_RUN" == "true" ]]; then - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Incomplete APFS backup in $bundle_name: $backup_name ${YELLOW}($size_human dry)${NC}" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Incomplete APFS backup in $bundle_name: $backup_name${NC}, ${YELLOW}$size_human dry${NC}" ((tm_cleaned++)) note_activity continue @@ -233,7 +233,7 @@ clean_time_machine_failed_backups() { continue fi if tmutil delete "$inprogress_file" 2> /dev/null; then - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Incomplete APFS backup in $bundle_name: $backup_name ${GREEN}($size_human)${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Incomplete APFS backup in $bundle_name: $backup_name${NC}, ${GREEN}$size_human${NC}" ((tm_cleaned++)) ((files_cleaned++)) ((total_size_cleaned += size_kb)) diff --git a/lib/clean/user.sh b/lib/clean/user.sh index ca78f66..591bf19 100644 --- a/lib/clean/user.sh +++ b/lib/clean/user.sh @@ -14,10 +14,10 @@ clean_user_essentials() { [[ "$trash_count" =~ ^[0-9]+$ ]] || trash_count="0" if [[ "$DRY_RUN" == "true" ]]; then - [[ $trash_count -gt 0 ]] && echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Trash · would empty ($trash_count items)" || echo -e " ${GRAY}${ICON_EMPTY}${NC} Trash · already empty" + [[ $trash_count -gt 0 ]] && echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Trash · would empty, $trash_count items" || echo -e " ${GRAY}${ICON_EMPTY}${NC} Trash · already empty" elif [[ $trash_count -gt 0 ]]; then if osascript -e 'tell application "Finder" to empty trash' > /dev/null 2>&1; then - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Trash · emptied ($trash_count items)" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Trash · emptied, $trash_count items" note_activity else safe_clean ~/.Trash/* "Trash" @@ -97,9 +97,9 @@ clean_chrome_old_versions() { local size_human size_human=$(bytes_to_human "$((total_size * 1024))") if [[ "$DRY_RUN" == "true" ]]; then - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Chrome old versions ${YELLOW}(${cleaned_count} dirs, $size_human dry)${NC}" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Chrome old versions${NC}, ${YELLOW}${cleaned_count} dirs, $size_human dry${NC}" else - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Chrome old versions ${GREEN}(${cleaned_count} dirs, $size_human)${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Chrome old versions${NC}, ${GREEN}${cleaned_count} dirs, $size_human${NC}" fi ((files_cleaned += cleaned_count)) ((total_size_cleaned += total_size)) @@ -183,9 +183,9 @@ clean_edge_old_versions() { local size_human size_human=$(bytes_to_human "$((total_size * 1024))") if [[ "$DRY_RUN" == "true" ]]; then - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Edge old versions ${YELLOW}(${cleaned_count} dirs, $size_human dry)${NC}" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Edge old versions${NC}, ${YELLOW}${cleaned_count} dirs, $size_human dry${NC}" else - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Edge old versions ${GREEN}(${cleaned_count} dirs, $size_human)${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Edge old versions${NC}, ${GREEN}${cleaned_count} dirs, $size_human${NC}" fi ((files_cleaned += cleaned_count)) ((total_size_cleaned += total_size)) @@ -245,9 +245,9 @@ clean_edge_updater_old_versions() { local size_human size_human=$(bytes_to_human "$((total_size * 1024))") if [[ "$DRY_RUN" == "true" ]]; then - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Edge updater old versions ${YELLOW}(${cleaned_count} dirs, $size_human dry)${NC}" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Edge updater old versions${NC}, ${YELLOW}${cleaned_count} dirs, $size_human dry${NC}" else - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Edge updater old versions ${GREEN}(${cleaned_count} dirs, $size_human)${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Edge updater old versions${NC}, ${GREEN}${cleaned_count} dirs, $size_human${NC}" fi ((files_cleaned += cleaned_count)) ((total_size_cleaned += total_size)) @@ -285,12 +285,12 @@ scan_external_volumes() { local network_count=${#network_volumes[@]} if [[ $volume_count -eq 0 ]]; then if [[ $network_count -gt 0 ]]; then - echo -e " ${GRAY}${ICON_LIST}${NC} External volumes (${network_count} network volume(s) skipped)" + echo -e " ${GRAY}${ICON_LIST}${NC} External volumes, ${network_count} network volumes skipped" note_activity fi return 0 fi - start_section_spinner "Scanning $volume_count external volume(s)..." + start_section_spinner "Scanning $volume_count external volumes..." for volume in "${candidate_volumes[@]}"; do [[ -d "$volume" && -r "$volume" ]] || continue local volume_trash="$volume/.Trashes" @@ -300,7 +300,7 @@ scan_external_volumes() { done < <(command find "$volume_trash" -mindepth 1 -maxdepth 1 -print0 2> /dev/null || true) fi if [[ "$PROTECT_FINDER_METADATA" != "true" ]]; then - clean_ds_store_tree "$volume" "$(basename "$volume") volume (.DS_Store)" + clean_ds_store_tree "$volume" "$(basename "$volume") volume, .DS_Store" fi done stop_section_spinner @@ -310,7 +310,7 @@ clean_finder_metadata() { if [[ "$PROTECT_FINDER_METADATA" == "true" ]]; then return fi - clean_ds_store_tree "$HOME" "Home directory (.DS_Store)" + clean_ds_store_tree "$HOME" "Home directory, .DS_Store" } # macOS system caches and user-level leftovers. clean_macos_system_caches() { @@ -389,7 +389,7 @@ clean_mail_downloads() { done if [[ $count -gt 0 ]]; then local cleaned_mb=$(echo "$cleaned_kb" | awk '{printf "%.1f", $1/1024}' || echo "0.0") - echo " ${GREEN}${ICON_SUCCESS}${NC} Cleaned $count mail attachments (~${cleaned_mb}MB)" + echo " ${GREEN}${ICON_SUCCESS}${NC} Cleaned $count mail attachments, about ${cleaned_mb}MB" note_activity fi } @@ -418,9 +418,9 @@ clean_sandboxed_app_caches() { if [[ "$found_any" == "true" ]]; then local size_human=$(bytes_to_human "$((total_size * 1024))") if [[ "$DRY_RUN" == "true" ]]; then - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Sandboxed app caches ${YELLOW}($size_human dry)${NC}" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Sandboxed app caches${NC}, ${YELLOW}$size_human dry${NC}" else - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Sandboxed app caches ${GREEN}($size_human)${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Sandboxed app caches${NC}, ${GREEN}$size_human${NC}" fi ((files_cleaned += cleaned_count)) ((total_size_cleaned += total_size)) @@ -603,9 +603,9 @@ clean_application_support_logs() { if [[ "$found_any" == "true" ]]; then local size_human=$(bytes_to_human "$((total_size * 1024))") if [[ "$DRY_RUN" == "true" ]]; then - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Application Support logs/caches ${YELLOW}($size_human dry)${NC}" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Application Support logs/caches${NC}, ${YELLOW}$size_human dry${NC}" else - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Application Support logs/caches ${GREEN}($size_human)${NC}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Application Support logs/caches${NC}, ${GREEN}$size_human${NC}" fi ((files_cleaned += cleaned_count)) ((total_size_cleaned += total_size)) diff --git a/lib/core/base.sh b/lib/core/base.sh index 92ae743..3c9e4c0 100644 --- a/lib/core/base.sh +++ b/lib/core/base.sh @@ -687,7 +687,7 @@ update_progress_if_needed() { if [[ $((current_time - last_time)) -ge $interval ]]; then # Update the spinner with progress stop_section_spinner - start_section_spinner "Scanning items... ($completed/$total)" + start_section_spinner "Scanning items... $completed/$total" # Update the last_update_time variable eval "$last_update_var=$current_time" @@ -717,7 +717,7 @@ push_spinner_state() { fi MOLE_SPINNER_STACK+=("$current_state") - debug_log "Pushed spinner state: $current_state (stack depth: ${#MOLE_SPINNER_STACK[@]})" + debug_log "Pushed spinner state: $current_state, stack depth: ${#MOLE_SPINNER_STACK[@]}" } # Pop and restore spinner state from stack @@ -730,7 +730,7 @@ pop_spinner_state() { # Stack depth safety check if [[ ${#MOLE_SPINNER_STACK[@]} -gt 10 ]]; then - debug_log "Warning: Spinner stack depth excessive (${#MOLE_SPINNER_STACK[@]}), possible leak" + debug_log "Warning: Spinner stack depth excessive, ${#MOLE_SPINNER_STACK[@]}, possible leak" fi local last_idx=$((${#MOLE_SPINNER_STACK[@]} - 1)) @@ -745,7 +745,7 @@ pop_spinner_state() { done MOLE_SPINNER_STACK=("${new_stack[@]}") - debug_log "Popped spinner state: $state (remaining depth: ${#MOLE_SPINNER_STACK[@]})" + debug_log "Popped spinner state: $state, remaining depth: ${#MOLE_SPINNER_STACK[@]}" # Restore state if needed if [[ "$state" == running:* ]]; then @@ -822,7 +822,7 @@ get_terminal_info() { local info="Terminal: ${TERM:-unknown}" if is_ansi_supported; then - info+=" (ANSI supported)" + info+=", ANSI supported" if command -v tput > /dev/null 2>&1; then local cols=$(tput cols 2> /dev/null || echo "?") @@ -831,7 +831,7 @@ get_terminal_info() { info+=" ${cols}x${lines}, ${colors} colors" fi else - info+=" (ANSI not supported)" + info+=", ANSI not supported" fi echo "$info" @@ -852,11 +852,11 @@ validate_terminal_environment() { # Check if running in a known problematic terminal case "${TERM:-}" in dumb) - log_warning "Running in 'dumb' terminal - limited functionality" + log_warning "Running in 'dumb' terminal, limited functionality" ((warnings++)) ;; unknown) - log_warning "Terminal type unknown - may have display issues" + log_warning "Terminal type unknown, may have display issues" ((warnings++)) ;; esac @@ -865,7 +865,7 @@ validate_terminal_environment() { if command -v tput > /dev/null 2>&1; then local cols=$(tput cols 2> /dev/null || echo "80") if [[ "$cols" -lt 60 ]]; then - log_warning "Terminal width ($cols cols) is narrow - output may wrap" + log_warning "Terminal width, $cols cols, is narrow, output may wrap" ((warnings++)) fi fi diff --git a/lib/core/common.sh b/lib/core/common.sh index 75da002..488f7f2 100755 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -81,7 +81,7 @@ update_via_homebrew() { installed_version=$(brew list --versions mole 2> /dev/null | awk '{print $2}') [[ -z "$installed_version" ]] && installed_version=$(mo --version 2> /dev/null | awk '/Mole version/ {print $3; exit}') echo "" - echo -e "${GREEN}${ICON_SUCCESS}${NC} Already on latest version (${installed_version:-$current_version})" + echo -e "${GREEN}${ICON_SUCCESS}${NC} Already on latest version, ${installed_version:-$current_version}" echo "" elif echo "$upgrade_output" | grep -q "Error:"; then log_error "Homebrew upgrade failed" @@ -93,7 +93,7 @@ update_via_homebrew() { new_version=$(brew list --versions mole 2> /dev/null | awk '{print $2}') [[ -z "$new_version" ]] && new_version=$(mo --version 2> /dev/null | awk '/Mole version/ {print $3; exit}') echo "" - echo -e "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version (${new_version:-$current_version})" + echo -e "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version, ${new_version:-$current_version}" echo "" fi diff --git a/lib/core/file_ops.sh b/lib/core/file_ops.sh index 24075ec..ccff245 100644 --- a/lib/core/file_ops.sh +++ b/lib/core/file_ops.sh @@ -211,7 +211,7 @@ safe_remove() { MOLE_PERMISSION_DENIED_COUNT=${MOLE_PERMISSION_DENIED_COUNT:-0} MOLE_PERMISSION_DENIED_COUNT=$((MOLE_PERMISSION_DENIED_COUNT + 1)) export MOLE_PERMISSION_DENIED_COUNT - debug_log "Permission denied: $path (may need Full Disk Access)" + debug_log "Permission denied: $path, may need Full Disk Access" else [[ "$silent" != "true" ]] && log_error "Failed to remove: $path" fi @@ -267,20 +267,20 @@ safe_sudo_remove() { fi fi - debug_file_action "[DRY RUN] Would remove (sudo)" "$path" "$file_size" "$file_age" + debug_file_action "[DRY RUN] Would remove, sudo" "$path" "$file_size" "$file_age" else - debug_log "[DRY RUN] Would remove (sudo): $path" + debug_log "[DRY RUN] Would remove, sudo: $path" fi return 0 fi - debug_log "Removing (sudo): $path" + debug_log "Removing, sudo: $path" # Perform the deletion if sudo rm -rf "$path" 2> /dev/null; then # SAFE: safe_sudo_remove implementation return 0 else - log_error "Failed to remove (sudo): $path" + log_error "Failed to remove, sudo: $path" return 1 fi } @@ -309,11 +309,11 @@ safe_find_delete() { # Validate type filter if [[ "$type_filter" != "f" && "$type_filter" != "d" ]]; then - log_error "Invalid type filter: $type_filter (must be 'f' or 'd')" + log_error "Invalid type filter: $type_filter, must be 'f' or 'd'" return 1 fi - debug_log "Finding in $base_dir: $pattern (age: ${age_days}d, type: $type_filter)" + debug_log "Finding in $base_dir: $pattern, age: ${age_days}d, type: $type_filter" local find_args=("-maxdepth" "5" "-name" "$pattern" "-type" "$type_filter") if [[ "$age_days" -gt 0 ]]; then @@ -340,7 +340,7 @@ safe_sudo_find_delete() { # Validate base directory (use sudo for permission-restricted dirs) if ! sudo test -d "$base_dir" 2> /dev/null; then - debug_log "Directory does not exist (skipping): $base_dir" + debug_log "Directory does not exist, skipping: $base_dir" return 0 fi @@ -351,11 +351,11 @@ safe_sudo_find_delete() { # Validate type filter if [[ "$type_filter" != "f" && "$type_filter" != "d" ]]; then - log_error "Invalid type filter: $type_filter (must be 'f' or 'd')" + log_error "Invalid type filter: $type_filter, must be 'f' or 'd'" return 1 fi - debug_log "Finding (sudo) in $base_dir: $pattern (age: ${age_days}d, type: $type_filter)" + debug_log "Finding, sudo, in $base_dir: $pattern, age: ${age_days}d, type: $type_filter" local find_args=("-maxdepth" "5" "-name" "$pattern" "-type" "$type_filter") if [[ "$age_days" -gt 0 ]]; then diff --git a/lib/core/log.sh b/lib/core/log.sh index 124ee7b..8d7f085 100644 --- a/lib/core/log.sh +++ b/lib/core/log.sh @@ -138,10 +138,9 @@ debug_file_action() { local file_age="${4:-}" if [[ "${MO_DEBUG:-}" == "1" ]]; then - local msg=" - $file_path" - [[ -n "$file_size" ]] && msg+=" ($file_size" + local msg=" * $file_path" + [[ -n "$file_size" ]] && msg+=", $file_size" [[ -n "$file_age" ]] && msg+=", ${file_age} days old" - [[ -n "$file_size" ]] && msg+=")" # Output to stderr echo -e "${GRAY}[DEBUG] $action: $msg${NC}" >&2 @@ -165,10 +164,10 @@ debug_risk_level() { esac # Output to stderr with color - echo -e "${GRAY}[DEBUG] Risk Level: ${color}${risk_level}${GRAY} ($reason)${NC}" >&2 + echo -e "${GRAY}[DEBUG] Risk Level: ${color}${risk_level}${GRAY}, $reason${NC}" >&2 # Also log to file - echo "Risk Level: $risk_level ($reason)" >> "$DEBUG_LOG_FILE" 2> /dev/null || true + echo "Risk Level: $risk_level, $reason" >> "$DEBUG_LOG_FILE" 2> /dev/null || true fi } @@ -187,16 +186,16 @@ log_system_info() { # Start block in debug log file { echo "----------------------------------------------------------------------" - echo "Mole Debug Session - $(date '+%Y-%m-%d %H:%M:%S')" + echo "Mole Debug Session, $(date '+%Y-%m-%d %H:%M:%S')" echo "----------------------------------------------------------------------" echo "User: $USER" echo "Hostname: $(hostname)" echo "Architecture: $(uname -m)" echo "Kernel: $(uname -r)" if command -v sw_vers > /dev/null; then - echo "macOS: $(sw_vers -productVersion) ($(sw_vers -buildVersion))" + echo "macOS: $(sw_vers -productVersion), $(sw_vers -buildVersion)" fi - echo "Shell: ${SHELL:-unknown} (${TERM:-unknown})" + echo "Shell: ${SHELL:-unknown}, ${TERM:-unknown}" # Check sudo status non-interactively if sudo -n true 2> /dev/null; then diff --git a/lib/core/sudo.sh b/lib/core/sudo.sh index 5431db3..d7de287 100644 --- a/lib/core/sudo.sh +++ b/lib/core/sudo.sh @@ -60,7 +60,7 @@ _request_password() { # Show hint on first attempt about Touch ID appearing again if [[ $show_hint == true ]] && check_touchid_support; then - echo -e "${GRAY}Note: Touch ID dialog may appear once more - just cancel it${NC}" > "$tty_path" + echo -e "${GRAY}Note: Touch ID dialog may appear once more, just cancel it${NC}" > "$tty_path" show_hint=false fi @@ -143,7 +143,7 @@ request_sudo_access() { fi # Touch ID is available and not in clamshell mode - echo -e "${PURPLE}${ICON_ARROW}${NC} ${prompt_msg} ${GRAY}(Touch ID or password)${NC}" + echo -e "${PURPLE}${ICON_ARROW}${NC} ${prompt_msg} ${GRAY}, Touch ID or password${NC}" # Start sudo in background so we can monitor and control it sudo -v < /dev/null > /dev/null 2>&1 & diff --git a/lib/core/timeout.sh b/lib/core/timeout.sh index 5ff9576..ae9779a 100644 --- a/lib/core/timeout.sh +++ b/lib/core/timeout.sh @@ -100,7 +100,7 @@ run_with_timeout() { # ======================================================================== if [[ "${MO_DEBUG:-0}" == "1" ]]; then - echo "[TIMEOUT] Shell fallback (${duration}s): $*" >&2 + echo "[TIMEOUT] Shell fallback, ${duration}s: $*" >&2 fi # Start command in background diff --git a/lib/manage/purge_paths.sh b/lib/manage/purge_paths.sh index bd163bd..0fddca2 100644 --- a/lib/manage/purge_paths.sh +++ b/lib/manage/purge_paths.sh @@ -58,7 +58,7 @@ manage_purge_paths() { if [[ -d "$path" ]]; then echo -e " ${GREEN}✓${NC} $display_path" else - echo -e " ${GRAY}○${NC} $display_path ${GRAY}(not found)${NC}" + echo -e " ${GRAY}○${NC} $display_path${GRAY}, not found${NC}" fi done fi @@ -76,7 +76,7 @@ manage_purge_paths() { echo "" if [[ $custom_count -gt 0 ]]; then - echo -e "${GRAY}Using custom config with $custom_count path(s)${NC}" + echo -e "${GRAY}Using custom config with $custom_count paths${NC}" else echo -e "${GRAY}Using ${#DEFAULT_PURGE_SEARCH_PATHS[@]} default paths${NC}" fi diff --git a/lib/manage/update.sh b/lib/manage/update.sh index b700f31..07cfb57 100644 --- a/lib/manage/update.sh +++ b/lib/manage/update.sh @@ -18,14 +18,14 @@ format_brew_update_label() { ((formulas > 0)) && details+=("${formulas} formula") ((casks > 0)) && details+=("${casks} cask") - local detail_str="(${total} updates)" + local detail_str=", ${total} updates" if ((${#details[@]} > 0)); then - detail_str="($( + detail_str=", $( IFS=', ' printf '%s' "${details[*]}" - ))" + )" fi - printf " • Homebrew %s" "$detail_str" + printf " • Homebrew%s" "$detail_str" } brew_has_outdated() { @@ -54,7 +54,7 @@ ask_for_updates() { if [[ -n "${APPSTORE_UPDATE_COUNT:-}" && "${APPSTORE_UPDATE_COUNT:-0}" -gt 0 ]]; then has_updates=true - update_list+=(" • App Store (${APPSTORE_UPDATE_COUNT} apps)") + update_list+=(" • App Store, ${APPSTORE_UPDATE_COUNT} apps") fi if [[ -n "${MACOS_UPDATE_AVAILABLE:-}" && "${MACOS_UPDATE_AVAILABLE}" == "true" ]]; then @@ -132,10 +132,10 @@ perform_updates() { echo -e "${GRAY}No updates to perform${NC}" return 0 elif [[ $updated_count -eq $total_count ]]; then - echo -e "${GREEN}All updates completed (${updated_count}/${total_count})${NC}" + echo -e "${GREEN}All updates completed, ${updated_count}/${total_count}${NC}" return 0 else - echo -e "${RED}Update failed (${updated_count}/${total_count})${NC}" + echo -e "${RED}Update failed, ${updated_count}/${total_count}${NC}" return 1 fi } diff --git a/lib/manage/whitelist.sh b/lib/manage/whitelist.sh index 23f5d91..e322b6f 100755 --- a/lib/manage/whitelist.sh +++ b/lib/manage/whitelist.sh @@ -148,7 +148,7 @@ CloudKit cache|$HOME/Library/Caches/CloudKit/*|system_cache Trash|$HOME/.Trash|system_cache EOF # Add FINDER_METADATA with constant reference - echo "Finder metadata (.DS_Store)|$FINDER_METADATA_SENTINEL|system_cache" + echo "Finder metadata, .DS_Store|$FINDER_METADATA_SENTINEL|system_cache" } # Get all optimize items with their patterns @@ -284,13 +284,13 @@ manage_whitelist_categories() { items_source=$(get_optimize_whitelist_items) active_config_file="$WHITELIST_CONFIG_OPTIMIZE" local display_config="${active_config_file/#$HOME/~}" - menu_title="Whitelist Manager – Select system checks to ignore + menu_title="Whitelist Manager, Select system checks to ignore ${GRAY}Edit: ${display_config}${NC}" else items_source=$(get_all_cache_items) active_config_file="$WHITELIST_CONFIG_CLEAN" local display_config="${active_config_file/#$HOME/~}" - menu_title="Whitelist Manager – Select caches to protect + menu_title="Whitelist Manager, Select caches to protect ${GRAY}Edit: ${display_config}${NC}" fi @@ -416,7 +416,7 @@ ${GRAY}Edit: ${display_config}${NC}" if [[ ${#custom_patterns[@]} -gt 0 ]]; then summary_lines+=("Protected ${#selected_patterns[@]} predefined + ${#custom_patterns[@]} custom patterns") else - summary_lines+=("Protected ${total_protected} cache(s)") + summary_lines+=("Protected ${total_protected} caches") fi local display_config="${active_config_file/#$HOME/~}" summary_lines+=("Config: ${GRAY}${display_config}${NC}") diff --git a/lib/optimize/tasks.sh b/lib/optimize/tasks.sh index 042e0f2..ea0a1fa 100644 --- a/lib/optimize/tasks.sh +++ b/lib/optimize/tasks.sh @@ -263,7 +263,7 @@ opt_sqlite_vacuum() { fi if ! command -v sqlite3 > /dev/null 2>&1; then - echo -e " ${GRAY}-${NC} Database optimization already optimal (sqlite3 unavailable)" + echo -e " ${GRAY}-${NC} Database optimization already optimal, sqlite3 unavailable" return 0 fi @@ -584,7 +584,7 @@ opt_disk_permissions_repair() { opt_msg "User directory permissions repaired" opt_msg "File access issues resolved" else - echo -e " ${YELLOW}!${NC} Failed to repair permissions (may not be needed)" + echo -e " ${YELLOW}!${NC} Failed to repair permissions, may not be needed" fi else opt_msg "User directory permissions repaired" @@ -705,7 +705,7 @@ opt_spotlight_index_optimize() { fi if [[ "${MOLE_DRY_RUN:-0}" != "1" ]]; then - echo -e " ${BLUE}ℹ${NC} Spotlight search is slow, rebuilding index (may take 1-2 hours)" + echo -e " ${BLUE}ℹ${NC} Spotlight search is slow, rebuilding index, may take 1-2 hours" if sudo mdutil -E / > /dev/null 2>&1; then opt_msg "Spotlight index rebuild started" echo -e " ${GRAY}Indexing will continue in background${NC}" diff --git a/lib/uninstall/batch.sh b/lib/uninstall/batch.sh index 85cc952..2bbc2df 100755 --- a/lib/uninstall/batch.sh +++ b/lib/uninstall/batch.sh @@ -307,7 +307,7 @@ batch_uninstall_applications() { local brew_tag="" [[ "$is_brew_cask" == "true" ]] && brew_tag=" ${CYAN}[Brew]${NC}" - echo -e "${BLUE}${ICON_CONFIRM}${NC} ${app_name}${brew_tag} ${GRAY}(${app_size_display})${NC}" + echo -e "${BLUE}${ICON_CONFIRM}${NC} ${app_name}${brew_tag} ${GRAY}, ${app_size_display}${NC}" # Show detailed file list for ALL apps (brew casks leave user data behind) local related_files=$(decode_file_list "$encoded_files" "$app_name") @@ -352,7 +352,7 @@ batch_uninstall_applications() { echo "" local removal_note="Remove ${app_total} ${app_text}" - [[ -n "$size_display" ]] && removal_note+=" (${size_display})" + [[ -n "$size_display" ]] && removal_note+=", ${size_display}" if [[ ${#running_apps[@]} -gt 0 ]]; then removal_note+=" ${YELLOW}[Running]${NC}" fi @@ -516,7 +516,7 @@ batch_uninstall_applications() { # Show failure if [[ -t 1 ]]; then if [[ ${#app_details[@]} -gt 1 ]]; then - echo -e "${ICON_ERROR} [$current_index/${#app_details[@]}] ${app_name} ${GRAY}($reason)${NC}" + echo -e "${ICON_ERROR} [$current_index/${#app_details[@]}] ${app_name} ${GRAY}, $reason${NC}" else echo -e "${ICON_ERROR} ${app_name} failed: $reason" fi @@ -592,7 +592,7 @@ batch_uninstall_applications() { still*running*) reason_summary="is still running" ;; remove*failed*) reason_summary="could not be removed" ;; permission*denied*) reason_summary="permission denied" ;; - owned*by*) reason_summary="$first_reason (try with sudo)" ;; + owned*by*) reason_summary="$first_reason, try with sudo" ;; *) reason_summary="$first_reason" ;; esac fi diff --git a/mole b/mole index f8ae12c..8761cb1 100755 --- a/mole +++ b/mole @@ -247,14 +247,14 @@ update_mole() { if [[ -z "$latest" ]]; then log_error "Unable to check for updates. Check network connection." - echo -e "${YELLOW}Tip:${NC} Check if you can access GitHub (https://github.com)" + echo -e "${YELLOW}Tip:${NC} Check if you can access GitHub, https://github.com" echo -e "${YELLOW}Tip:${NC} Try again with: ${GRAY}mo update${NC}" exit 1 fi if [[ "$VERSION" == "$latest" && "$force_update" != "true" ]]; then echo "" - echo -e "${GREEN}${ICON_SUCCESS}${NC} Already on latest version (${VERSION})" + echo -e "${GREEN}${ICON_SUCCESS}${NC} Already on latest version, ${VERSION}" echo "" exit 0 fi @@ -278,7 +278,7 @@ update_mole() { local curl_exit=$? if [[ -t 1 ]]; then stop_inline_spinner; fi rm -f "$tmp_installer" - log_error "Update failed (curl error: $curl_exit)" + log_error "Update failed, curl error: $curl_exit" case $curl_exit in 6) echo -e "${YELLOW}Tip:${NC} Could not resolve host. Check DNS or network connection." ;; @@ -294,7 +294,7 @@ update_mole() { download_error=$(wget --timeout=10 --tries=3 -qO "$tmp_installer" "$installer_url" 2>&1) || { if [[ -t 1 ]]; then stop_inline_spinner; fi rm -f "$tmp_installer" - log_error "Update failed (wget error)" + log_error "Update failed, wget error" echo -e "${YELLOW}Tip:${NC} Check network connection and try again." echo -e "${YELLOW}Tip:${NC} URL: $installer_url" exit 1 @@ -324,7 +324,7 @@ update_mole() { if [[ "$requires_sudo" == "true" ]]; then if ! request_sudo_access "Mole update requires admin access"; then - log_error "Update aborted (admin access denied)" + log_error "Update aborted, admin access denied" rm -f "$tmp_installer" exit 1 fi @@ -349,14 +349,17 @@ update_mole() { if ! printf '%s\n' "$output" | grep -Eq "Updated to latest version|Already on latest version"; then local new_version - new_version=$(printf '%s\n' "$output" | sed -n 's/.*(version \([^)]*\)).*/\1/p' | head -1) + new_version=$(printf '%s\n' "$output" | sed -n 's/.*-> \([^[:space:]]\{1,\}\).*/\1/p' | head -1) + if [[ -z "$new_version" ]]; then + new_version=$(printf '%s\n' "$output" | sed -n 's/.*version[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*/\1/p' | head -1) + fi if [[ -z "$new_version" ]]; then new_version=$("$mole_path" --version 2> /dev/null | awk 'NR==1 && NF {print $NF}' || echo "") fi if [[ -z "$new_version" ]]; then new_version="$fallback_version" fi - printf '\n%s\n\n' "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version (${new_version:-unknown})" + printf '\n%s\n\n' "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version, ${new_version:-unknown}" else printf '\n' fi @@ -484,15 +487,15 @@ remove_mole() { exit 0 fi - echo -e "${YELLOW}Remove Mole${NC} - will delete the following:" + echo -e "${YELLOW}Remove Mole${NC}, will delete the following:" if [[ "$is_homebrew" == "true" ]]; then - echo " - Mole via Homebrew" + echo " * Mole via Homebrew" fi for install in ${manual_installs[@]+"${manual_installs[@]}"} ${alias_installs[@]+"${alias_installs[@]}"}; do - echo " - $install" + echo " * $install" done - echo " - ~/.config/mole" - echo " - ~/.cache/mole" + echo " * ~/.config/mole" + echo " * ~/.cache/mole" echo -ne "${PURPLE}${ICON_ARROW}${NC} Press ${GREEN}Enter${NC} to confirm, ${GRAY}ESC${NC} to cancel: " IFS= read -r -s -n1 key || key="" diff --git a/scripts/check.sh b/scripts/check.sh index 4249a82..20e3dff 100755 --- a/scripts/check.sh +++ b/scripts/check.sh @@ -14,7 +14,7 @@ usage() { Usage: ./scripts/check.sh [--format|--no-format] Options: - --format Apply formatting fixes only (shfmt, gofmt) + --format Apply formatting fixes only, shfmt, gofmt --no-format Skip formatting and run checks only --help Show this help EOF @@ -55,7 +55,7 @@ readonly ICON_ERROR="☻" readonly ICON_WARNING="●" readonly ICON_LIST="•" -echo -e "${BLUE}=== Mole Check (${MODE}) ===${NC}\n" +echo -e "${BLUE}=== Mole Check, ${MODE} ===${NC}\n" SHELL_FILES=$(find . -type f \( -name "*.sh" -o -name "mole" \) \ -not -path "./.git/*" \ @@ -75,11 +75,11 @@ if [[ "$MODE" == "format" ]]; then fi if command -v goimports > /dev/null 2>&1; then - echo -e "${YELLOW}Formatting Go code (goimports)...${NC}" + echo -e "${YELLOW}Formatting Go code, goimports...${NC}" goimports -w -local github.com/tw93/Mole ./cmd echo -e "${GREEN}${ICON_SUCCESS} Go formatting complete${NC}\n" elif command -v go > /dev/null 2>&1; then - echo -e "${YELLOW}Formatting Go code (gofmt)...${NC}" + echo -e "${YELLOW}Formatting Go code, gofmt...${NC}" gofmt -w ./cmd echo -e "${GREEN}${ICON_SUCCESS} Go formatting complete${NC}\n" else @@ -100,11 +100,11 @@ if [[ "$MODE" != "check" ]]; then fi if command -v goimports > /dev/null 2>&1; then - echo -e "${YELLOW}2. Formatting Go code (goimports)...${NC}" + echo -e "${YELLOW}2. Formatting Go code, goimports...${NC}" goimports -w -local github.com/tw93/Mole ./cmd echo -e "${GREEN}${ICON_SUCCESS} Go formatting applied${NC}\n" elif command -v go > /dev/null 2>&1; then - echo -e "${YELLOW}2. Formatting Go code (gofmt)...${NC}" + echo -e "${YELLOW}2. Formatting Go code, gofmt...${NC}" gofmt -w ./cmd echo -e "${GREEN}${ICON_SUCCESS} Go formatting applied${NC}\n" fi @@ -148,18 +148,18 @@ fi echo -e "${YELLOW}5. Running syntax check...${NC}" if ! bash -n mole; then - echo -e "${RED}${ICON_ERROR} Syntax check failed (mole)${NC}\n" + echo -e "${RED}${ICON_ERROR} Syntax check failed, mole${NC}\n" exit 1 fi for script in bin/*.sh; do if ! bash -n "$script"; then - echo -e "${RED}${ICON_ERROR} Syntax check failed ($script)${NC}\n" + echo -e "${RED}${ICON_ERROR} Syntax check failed, $script${NC}\n" exit 1 fi done find lib -name "*.sh" | while read -r script; do if ! bash -n "$script"; then - echo -e "${RED}${ICON_ERROR} Syntax check failed ($script)${NC}\n" + echo -e "${RED}${ICON_ERROR} Syntax check failed, $script${NC}\n" exit 1 fi done diff --git a/scripts/setup-quick-launchers.sh b/scripts/setup-quick-launchers.sh index 11b8784..53b07f3 100755 --- a/scripts/setup-quick-launchers.sh +++ b/scripts/setup-quick-launchers.sh @@ -392,7 +392,7 @@ ${command} EOF - log_success "Workflow ready: ${name} (keyword: ${keyword})" + log_success "Workflow ready: ${name}, keyword: ${keyword}" done log_step "Open Alfred preferences → Workflows if you need to adjust keywords." @@ -413,11 +413,11 @@ main() { echo "" log_success "Done! Raycast and Alfred are ready with 5 commands:" - echo " • clean - Deep system cleanup" - echo " • uninstall - Remove applications" - echo " • optimize - System health & tuning" - echo " • analyze - Disk space explorer" - echo " • status - Live system monitor" + echo " • clean, Deep system cleanup" + echo " • uninstall, Remove applications" + echo " • optimize, System health & tuning" + echo " • analyze, Disk space explorer" + echo " • status, Live system monitor" echo "" } diff --git a/scripts/test.sh b/scripts/test.sh index 11bc688..d42905c 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -183,7 +183,7 @@ echo "" echo "6. Testing installation..." # Skip if Homebrew mole is installed (install.sh will refuse to overwrite) if brew list mole &> /dev/null; then - printf "${GREEN}${ICON_SUCCESS} Installation test skipped (Homebrew)${NC}\n" + printf "${GREEN}${ICON_SUCCESS} Installation test skipped, Homebrew${NC}\n" elif ./install.sh --prefix /tmp/mole-test > /dev/null 2>&1; then if [ -f /tmp/mole-test/mole ]; then printf "${GREEN}${ICON_SUCCESS} Installation test passed${NC}\n" @@ -203,5 +203,5 @@ if [[ $FAILED -eq 0 ]]; then printf "${GREEN}${ICON_SUCCESS} All tests passed!${NC}\n" exit 0 fi -printf "${RED}${ICON_ERROR} $FAILED test(s) failed!${NC}\n" +printf "${RED}${ICON_ERROR} $FAILED tests failed!${NC}\n" exit 1 diff --git a/tests/update.bats b/tests/update.bats index 055603a..a02fd75 100644 --- a/tests/update.bats +++ b/tests/update.bats @@ -78,8 +78,8 @@ ask_for_updates EOF [ "$status" -eq 1 ] # ESC cancels - [[ "$output" == *"Homebrew (5 updates)"* ]] - [[ "$output" == *"App Store (1 apps)"* ]] + [[ "$output" == *"Homebrew, 3 formula, 2 cask"* ]] + [[ "$output" == *"App Store, 1 apps"* ]] [[ "$output" == *"macOS system"* ]] [[ "$output" == *"Mole"* ]] } @@ -253,24 +253,27 @@ process_install_output() { if ! printf '%s\n' "$output" | grep -Eq "Updated to latest version|Already on latest version"; then local new_version - new_version=$(printf '%s\n' "$output" | sed -n 's/.*(version \([^)]*\)).*/\1/p' | head -1) + new_version=$(printf '%s\n' "$output" | sed -n 's/.*-> \([^[:space:]]\{1,\}\).*/\1/p' | head -1) + if [[ -z "$new_version" ]]; then + new_version=$(printf '%s\n' "$output" | sed -n 's/.*version[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*/\1/p' | head -1) + fi if [[ -z "$new_version" ]]; then new_version=$(command -v mo > /dev/null 2>&1 && mo --version 2> /dev/null | awk 'NR==1 && NF {print $NF}' || echo "") fi if [[ -z "$new_version" ]]; then new_version="$fallback_version" fi - printf '\n%s\n' "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version (${new_version:-unknown})" + printf '\n%s\n' "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version, ${new_version:-unknown}" fi } output="Installing Mole... -◎ Mole installed successfully (version 1.23.1)" +◎ Mole installed successfully, version 1.23.1" process_install_output "$output" "1.23.0" EOF [ "$status" -eq 0 ] - [[ "$output" == *"Updated to latest version (1.23.1)"* ]] + [[ "$output" == *"Updated to latest version, 1.23.1"* ]] [[ "$output" != *"1.23.0"* ]] } @@ -293,14 +296,17 @@ process_install_output() { if ! printf '%s\n' "$output" | grep -Eq "Updated to latest version|Already on latest version"; then local new_version - new_version=$(printf '%s\n' "$output" | sed -n 's/.*(version \([^)]*\)).*/\1/p' | head -1) + new_version=$(printf '%s\n' "$output" | sed -n 's/.*-> \([^[:space:]]\{1,\}\).*/\1/p' | head -1) + if [[ -z "$new_version" ]]; then + new_version=$(printf '%s\n' "$output" | sed -n 's/.*version[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*/\1/p' | head -1) + fi if [[ -z "$new_version" ]]; then new_version=$(command -v mo > /dev/null 2>&1 && mo --version 2> /dev/null | awk 'NR==1 && NF {print $NF}' || echo "") fi if [[ -z "$new_version" ]]; then new_version="$fallback_version" fi - printf '\n%s\n' "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version (${new_version:-unknown})" + printf '\n%s\n' "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version, ${new_version:-unknown}" fi } @@ -311,7 +317,7 @@ EOF [ "$status" -eq 0 ] [[ "$output" == *"Installation completed"* ]] - [[ "$output" == *"Updated to latest version (1.23.1)"* ]] + [[ "$output" == *"Updated to latest version, 1.23.1"* ]] } @test "process_install_output handles empty output with fallback version" { @@ -333,14 +339,17 @@ process_install_output() { if ! printf '%s\n' "$output" | grep -Eq "Updated to latest version|Already on latest version"; then local new_version - new_version=$(printf '%s\n' "$output" | sed -n 's/.*(version \([^)]*\)).*/\1/p' | head -1) + new_version=$(printf '%s\n' "$output" | sed -n 's/.*-> \([^[:space:]]\{1,\}\).*/\1/p' | head -1) + if [[ -z "$new_version" ]]; then + new_version=$(printf '%s\n' "$output" | sed -n 's/.*version[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*/\1/p' | head -1) + fi if [[ -z "$new_version" ]]; then new_version=$(command -v mo > /dev/null 2>&1 && mo --version 2> /dev/null | awk 'NR==1 && NF {print $NF}' || echo "") fi if [[ -z "$new_version" ]]; then new_version="$fallback_version" fi - printf '\n%s\n' "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version (${new_version:-unknown})" + printf '\n%s\n' "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version, ${new_version:-unknown}" fi } @@ -349,7 +358,7 @@ process_install_output "$output" "1.23.1" EOF [ "$status" -eq 0 ] - [[ "$output" == *"Updated to latest version (1.23.1)"* ]] + [[ "$output" == *"Updated to latest version, 1.23.1"* ]] } @test "process_install_output does not extract wrong parentheses content" { @@ -371,14 +380,17 @@ process_install_output() { if ! printf '%s\n' "$output" | grep -Eq "Updated to latest version|Already on latest version"; then local new_version - new_version=$(printf '%s\n' "$output" | sed -n 's/.*(version \([^)]*\)).*/\1/p' | head -1) + new_version=$(printf '%s\n' "$output" | sed -n 's/.*-> \([^[:space:]]\{1,\}\).*/\1/p' | head -1) + if [[ -z "$new_version" ]]; then + new_version=$(printf '%s\n' "$output" | sed -n 's/.*version[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*/\1/p' | head -1) + fi if [[ -z "$new_version" ]]; then new_version=$(command -v mo > /dev/null 2>&1 && mo --version 2> /dev/null | awk 'NR==1 && NF {print $NF}' || echo "") fi if [[ -z "$new_version" ]]; then new_version="$fallback_version" fi - printf '\n%s\n' "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version (${new_version:-unknown})" + printf '\n%s\n' "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version, ${new_version:-unknown}" fi } @@ -389,7 +401,7 @@ EOF [ "$status" -eq 0 ] [[ "$output" == *"Downloading (progress: 100%)"* ]] - [[ "$output" == *"Updated to latest version (1.23.1)"* ]] + [[ "$output" == *"Updated to latest version, 1.23.1"* ]] [[ "$output" != *"progress: 100%"* ]] || [[ "$output" == *"Downloading (progress: 100%)"* ]] } @@ -418,7 +430,7 @@ curl() { if [[ -n "$out" ]]; then cat > "$out" << 'INSTALLER' #!/usr/bin/env bash -echo "Mole installed successfully (version $CURRENT_VERSION)" +echo "Mole installed successfully, version $CURRENT_VERSION" INSTALLER return 0 fi