-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclean_path.sh
More file actions
executable file
·125 lines (111 loc) · 3.5 KB
/
Copy pathclean_path.sh
File metadata and controls
executable file
·125 lines (111 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/bin/zsh
#
# Script Name: clean_path.sh
# Description: <short description of what this script does>
# Author: B Chahal
# Created: 2025-08-09
# Version: 1.0
#
# Usage:
# clean_path.sh [options]
#
# Notes:
# - Designed for macOS with zsh
# - Place this script in ~/.local/bin and make it executable
#
########################################
# Safety settings
########################################
set -euo pipefail
IFS=$'\n\t'
########################################
# Logging helpers
########################################
log_info() { echo "ℹ️ [INFO] $*"; }
log_success() { echo "✅ [SUCCESS] $*"; }
log_warn() { echo "⚠️ [WARNING] $*"; }
log_error() { echo "❌ [ERROR] $*" >&2; }
########################################
# Main script logic
########################################
main() {
log_info "Auditing and cleaning your PATH (order-preserving, de-duplicated)…"
# --- Snapshot BEFORE ---
local before="$PATH"
local before_count
before_count=$(print -r -- "$before" | tr ':' '\n' | wc -l | tr -d ' ')
# --- Report duplicates (with counts) ---
local dups
dups=$(print -r -- "$before" \
| tr ':' '\n' \
| awk '{c[$0]++} END{for (p in c) if (c[p]>1) printf "%dx %s\n", c[p], p}' \
| sort -nr || true)
if [[ -n "$dups" ]]; then
log_warn "Duplicate entries found:"
printf "%s\n" "$dups"
else
log_info "No duplicates found."
fi
# --- De-duplicate NOW (preserve first occurrence order) ---
local cleaned
cleaned=$(print -r -- "$before" | tr ':' '\n' | awk '!seen[$0]++' | paste -sd ':' -)
# --- Prefer common user + Homebrew dirs first; keep uniques with zsh arrays ---
typeset -U path PATH
path=(${(s/:/)cleaned})
path=(
"$HOME/.local/bin"
"$HOME/bin"
/opt/homebrew/bin
/opt/homebrew/sbin
$path
)
export PATH=${(j/:/)path}
# --- Snapshot AFTER ---
local after="$PATH"
local after_count
after_count=$(print -r -- "$after" | tr ':' '\n' | wc -l | tr -d ' ')
log_success "De-duplicated current PATH: $before_count → $after_count entries"
# --- Persist in ~/.zshrc (idempotent managed block) ---
local zshrc="$HOME/.zshrc"
local marker_start="# >>> PATH DEDUPE START (managed by clean_path.sh)"
local marker_end="# <<< PATH DEDUPE END (managed by clean_path.sh)"
local block_content
block_content=$(cat <<'EOF'
# >>> PATH DEDUPE START (managed by clean_path.sh)
# Keep unique PATH entries (zsh) and set preferred ordering first.
typeset -U path PATH
path=(
"$HOME/.local/bin"
"$HOME/bin"
/opt/homebrew/bin
/opt/homebrew/sbin
$path
)
# >>> If you add PATH lines elsewhere, this unique array drops duplicates automatically.
# <<< PATH DEDUPE END (managed by clean_path.sh)
EOF
)
if grep -Fq "$marker_start" "$zshrc" 2>/dev/null; then
log_info "PATH dedupe block already present in ~/.zshrc — leaving it as-is."
else
if [[ -f "$zshrc" ]]; then
local backup="$HOME/.zshrc.bak-$(date +%Y%m%d-%H%M%S)"
cp "$zshrc" "$backup"
log_info "Backed up ~/.zshrc → $backup"
fi
printf "\n%s\n" "$block_content" >> "$zshrc"
log_success "Appended PATH dedupe block to ~/.zshrc"
fi
# --- Reload only if we're interactive (avoid errors from non-interactive sourcing) ---
if [[ -o interactive ]]; then
log_info "Reloading ~/.zshrc for this shell…"
source "$zshrc"
else
log_info "Open a new terminal or run: exec zsh"
fi
log_success "Done. Try: showpath"
}
########################################
# Run main
########################################
main "$@"