/[gentoo-x86]/eclass/versionator.eclass
Gentoo

Contents of /eclass/versionator.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (hide annotations) (download)
Tue Jan 4 13:03:54 2005 UTC (9 years, 6 months ago) by ciaranm
Branch: MAIN
Changes since 1.4: +3 -3 lines
fix delete_all_version_separators when called with args

1 ciaranm 1.1 # Copyright 1999-2004 Gentoo Foundation
2     # Distributed under the terms of the GNU General Public License v2
3 ciaranm 1.5 # $Header: /var/cvsroot/gentoo-x86/eclass/versionator.eclass,v 1.4 2005/01/02 17:08:19 ciaranm Exp $
4 ciaranm 1.1 #
5     # Original Author: Ciaran McCreesh <ciaranm@gentoo.org>
6     #
7     # This eclass provides functions which simplify manipulating $PV and similar
8     # variables. Most functions default to working with $PV, although other
9     # values can be used.
10     #
11     # Simple Example 1: $PV is 1.2.3b, we want 1_2.3b:
12     # MY_PV=$(replace_version_separator 1 '_' )
13     #
14     # Simple Example 2: $PV is 1.4.5, we want 1:
15     # MY_MAJORV=$(get_major_version )
16     #
17     # Full list of user usable functions provided by this eclass (see the functions
18     # themselves for documentation):
19     # get_all_version_components ver_str
20     # get_version_components ver_str
21     # get_major_version ver_str
22     # get_version_component_range range ver_str
23     # get_after_major_version ver_str
24     # replace_version_separator index newvalue ver_str
25     # replace_all_version_separators newvalue ver_str
26 ciaranm 1.3 # delete_version_separator index ver_str
27     # delete_all_version_separators ver_str
28     #
29     # Rather than being a number, the index parameter can be a separator character
30     # such as '-', '.' or '_'. In this case, the first separator of this kind is
31     # selected.
32 ciaranm 1.2 #
33     # There's also:
34     # version_is_at_least want have
35 ciaranm 1.3 # but it doesn't work in all cases, so only use it if you know what you're
36     # doing.
37 ciaranm 1.1
38     ECLASS=versionator
39     INHERITED="$INHERITED $ECLASS"
40    
41     shopt -s extglob
42    
43     # Split up a version string into its component parts. If no parameter is
44     # supplied, defaults to $PV.
45     # 0.8.3 -> 0 . 8 . 3
46     # 7c -> 7 c
47     # 3.0_p2 -> 3 . 0 _ p2
48     # 20040905 -> 20040905
49     # 3.0c-r1 -> 3 . 0 c - r1
50     get_all_version_components() {
51     local ver_str=${1:-${PV}} result result_idx=0
52     result=( )
53    
54     # sneaky cache trick cache to avoid having to parse the same thing several
55     # times.
56     if [[ "${VERSIONATOR_CACHE_VER_STR}" == "${ver_str}" ]] ; then
57     echo ${VERSIONATOR_CACHE_RESULT}
58     return
59     fi
60     export VERSIONATOR_CACHE_VER_STR="${ver_str}"
61    
62     while [[ -n "$ver_str" ]] ; do
63     case "${ver_str:0:1}" in
64     # number: parse whilst we have a number
65     [[:digit:]])
66     result[$result_idx]="${ver_str%%[^[:digit:]]*}"
67     ver_str="${ver_str##+([[:digit:]])}"
68     result_idx=$(($result_idx + 1))
69     ;;
70    
71     # separator: single character
72     [-_.])
73     result[$result_idx]="${ver_str:0:1}"
74     ver_str="${ver_str:1}"
75     result_idx=$(($result_idx + 1))
76     ;;
77    
78     # letter: grab the letters plus any following numbers
79     [[:alpha:]])
80     local not_match="${ver_str##+([[:alpha:]])*([[:digit:]])}"
81     result[$result_idx]=${ver_str:0:$((${#ver_str} - ${#not_match}))}
82     ver_str="${not_match}"
83     result_idx=$(($result_idx + 1))
84     ;;
85    
86     # huh?
87     *)
88     result[$result_idx]="${ver_str:0:1}"
89     ver_str="${ver_str:1}"
90     result_idx=$(($result_idx + 1))
91     ;;
92     esac
93     done
94    
95     export VERSIONATOR_CACHE_RESULT="${result[@]}"
96     echo ${result[@]}
97     }
98    
99     # Get the important version components, excluding '.', '-' and '_'. Defaults to
100     # $PV if no parameter is supplied.
101     # 0.8.3 -> 0 8 3
102     # 7c -> 7 c
103     # 3.0_p2 -> 3 0 p2
104     # 20040905 -> 20040905
105     # 3.0c-r1 -> 3 0 c r1
106     get_version_components() {
107     local c="$(get_all_version_components "${1:-${PV}}")"
108     c=( ${c[@]//[-._]/ } )
109     echo ${c[@]}
110     }
111    
112     # Get the major version of a value. Defaults to $PV if no parameter is supplied.
113     # 0.8.3 -> 0
114     # 7c -> 7
115     # 3.0_p2 -> 3
116     # 20040905 -> 20040905
117     # 3.0c-r1 -> 3
118     get_major_version() {
119     local c
120     c=( $(get_all_version_components "${1:-${PV}}" ) )
121     echo ${c[0]}
122     }
123    
124     # Get a particular component or range of components from the version. If no
125     # version parameter is supplied, defaults to $PV.
126     # 1 1.2.3 -> 1
127     # 1-2 1.2.3 -> 1.2
128     # 2- 1.2.3 -> 2.3
129     get_version_component_range() {
130     local c v="${2:-${PV}}" range="${1}" range_start range_end i=-1 j=0
131     c=( $(get_all_version_components ${v} ) )
132     range_start="${range%-*}" ; range_start="${range_start:-1}"
133     range_end="${range#*-}" ; range_end="${range_end:-${#c[@]}}"
134    
135     while (( j < ${range_start} )) ; do
136     i=$(($i + 1))
137     [[ $i -gt ${#c[@]} ]] && return
138     [[ -n "${c[${i}]//[-._]}" ]] && j=$(($j + 1))
139     done
140    
141     while (( j <= ${range_end} )) ; do
142     echo -n ${c[$i]}
143     [[ $i -gt ${#c[@]} ]] && return
144     [[ -n "${c[${i}]//[-._]}" ]] && j=$(($j + 1))
145     i=$(($i + 1))
146     done
147     }
148    
149     # Get everything after the major version and its separator (if present) of a
150     # value. Defaults to $PV if no parameter is supplied.
151     # 0.8.3 -> 8.3
152     # 7c -> c
153     # 3.0_p2 -> 0_p2
154     # 20040905 -> (empty string)
155     # 3.0c-r1 -> 0c-r1
156     get_after_major_version() {
157     echo $(get_version_component_range 2- "${1:-PV}" )
158     }
159    
160     # Replace the $1th separator with $2 in $3 (defaults to $PV if $3 is not
161     # supplied). If there are fewer than $1 separators, don't change anything.
162     # 1 '_' 1.2.3 -> 1_2.3
163     # 2 '_' 1.2.3 -> 1.2_3
164     # 1 '_' 1b-2.3 -> 1b_2.3
165 ciaranm 1.3 # Rather than being a number, $1 can be a separator character such as '-', '.'
166     # or '_'. In this case, the first separator of this kind is selected.
167 ciaranm 1.1 replace_version_separator() {
168 ciaranm 1.3 local w i c found=0 v="${3:-${PV}}"
169     w=${1:-1}
170 ciaranm 1.1 c=( $(get_all_version_components ${v} ) )
171 ciaranm 1.3 if [[ "${w//[[:digit:]]/}" == "${w}" ]] ; then
172     # it's a character, not an index
173     for (( i = 0 ; i < ${#c[@]} ; i = $i + 1 )) ; do
174     if [[ "${c[${i}]}" == "${w}" ]] ; then
175 ciaranm 1.1 c[${i}]="${2}"
176     break
177     fi
178 ciaranm 1.3 done
179     else
180     for (( i = 0 ; i < ${#c[@]} ; i = $i + 1 )) ; do
181     if [[ -n "${c[${i}]//[^-._]}" ]] ; then
182     found=$(($found + 1))
183     if [[ "$found" == "${w}" ]] ; then
184     c[${i}]="${2}"
185     break
186     fi
187     fi
188     done
189     fi
190 ciaranm 1.1 c=${c[@]}
191     echo ${c// }
192     }
193    
194     # Replace all version separators in $2 (defaults to $PV) with $1.
195     # '_' 1b.2.3 -> 1b_2_3
196     replace_all_version_separators() {
197     local c
198     c=( $(get_all_version_components "${2:-${PV}}" ) )
199     c="${c[@]//[-._]/$1}"
200     echo ${c// }
201     }
202    
203 ciaranm 1.4 # Delete the $1th separator in $2 (defaults to $PV if $2 is not supplied). If
204 ciaranm 1.3 # there are fewer than $1 separators, don't change anything.
205     # 1 1.2.3 -> 12.3
206     # 2 1.2.3 -> 1.23
207     # 1 1b-2.3 -> 1b2.3
208     # Rather than being a number, $1 can be a separator character such as '-', '.'
209     # or '_'. In this case, the first separator of this kind is deleted.
210     delete_version_separator() {
211     replace_version_separator "${1}" "" "${2}"
212     }
213    
214     # Delete all version separators in $1 (defaults to $PV).
215 ciaranm 1.5 # 1b.2.3 -> 1b23
216 ciaranm 1.3 delete_all_version_separators() {
217 ciaranm 1.5 replace_all_version_separators "" "${1}"
218 ciaranm 1.3 }
219    
220 ciaranm 1.2 # Is $2 (defaults to $PVR) at least version $1? Intended for use in eclasses
221     # only. Not very reliable, doesn't understand most things, make sure you test
222     # reaaaallly well before using this. Prod ciaranm if you need it to support more
223     # things... WARNING: DOES NOT HANDLE 1.2b style versions. WARNING: not very well
224     # tested, needs lots of work before it's totally reliable. Use with extreme
225     # caution.
226     version_is_at_least() {
227     local want_s="$1" have_s="${2:-${PVR}}" want_c have_c
228     want_c=( $(get_version_components "$want_s" ) )
229     have_c=( $(get_version_components "$have_s" ) )
230    
231     # Stage 1: compare the version numbers part.
232     local done_w="" done_h="" i=0
233     while [[ -z "${done_w}" ]] || [[ -z "${done_h}" ]] ; do
234     local cur_w="${want_c[$i]}" cur_h="${have_c[$i]}"
235     [[ -z "${cur_w##[^[:digit:]]*}" ]] && done_w="yes"
236     [[ -z "${cur_h##[^[:digit:]]*}" ]] && done_h="yes"
237     [[ -z "${done_w}" ]] || cur_w=0
238     [[ -z "${done_h}" ]] || cur_h=0
239     if [[ ${cur_w} -lt ${cur_h} ]] ; then return 0 ; fi
240     if [[ ${cur_w} -gt ${cur_h} ]] ; then return 1 ; fi
241     i=$(($i + 1))
242     done
243    
244     local part
245     for part in "_alpha" "_beta" "_pre" "_rc" "_p" "-r" ; do
246     local part_w= part_h=
247    
248     for (( i = 0 ; i < ${#want_c[@]} ; i = $i + 1 )) ; do
249     if [[ -z "${want_c[$i]##${part#[-._]}*}" ]] ; then
250     part_w="${want_c[$i]##${part#[-._]}}"
251     break
252     fi
253     done
254     for (( i = 0 ; i < ${#have_c[@]} ; i = $i + 1 )) ; do
255     if [[ -z "${have_c[$i]##${part#[-._]}*}" ]] ; then
256     part_h="${have_c[$i]##${part#[-._]}}"
257     break
258     fi
259     done
260    
261     if [[ "${part}" == "_p" ]] || [[ "${part}" == "-r" ]] ; then
262     # if present in neither want nor have, go to the next item
263     [[ -z "${part_w}" ]] && [[ -z "${part_h}" ]] && continue
264    
265     [[ -z "${part_w}" ]] && [[ -n "${part_h}" ]] && return 0
266     [[ -n "${part_w}" ]] && [[ -z "${part_h}" ]] && return 1
267    
268     if [[ ${part_w} -lt ${part_h} ]] ; then return 0 ; fi
269     if [[ ${part_w} -gt ${part_h} ]] ; then return 1 ; fi
270    
271     else
272     # if present in neither want nor have, go to the next item
273     [[ -z "${part_w}" ]] && [[ -z "${part_h}" ]] && continue
274    
275     [[ -z "${part_w}" ]] && [[ -n "${part_h}" ]] && return 1
276     [[ -n "${part_w}" ]] && [[ -z "${part_h}" ]] && return 0
277    
278     if [[ ${part_w} -lt ${part_h} ]] ; then return 0 ; fi
279     if [[ ${part_w} -gt ${part_h} ]] ; then return 1 ; fi
280     fi
281     done
282    
283     return 0
284     }
285    
286     # Test function thing. To use, source versionator.eclass and then run it.
287     __versionator__test_version_is_at_least() {
288     version_is_at_least "1.2" "1.2" || echo "test 1 failed"
289     version_is_at_least "1.2" "1.2.3" || echo "test 2 failed"
290     version_is_at_least "1.2.3" "1.2" && echo "test 3 failed"
291    
292     version_is_at_least "1.2_beta1" "1.2" || echo "test 4 failed"
293     version_is_at_least "1.2_alpha1" "1.2" || echo "test 5 failed"
294     version_is_at_least "1.2_alpha1" "1.2_beta1" || echo "test 6 failed"
295    
296     version_is_at_least "1.2" "1.2_beta1" && echo "test 7 failed"
297     version_is_at_least "1.2" "1.2_alpha1" && echo "test 8 failed"
298     version_is_at_least "1.2_beta1" "1.2_alpha1" && echo "test 9 failed"
299    
300     version_is_at_least "1.2_beta1" "1.2_beta1" || echo "test 10 failed"
301     version_is_at_least "1.2_beta2" "1.2_beta1" && echo "test 11 failed"
302     version_is_at_least "1.2_beta2" "1.2_beta3" || echo "test 12 failed"
303    
304     version_is_at_least "1.2-r1" "1.2" && echo "test 13 failed"
305     version_is_at_least "1.2" "1.2-r1" || echo "test 14 failed"
306     version_is_at_least "1.2-r1" "1.3" || echo "test 15 failed"
307     version_is_at_least "1.2-r1" "1.2-r2" || echo "test 16 failed"
308     version_is_at_least "1.2-r3" "1.2-r2" && echo "test 17 failed"
309    
310     version_is_at_least "1.2-r1" "1.2_beta2-r3" && echo "test 18 failed"
311     version_is_at_least "1.2-r1" "1.3_beta2-r3" || echo "test 19 failed"
312     return 0
313     }

  ViewVC Help
Powered by ViewVC 1.1.20