Browse code

Merge pull request #275 from tristan0x/require_tool

New script $ZSH/tools/require_tool.sh to ensure version of tool

Robby Russell authored on 10/10/2011 at 12:08:38
Showing 1 changed files
1 1
new file mode 100755
... ...
@@ -0,0 +1,161 @@
0
+__require_tool_version_compare ()
1
+{
2
+  (
3
+    # Locally ignore failures, otherwise we'll exit whenever $1 and $2
4
+    # are not equal!
5
+    set +e
6
+
7
+awk_strverscmp='
8
+  # Use only awk features that work with 7th edition Unix awk (1978).
9
+  # My, what an old awk you have, Mr. Solaris!
10
+  END {
11
+    while (length(v1) || length(v2)) {
12
+      # Set d1 to be the next thing to compare from v1, and likewise for d2.
13
+      # Normally this is a single character, but if v1 and v2 contain digits,
14
+      # compare them as integers and fractions as strverscmp does.
15
+      if (v1 ~ /^[0-9]/ && v2 ~ /^[0-9]/) {
16
+	# Split v1 and v2 into their leading digit string components d1 and d2,
17
+	# and advance v1 and v2 past the leading digit strings.
18
+	for (len1 = 1; substr(v1, len1 + 1) ~ /^[0-9]/; len1++) continue
19
+	for (len2 = 1; substr(v2, len2 + 1) ~ /^[0-9]/; len2++) continue
20
+	d1 = substr(v1, 1, len1); v1 = substr(v1, len1 + 1)
21
+	d2 = substr(v2, 1, len2); v2 = substr(v2, len2 + 1)
22
+	if (d1 ~ /^0/) {
23
+	  if (d2 ~ /^0/) {
24
+	    # Compare two fractions.
25
+	    while (d1 ~ /^0/ && d2 ~ /^0/) {
26
+	      d1 = substr(d1, 2); len1--
27
+	      d2 = substr(d2, 2); len2--
28
+	    }
29
+	    if (len1 != len2 && ! (len1 && len2 && substr(d1, 1, 1) == substr(d2, 1, 1))) {
30
+	      # The two components differ in length, and the common prefix
31
+	      # contains only leading zeros.  Consider the longer to be less.
32
+	      d1 = -len1
33
+	      d2 = -len2
34
+	    } else {
35
+	      # Otherwise, compare as strings.
36
+	      d1 = "x" d1
37
+	      d2 = "x" d2
38
+	    }
39
+	  } else {
40
+	    # A fraction is less than an integer.
41
+	    exit 1
42
+	  }
43
+	} else {
44
+	  if (d2 ~ /^0/) {
45
+	    # An integer is greater than a fraction.
46
+	    exit 2
47
+	  } else {
48
+	    # Compare two integers.
49
+	    d1 += 0
50
+	    d2 += 0
51
+	  }
52
+	}
53
+      } else {
54
+	# The normal case, without worrying about digits.
55
+	if (v1 == "") d1 = v1; else { d1 = substr(v1, 1, 1); v1 = substr(v1,2) }
56
+	if (v2 == "") d2 = v2; else { d2 = substr(v2, 1, 1); v2 = substr(v2,2) }
57
+      }
58
+      if (d1 < d2) exit 1
59
+      if (d1 > d2) exit 2
60
+    }
61
+  }
62
+'
63
+    awk "$awk_strverscmp" v1="$1" v2="$2" /dev/null
64
+    case $? in
65
+      1)  echo '<';;
66
+      0)  echo '=';;
67
+      2)  echo '>';;
68
+    esac
69
+  )
70
+}
71
+
72
+
73
+__require_tool_fatal ()
74
+{
75
+    echo $@ >/dev/stderr
76
+    return 1
77
+}
78
+
79
+# Usage: require_tool program version
80
+# Returns: 0 if $1 version if greater equals than $2, 1 otherwise.
81
+# In case of error, message is written on error output.
82
+#
83
+# Example: require_tool gcc 4.6
84
+# Use GCC environment variable if defined instead of lookup for the tool
85
+# in the environment.
86
+require_tool ()
87
+{
88
+  envvar_name=$(echo $1 | tr '[:lower:]' '[:upper:]')
89
+  tool=$(printenv $envvar_name || echo $1)
90
+  local version=$($tool --version 2>/dev/null| \
91
+    sed -n 's/.*[^0-9.]\([0-9]*\.[0-9.]*\).*/\1/p;q')
92
+  if test x"$version" = x ; then
93
+      echo "$tool is required" >/dev/stderr
94
+      return 1
95
+  fi
96
+  case $(__require_tool_version_compare "$2" "$version") in
97
+    '>')
98
+	  echo "$1 $2 or better is required: this is $tool $version" >/dev/stderr
99
+	  return 1
100
+	  ;;
101
+  esac
102
+}
103
+
104
+usage() {
105
+    cat <<EOF
106
+NAME
107
+    require_tool.sh - Ensure version of a tool is greater than the one expected
108
+
109
+SYNOPSYS
110
+    require_tool.sh [ -h ]
111
+                    [ --help ]
112
+                    [ TOOL MIN_VERSION ]
113
+
114
+DESCRIPTION
115
+    TOOL is the name or path of the program to check. If the name is specified, its
116
+    path is deduced from PATH environment variable. If environment variable TOOL
117
+    (in upper-case characters) is defined, considers its value as path to the tool.
118
+
119
+    MIN_VERSION is a string representing the minimum required version.
120
+
121
+BEHAVIOR
122
+    * locate path to the program.
123
+    * execute $ TOOL_PATH --version
124
+    * extract version from standard output.
125
+    * compare this version to the expected one.
126
+
127
+OPTIONS
128
+    -h --help
129
+        Display this message and exit 0
130
+
131
+ERRORS
132
+    if program is not found or its version is prior to expected version,
133
+    a message is written to error output.
134
+
135
+EXIT VALUE
136
+    returns 0 if program version if greater equals than expected version,
137
+    returns 1 otherwise.
138
+
139
+EXAMPLE
140
+    $ require_tool.sh emacs 23
141
+    $ CC=g++ require_tool.sh cc 4.6
142
+    $ require_tool.sh zsh 4.5
143
+
144
+EOF
145
+}
146
+
147
+for arg in $@; do
148
+    case $arg in
149
+        -h|--help)
150
+            usage
151
+            exit 0
152
+            ;;
153
+    esac
154
+done
155
+if [ $# -gt 2 ] ; then
156
+    echo "ERROR: expecting 2 parameters. Please see option --help"
157
+    exit 1
158
+fi
159
+
160
+require_tool $@