-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpath-tools.sh
114 lines (107 loc) · 3.53 KB
/
path-tools.sh
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
#!/usr/bin/env bash
path_append() {
[[ -n $1 && $# -eq 1 ]] || { printf "Usage: path_append ELM\n" >&2; return 1; }
local new_path; new_path=$(path_remove "$1")
printf "%s\n" "$new_path:$1"
}
path_prepend() {
[[ -n $1 && $# -eq 1 ]] || { printf "Usage: path_prepend ELM\n" >&2; return 1; }
local new_path; new_path=$(path_remove "$1")
printf "%s\n" "$1:$new_path"
}
path_insert_after() {
local new_path new_path_inner path rev_path prepend=false matched=false
if [[ $1 == '-p' ]]; then prepend=true; shift; fi
[[ -n $1 && $# -le 2 ]] || { printf "Usage: path_insert_after [-p] ELM [GLOB]\n" >&2; return 1; }
if [[ -n $2 ]]; then
new_path=$(path_remove "$1")
while IFS= read -r -d ':' rev_path; do
path=$(rev <<<"$rev_path")
# shellcheck disable=2053
if [[ ${path%/} != $2 ]] || $matched; then
new_path_inner=$new_path_inner:$rev_path
else
new_path_inner=$new_path_inner:$(rev <<<"$1"):$rev_path
matched=true
fi
done < <(rev <<<":$new_path")
new_path_inner=$(rev <<<"$new_path_inner")
new_path=${new_path_inner%:}
if ! $matched; then
if $prepend; then new_path=$1:$new_path
else new_path=$new_path:$1; fi
fi
printf "%s\n" "$new_path"
else
if $prepend; then path_prepend "$1"
else path_append "$1"; fi
fi
}
path_insert_before() {
local new_path new_path_inner path prepend=false matched=false
if [[ $1 == '-p' ]]; then prepend=true; shift; fi
[[ -n $1 && $# -le 2 ]] || { printf "Usage: path_insert_before [-p] ELM [GLOB]\n" >&2; return 1; }
if [[ -n $2 ]]; then
new_path=$(path_remove "$1")
while IFS= read -r -d ':' path; do
# shellcheck disable=2053
if [[ ${path%/} != $2 ]] || $matched; then
new_path_inner=$new_path_inner:$path
else
new_path_inner=$new_path_inner:$1:$path
matched=true
fi
done <<<"$new_path:"
new_path=${new_path_inner#:}
if ! $matched; then
if $prepend; then new_path=$1:$new_path
else new_path=$new_path:$1; fi
fi
printf "%s\n" "$new_path"
else
if $prepend; then path_prepend "$1"
else path_append "$1"; fi
fi
}
path_remove() {
[[ -n $1 && $2 =~ ^|true|false$ && $# -le 2 ]] || { printf "Usage: path_remove ELM [ENABLE_GLOB]\n" >&2; return 1; }
local path new_path
while IFS= read -r -d ':' path; do
# shellcheck disable=2053
if [[ $2 = true && ${path%/} != $1 ]] || [[ $2 != true && ${path%/} != "${1%/}" ]]; then
new_path=$new_path:$path
fi
done <<<"$PATH:"
printf "%s\n" "${new_path#:}"
}
path_contains() {
[[ -n $1 || ! $2 =~ ^|true|false$ && $# -le 2 ]] || { printf "Usage: path_contains ELM [ENABLE_GLOB]\n" >&2; return 1; }
local path
while IFS= read -r -d ':' path; do
# shellcheck disable=2053
if [[ $2 = true && ${path%/} = $1 ]] || [[ $2 != true && ${path%/} = "${1%/}" ]]; then
return 0
fi
done <<<"$PATH:"
return 1
}
# shellcheck disable=2120
path_validate() {
[[ $# -eq 0 ]] || { printf "Usage: path_validate\n" >&2; return 1; }
local ret=0
if [[ $PATH = *'\0'* ]]; then
printf "path-tools.sh: \$PATH contains nul bytes\n" >&2
ret=1
fi
if [[ $PATH =~ ^:|:$|:: ]]; then
printf "path-tools.sh: \$PATH contains empty strings\n" >&2
ret=1
fi
local duplicates=(); IFS=$'\n' readarray -t duplicates < <(tr ':' $'\n' <<<"$PATH" | sed 's%\(.\)/$%\1%' | sort | uniq -D | uniq)
if [[ ${#duplicates[@]} -ne 0 ]]; then
printf "path-tools.sh: \$PATH contains duplicate paths:\n" >&2
printf " %s\n" "${duplicates[@]}" >&2
ret=1
fi
return $ret
}