forked from ohmyzsh/ohmyzsh
-
Notifications
You must be signed in to change notification settings - Fork 0
/
require_tool.sh
executable file
·161 lines (145 loc) · 4.28 KB
/
require_tool.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
__require_tool_version_compare ()
{
(
# Locally ignore failures, otherwise we'll exit whenever $1 and $2
# are not equal!
set +e
awk_strverscmp='
# Use only awk features that work with 7th edition Unix awk (1978).
# My, what an old awk you have, Mr. Solaris!
END {
while (length(v1) || length(v2)) {
# Set d1 to be the next thing to compare from v1, and likewise for d2.
# Normally this is a single character, but if v1 and v2 contain digits,
# compare them as integers and fractions as strverscmp does.
if (v1 ~ /^[0-9]/ && v2 ~ /^[0-9]/) {
# Split v1 and v2 into their leading digit string components d1 and d2,
# and advance v1 and v2 past the leading digit strings.
for (len1 = 1; substr(v1, len1 + 1) ~ /^[0-9]/; len1++) continue
for (len2 = 1; substr(v2, len2 + 1) ~ /^[0-9]/; len2++) continue
d1 = substr(v1, 1, len1); v1 = substr(v1, len1 + 1)
d2 = substr(v2, 1, len2); v2 = substr(v2, len2 + 1)
if (d1 ~ /^0/) {
if (d2 ~ /^0/) {
# Compare two fractions.
while (d1 ~ /^0/ && d2 ~ /^0/) {
d1 = substr(d1, 2); len1--
d2 = substr(d2, 2); len2--
}
if (len1 != len2 && ! (len1 && len2 && substr(d1, 1, 1) == substr(d2, 1, 1))) {
# The two components differ in length, and the common prefix
# contains only leading zeros. Consider the longer to be less.
d1 = -len1
d2 = -len2
} else {
# Otherwise, compare as strings.
d1 = "x" d1
d2 = "x" d2
}
} else {
# A fraction is less than an integer.
exit 1
}
} else {
if (d2 ~ /^0/) {
# An integer is greater than a fraction.
exit 2
} else {
# Compare two integers.
d1 += 0
d2 += 0
}
}
} else {
# The normal case, without worrying about digits.
if (v1 == "") d1 = v1; else { d1 = substr(v1, 1, 1); v1 = substr(v1,2) }
if (v2 == "") d2 = v2; else { d2 = substr(v2, 1, 1); v2 = substr(v2,2) }
}
if (d1 < d2) exit 1
if (d1 > d2) exit 2
}
}
'
awk "$awk_strverscmp" v1="$1" v2="$2" /dev/null
case $? in
1) echo '<';;
0) echo '=';;
2) echo '>';;
esac
)
}
__require_tool_fatal ()
{
echo $@ >/dev/stderr
return 1
}
# Usage: require_tool program version
# Returns: 0 if $1 version if greater equals than $2, 1 otherwise.
# In case of error, message is written on error output.
#
# Example: require_tool gcc 4.6
# Use GCC environment variable if defined instead of lookup for the tool
# in the environment.
require_tool ()
{
envvar_name=$(echo $1 | tr '[:lower:]' '[:upper:]')
tool=$(printenv $envvar_name || echo $1)
local version=$($tool --version 2>/dev/null| \
sed -n 's/.*[^0-9.]\([0-9]*\.[0-9.]*\).*/\1/p;q')
if test x"$version" = x ; then
echo "$tool is required" >/dev/stderr
return 1
fi
case $(__require_tool_version_compare "$2" "$version") in
'>')
echo "$1 $2 or better is required: this is $tool $version" >/dev/stderr
return 1
;;
esac
}
usage() {
cat <<EOF
NAME
require_tool.sh - Ensure version of a tool is greater than the one expected
SYNOPSYS
require_tool.sh [ -h ]
[ --help ]
[ TOOL MIN_VERSION ]
DESCRIPTION
TOOL is the name or path of the program to check. If the name is specified, its
path is deduced from PATH environment variable. If environment variable TOOL
(in upper-case characters) is defined, considers its value as path to the tool.
MIN_VERSION is a string representing the minimum required version.
BEHAVIOR
* locate path to the program.
* execute $ TOOL_PATH --version
* extract version from standard output.
* compare this version to the expected one.
OPTIONS
-h --help
Display this message and exit 0
ERRORS
if program is not found or its version is prior to expected version,
a message is written to error output.
EXIT VALUE
returns 0 if program version if greater equals than expected version,
returns 1 otherwise.
EXAMPLE
$ require_tool.sh emacs 23
$ CC=g++ require_tool.sh cc 4.6
$ require_tool.sh zsh 4.5
EOF
}
for arg in $@; do
case $arg in
-h|--help)
usage
exit 0
;;
esac
done
if [ $# -gt 2 ] ; then
echo "ERROR: expecting 2 parameters. Please see option --help"
exit 1
fi
require_tool $@