source: trunk/coin-functions @ 1798

Last change on this file since 1798 was 1798, checked in by stefan, 10 years ago

use complicated way of finding last stable/releases for Data only if old-style Data project is given

File size: 16.9 KB
Line 
1
2# Utility function definitions for the various COIN scripts.
3
4# Copyright (c) 2010 Lou Hafer  Simon Fraser University
5# All Rights Reserved.
6# This file is distributed under the Common Public License.
7# It is part of the BuildTools project in COIN-OR (www.coin-or.org)
8#
9# $Id$
10
11# Functions to disassemble svn URLs and extract relevant bits, and utilities
12# to find the best (most recent) stable and release URLs, calculate libtool
13# version numbers, and compare URLs for compatibility based on major and minor
14# version. Complicated because we have to account for trunk/stable/release and
15# for the variant syntax of Data and ThirdParty URLs. For your normal project,
16# it's
17#   https://projects.coin-or.org/svn/ProjName/trunk
18#   https://projects.coin-or.org/svn/ProjName/stable/M.m
19#   https://projects.coin-or.org/svn/ProjName/releases/M.m.r
20# with the proviso that sometimes it's
21#   https://projects.coin-or.org/svn/ProjName/SubProj/trunk
22# etc.
23# For ThirdParty, it's just like a normal project, except the prefix string
24# is longer:
25#   https://projects.coin-or.org/svn/BuildTools/ThirdParty/ProjName
26# Data is the real pain, with this form:
27#  https://projects.coin-or.org/svn/Data/trunk/ProjName
28#  https://projects.coin-or.org/svn/Data/stable/M.m/ProjName
29#  https://projects.coin-or.org/svn/Data/releases/M.m.r/ProjName
30
31# Extract the COIN base from the URL, up to svn. Just in case it ever changes.
32# usage: baseURL=`extractBaseURL $svnURL`
33
34extractBaseURL ()
35{
36  exbu_baseURL=`echo $1 | sed -n -e 's|\(.*/svn\)/.*$|\1|p'`
37  echo "$exbu_baseURL"
38}
39
40
41# Extract branch type (trunk/stable/release) from the URL.
42# usage: branchType=`extractTypeFromURL $svnURL`
43
44extractTypeFromURL ()
45{
46  etfu_type="invalid"
47  case "$1" in
48    */trunk* ) etfu_type=trunk ;;
49    */stable/* ) etfu_type=stable ;;
50    */releases/* ) etfu_type=releases ;;
51  esac
52  echo $etfu_type
53}
54
55# Determine if this is a `normal' URL, defined as not Data, ThirdParty, or
56# BuildTools itself. ThirdParty lives in BuildTools as of 100628, so the
57# condition is redundant. Returns yes or no.
58# usage: isNormal=`isNormalURL $svnURL`
59
60isNormalURL ()
61{ case $1 in
62    */BuildTools/* | */ThirdParty/* | */Data/* )
63       echo "no"
64       ;;
65    *) echo "yes"
66       ;;
67  esac
68}
69
70# Extract the project from a svn URL. The trick, for `normal' projects, is to
71# handle CHiPPS, which has CHiPPS/Alps, Bcps, Blis. We can't assume the
72# project name does not contain '/'. The heuristic is to look for everything
73# between svn and one of trunk, stable, releases, or end of line.
74# usage: projName=`extractProjFromURL $svnURL`
75
76extractProjFromURL ()
77{
78  epfu_URL="$1"
79  epfu_projPat='\([^/][^/]*\)'
80  epfu_sfxPat='.*$'
81  case "$epfu_URL" in
82    */Data/trunk/* )
83        epfu_pfxPat=svn/Data/trunk/
84        ;;
85    */Data/stable/* | */Data/releases/* )
86        epfu_pfxPat='svn/Data/[^/][^/]*/[0-9][0-9.]*/'
87        ;;
88    */Data/* )
89        epfu_pfxPat='svn/Data/'
90        ;;
91    */ThirdParty/* )
92        epfu_pfxPat=svn/BuildTools/ThirdParty/
93        ;;
94    *)  epfu_type=`extractTypeFromURL $epfu_URL`
95        epfu_pfxPat='svn/'
96        epfu_projPat='\(.*\)'
97        case $epfu_type in
98          trunk | stable | releases )
99              epfu_sfxPat=$epfu_type'.*$'
100              ;;
101          * )
102              epfu_sfxPat='$'
103              ;;
104        esac
105        ;;
106  esac
107  epfu_projName=`echo $epfu_URL | sed -n -e 's|.*/'$epfu_pfxPat$epfu_projPat$epfu_sfxPat'|\1|p'`
108  epfu_projName=`echo $epfu_projName | sed -e 's|/$||'`
109  echo "$epfu_projName"
110}
111
112# Extract the tail (directory) from a URL that specifies an external. Relevant
113# only for normal projects, where the external will be a subdirectory
114# of the project. Returns null for Data / ThirdParty / BuildTools.
115# usage: projName=`extractTailFromExt $extURL`
116
117extractTailFromExt ()
118{
119  etfe_tail=
120  case "$1" in
121    */Data/* )
122        ;;
123    */BuildTools/ThirdParty/* )
124        ;;
125    */BuildTools/* )
126        ;;
127    *)
128        etfe_pfxPat=
129        case "$1" in
130          */trunk/* )
131              etfe_pfxPat='.*/trunk/'
132              ;;
133          */stable/* )
134              etfe_pfxPat='.*/stable/[0-9][0-9.]*/'
135              ;;
136          */releases/* )
137              etfe_pfxPat='.*/releases/[0-9][0-9.]*/'
138              ;;
139        esac
140        etfe_tail=`echo $1 | sed -n -e 's|'$etfe_pfxPat'\(.*\)|\1|p'`
141        ;;
142  esac
143  echo "$etfe_tail"
144}
145
146
147# CppAD uses a version string of the form YYYMMDD.rr. What a pain in the ass.
148# Hence the scattered exceptions below.
149# Extract the entire version string from a stable or release URL. Returns a
150# null string if handed a trunk URL or if there's no version in the URL. The
151# version number must have at least major.minor to match.
152# usage: version=`extractVersionFromURL $svnURL`
153
154extractVersionFromURL ()
155{
156  evfu_URL="$1"
157  if expr "$evfu_URL" : '.*/stable/.*' >/dev/null 2>&1 ||
158     expr "$evfu_URL" : '.*/releases/.*' >/dev/null 2>&1 ; then
159    if expr "$evfu_URL" : '.*/CppAD/.*' >/dev/null 2>&1 ; then
160      evfu_verPat='\([0-9][0-9.]*\)'
161    else
162      evfu_verPat='\([0-9][0-9]*\.[0-9][0-9.]*\)'
163    fi
164    evfu_sfxPat='.*$'
165    evfu_proj=`extractProjFromURL $evfu_URL`
166    case "$evfu_URL" in
167      */Data/stable/* | */Data/releases/* )
168          evfu_pfxPat='svn/Data/[^/][^/]*/'
169          ;;
170      */ThirdParty/* )
171          evfu_pfxPat='svn/BuildTools/ThirdParty/[^/][^/]*/[^/][^/]*/'
172          ;;
173      */Data/* )
174          evfu_pfxPat='svn/Data/'$evfu_proj'/[^/][^/]*/'
175          ;;
176      *)
177          evfu_pfxPat='svn/'$evfu_proj'/[^/][^/]*/'
178          ;;
179    esac
180    evfu_verVer=`echo $1 | sed -n -e 's|.*/'$evfu_pfxPat$evfu_verPat$evfu_sfxPat'|\1|p'`
181    echo "$evfu_verVer"
182  else
183    echo ""
184  fi
185}
186
187# Replace the entire version string from a stable or release URL. A trunk
188# URL will be unmodified. newRev will not be accessed unless the URL is a
189# release. The version must have at least major.minor to match.
190# usage: newURL=`replaceVersionInURL $oldURL $newMajor $newMinor $newRev`
191# and just for CppAD,
192# usage: newURL=`replaceVersionInURL $oldURL $newMajor $newRev`
193
194replaceVersionInURL ()
195{
196  if expr "$1" : '.*/CppAD/.*' >/dev/null 2>&1 ; then
197    isCppAD=yes
198  else
199    isCppAD=no
200  fi
201  if test $isCppAD = no ; then
202    rviu_verPat='[0-9][0-9]*\.[0-9][0-9.]*'
203  else
204    rviu_verPat='[0-9][0-9.]*'
205  fi
206
207  if expr "$1" : '.*/stable/.*' >/dev/null 2>&1 ; then
208    if test $isCppAD = no ; then
209      rviu_newVersion=$2.$3
210    else
211      rviu_newVersion=$2
212    fi
213  elif expr "$1" : '.*/releases/.*' >/dev/null 2>&1 ; then
214    if test $isCppAD = no ; then
215      rviu_newVersion=$2.$3.$4
216    else
217      rviu_newVersion=$2.$3
218    fi
219  else
220    rviu_newVersion=
221    rviu_newURL=$1
222  fi
223  if test -n "$rviu_newVersion" ; then
224    rviu_newURL=`echo $1 | sed -n -e 's|^\(.*\)/'$rviu_verPat'\(.*\)$|\1/'$rviu_newVersion'\2|p'`
225  fi
226  echo $rviu_newURL
227}
228
229# Extract the major version number from a stable or release URL. Returns -1 if
230# handed a trunk URL or if there's no version in the URL
231# usage: majVer=`extractMajorFromURL $svnURL`
232
233extractMajorFromURL ()
234{
235  ejfu_URL="$1"
236  if expr "$ejfu_URL" : '.*/stable/.*' >/dev/null 2>&1 ||
237     expr "$ejfu_URL" : '.*/releases/.*' >/dev/null 2>&1 ; then
238    ejfu_majPat='\([0-9][0-9]*\)'
239    if expr "$ejfu_URL" : '.*/CppAD/.*' >/dev/null 2>&1 ; then
240      ejfu_sfxPat='.*$'
241    else
242      ejfu_sfxPat='\.[0-9][0-9]*.*$'
243    fi
244    ejfu_proj=`extractProjFromURL $ejfu_URL`
245    case "$ejfu_URL" in
246      */Data/stable/* | */Data/releases/* )
247          ejfu_pfxPat='svn/Data/[^/][^/]*/'
248          ;;
249      */ThirdParty/* )
250          ejfu_pfxPat='svn/BuildTools/ThirdParty/[^/][^/]*/[^/][^/]*/'
251          ;;
252      */Data/* )
253          ejfu_pfxPat='svn/Data/'$ejfu_proj'/[^/][^/]*/'
254          ;;
255      *)
256          ejfu_pfxPat='svn/'$ejfu_proj'/[^/][^/]*/'
257          ;;
258    esac
259    ejfu_majVer=`echo $ejfu_URL | sed -n -e 's|.*/'$ejfu_pfxPat$ejfu_majPat$ejfu_sfxPat'|\1|p'`
260    echo "$ejfu_majVer"
261  else
262    echo "-1"
263  fi
264}
265
266# Extract the minor version number from a stable or release URL. Returns -1 if
267# handed a trunk URL or if there's no version in the URL.
268# The CppAD form (YYYYMMDD.rr) doesn't have a minor version number.
269# usage: minVer=`extractMinorFromURL $svnURL`
270
271extractMinorFromURL ()
272{
273  emfu_URL="$1"
274  if expr "$emfu_URL" : '.*/CppAD/.*' >/dev/null 2>&1 ; then
275    echo "-1"
276  elif expr "$emfu_URL" : '.*/stable/.*' >/dev/null 2>&1 ||
277       expr "$emfu_URL" : '.*/releases/.*' >/dev/null 2>&1 ; then
278    emfu_minPat='[0-9][0-9]*\.\([0-9][0-9]*\)'
279    emfu_sfxPat='.*$'
280    emfu_proj=`extractProjFromURL $emfu_URL`
281    case "$emfu_URL" in
282      */Data/stable/* | */Data/releases/* )
283          emfu_pfxPat='svn/Data/[^/][^/]*/'
284          ;;
285      */ThirdParty/* )
286          emfu_pfxPat='svn/BuildTools/ThirdParty/[^/][^/]*/[^/][^/]*/'
287          ;;
288      */Data/* )
289          emfu_pfxPat='svn/Data/'$emfu_proj'/[^/][^/]*/'
290          ;;
291      *)
292          emfu_pfxPat='svn/'$emfu_proj'/[^/][^/]*/'
293          ;;
294    esac
295    emfu_minVer=`echo $emfu_URL | sed -n -e 's|.*/'$emfu_pfxPat$emfu_minPat$emfu_sfxPat'|\1|p'`
296    echo "$emfu_minVer"
297  else
298    echo "-1"
299  fi
300}
301
302# Extract the release (revision) number from a release URL. Returns -1 if
303# handed a trunk or stable URL
304# usage: minVer=`extractReleaseFromURL $svnURL`
305
306extractReleaseFromURL ()
307{
308  erfu_URL="$1"
309  if expr "$erfu_URL" : '.*/releases/.*' >/dev/null 2>&1 ; then
310    if expr "$erfu_URL" : '.*/CppAD/.*' >/dev/null 2>&1 ; then
311      erfu_relPat='[0-9][0-9]*\.\([0-9][0-9]*\)'
312    else
313      erfu_relPat='[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\)'
314    fi
315    erfu_sfxPat='.*$'
316    erfu_proj=`extractProjFromURL $erfu_URL`
317    case "$erfu_URL" in
318      */Data/releases/* )
319          erfu_pfxPat='svn/Data/[^/][^/]*/'
320          ;;
321      */ThirdParty/* )
322          erfu_pfxPat='svn/BuildTools/ThirdParty/[^/][^/]*/[^/][^/]*/'
323          ;;
324      */Data/*)
325          erfu_pfxPat='svn/Data/'$erfu_proj'/[^/][^/]*/'
326          ;;
327      *)
328          erfu_pfxPat='svn/'$erfu_proj'/[^/][^/]*/'
329          ;;
330    esac
331    erfu_relVer=`echo $erfu_URL | sed -n -e 's|.*/'$erfu_pfxPat$erfu_relPat$erfu_sfxPat'|\1|p'`
332    echo "$erfu_relVer"
333  else
334    echo "-1"
335  fi
336}
337
338# Now some functions to locate the highest-numbered stable or release.
339
340# Return the URL of the most recent stable branch matching the parameters.
341# A value of -1 for major or minor version is interpreted as `highest number'
342# Returns an empty string if no suitable stable branch exists.
343# usage: stableURL=`bestStable <URL> <major>`
344
345bestStable ()
346{ bstb_URL=$1
347  bstb_majVer=$2
348
349  # Construct a URL to send to the repository to list the stable branches.
350
351  bstb_baseURL=`extractBaseURL $bstb_URL`
352  bstb_proj=`extractProjFromURL $bstb_URL`
353
354  case "$bstb_URL" in
355    */Data/* )
356        bstb_listURL=$bstb_baseURL/Data/stable
357        ;;
358    */ThirdParty/* )
359        bstb_listURL=$bstb_baseURL/BuildTools/ThirdParty/$bstb_proj/stable
360        ;;
361    * )
362        bstb_listURL=$bstb_baseURL/$bstb_proj/stable
363        ;;
364  esac
365
366  bstb_rawls=`svn list $bstb_listURL | sort -nr -t. -k1,1 -k2,2`
367
368  # echo "Raw ls: $bstb_rawls"
369
370  # Filter the list of stable branches to remove any that do not match the
371  # requested major version. Note that there's a / at the end of each URL.
372
373  if test "$bstb_majVer" = "-1" ; then
374    bstb_verPat='[0-9][0-9.]*/'
375  elif expr "$bstb_URL" : '.*/CppAD/.*' >/dev/null 2>&1 ; then
376    bstb_verPat=$bstb_majVer'/'
377  else
378    bstb_verPat=$bstb_majVer'\.[0-9][0-9]*'
379  fi
380  bstb_filter=
381  for bstb_ver in $bstb_rawls ; do
382    if  expr "$bstb_ver" : $bstb_verPat >/dev/null 2>&1 ; then
383      bstb_filter="$bstb_filter $bstb_ver"
384    fi
385  done
386
387  # echo "Filtered ls: $bstb_filter"
388
389  # If there are any candidates left ...
390
391  bstb_bestURL=
392  if test -n "$bstb_filter" ; then
393
394    # If we're dealing with old-style Data, we have to work a bit harder to find our
395    # project. See if any of the filtered candidates contain the correct
396    # project.
397
398    case "$bstb_URL" in
399      */Data/trunk/* | */Data/stable/* | */Data/releases/* )
400        bstb_projPat='.*'$bstb_proj'/.*'
401        # echo "Pattern: $bstb_projPat"
402        for bstb_ver in $bstb_filter ; do
403          if  expr "$bstb_ver" : $bstb_verPat >/dev/null 2>&1 ; then
404            # echo "  url: $bstb_listURL/$bstb_ver"
405            bstb_svnls2="`svn list $bstb_listURL/$bstb_ver`"
406            # echo "  result: $bstb_svnls2"
407            if expr "$bstb_svnls2" : $bstb_projPat >/dev/null 2>&1 ; then
408              bstb_best=$bstb_ver
409              # echo "  best: $bstb_best"
410              break
411            fi
412          fi
413        done
414        bstb_bestURL=$bstb_listURL/$bstb_best$bstb_proj
415      ;;
416      *)
417        bstb_bestURL=`echo $bstb_filter | sed -n -e 's|\([^/]*/\).*$|\1|p'`
418        bstb_bestURL=$bstb_listURL/$bstb_bestURL
419      ;;
420    esac
421  fi
422
423  echo $bstb_bestURL
424}
425
426# Return the URL of the most recent release matching the parameters. Returns
427# null if no suitable release exists.
428# A value of -1 for major or minor version is interpreted as `highest number'
429# A value of -1 for major version means that minor version is ignored.
430# usage: releaseURL=`bestRelease <URL> <major> <minor>`
431
432bestRelease ()
433{ bstb_URL=$1
434  bstb_majVer=$2
435  bstb_minVer=$3
436
437  # Construct a URL to send to the repository to list the releases.
438
439  bstb_baseURL=`extractBaseURL $bstb_URL`
440  bstb_proj=`extractProjFromURL $bstb_URL`
441
442  case "$bstb_URL" in
443    */Data/* )
444        bstb_listURL=$bstb_baseURL/Data/$bstb_proj/releases
445        ;;
446    */ThirdParty/* )
447        bstb_listURL=$bstb_baseURL/BuildTools/ThirdParty/$bstb_proj/releases
448        ;;
449    * )
450        bstb_listURL=$bstb_baseURL/$bstb_proj/releases
451        ;;
452  esac
453
454  bstb_rawls=`svn list $bstb_listURL | sort -nr -t. -k1,1 -k2,2 -k3,3`
455
456  # echo "Raw ls: $bstb_rawls"
457
458  # Filter the list of releases to remove any that do not match the
459  # requested major and minor version.
460
461  if expr "$bstb_URL" : '.*/CppAD/.*' >/dev/null 2>&1 ; then
462    isCppAD=yes
463  else
464    isCppAD=no
465  fi
466
467  if test "$bstb_majVer" = "-1" ; then
468    bstb_verPat='[0-9][0-9.]*/'
469  else
470    bstb_verPat=$bstb_majVer
471    if test $isCppAD = no &&
472       test "$bstb_minVer" != "-1" ; then
473      bstb_verPat="${bstb_verPat}\.$bstb_minVer"
474    fi
475    bstb_verPat="${bstb_verPat}"'\.[0-9][0-9]*/'
476  fi
477
478  # echo "Version pattern: $bstb_verPat"
479  bstb_filter=
480  for bstb_ver in $bstb_rawls ; do
481    if  expr "$bstb_ver" : $bstb_verPat >/dev/null 2>&1 ; then
482      bstb_filter="$bstb_filter $bstb_ver"
483    fi
484  done
485
486  # echo "Filtered ls: $bstb_filter"
487
488  # If there are any candidates left ...
489
490  bstb_bestURL=
491  if test -n "$bstb_filter" ; then
492
493    # If we're dealing with old-style Data, we have to work a bit harder to find our
494    # project. See if any of the filtered candidates contain the correct
495    # project.
496
497    case "$bstb_URL" in
498      */Data/trunk/* | */Data/stable/* | */Data/releases/* )
499        bstb_projPat='.*'$bstb_proj'/.*'
500        # echo "Pattern: $bstb_projPat"
501        for bstb_ver in $bstb_filter ; do
502          if  expr "$bstb_ver" : $bstb_verPat >/dev/null 2>&1 ; then
503            # echo "  url: $bstb_listURL/$bstb_ver"
504            bstb_svnls2="`svn list $bstb_listURL/$bstb_ver`"
505            # echo "  result: $bstb_svnls2"
506            if expr "$bstb_svnls2" : $bstb_projPat >/dev/null 2>&1 ; then
507              bstb_best=$bstb_ver
508              # echo "  best: $bstb_best"
509              break
510            fi
511          fi
512        done
513        bstb_bestURL=$bstb_listURL/$bstb_best$bstb_proj
514      ;;
515      *)
516        bstb_bestURL=`echo $bstb_filter | sed -n -e 's|\([^/]*/\).*$|\1|p'`
517        bstb_bestURL=$bstb_listURL/$bstb_bestURL
518      ;;
519    esac
520
521  fi
522
523  echo $bstb_bestURL
524}
525
526# Count the total number of stable branches for the project for the specified
527# major version number (libtool age). A major version number of -1 means all
528# stable branches (libtool current; see next function). Returns 0 if handed
529# a trunk url, or if the url is Data or BuildTools itself.
530# usage: calcLibtoolAge <svnURL> <major>
531
532calcLibtoolAge ()
533{ cltc_URL=$1
534  cltc_majVer=$2
535
536  # Construct a URL to send to the repository to list the stable branches.
537
538  cltc_baseURL=`extractBaseURL $cltc_URL`
539  cltc_proj=`extractProjFromURL $cltc_URL`
540
541  case "$cltc_URL" in
542    */Data/* )
543        cltc_listURL=
544        ;;
545    */ThirdParty/* )
546        cltc_listURL=$cltc_baseURL/BuildTools/ThirdParty/$cltc_proj/stable
547        ;;
548    */BuildTools/* )
549        cltc_listURL=
550        ;;
551    * )
552        cltc_listURL=$cltc_baseURL/$cltc_proj/stable
553        ;;
554  esac
555
556  # Run an ls and filter for standard stable branches (M.m or YYYYMMDD)
557
558  if test -n "$cltc_listURL" ; then
559    cltc_rawls=`svn list $cltc_listURL | sed -n -e '/[0-9][0-9.]/p'`
560
561    # echo "Raw ls: $cltc_rawls"
562
563    # Filter the list of stable branches to remove any that do not match the
564    # requested major version. -1 means `any major version', hence no filter.
565
566    if test "$cltc_majVer" != "-1" ; then
567      if expr "$cltc_URL" : '.*/CppAD/.*' >/dev/null 2>&1 ; then
568        cltc_verPat=$cltc_majVer
569      else
570        cltc_verPat=$cltc_majVer'\.[0-9][0-9]*'
571      fi
572    else
573      cltc_verPat='[0-9][0-9.]*'
574    fi
575    cltc_filter=
576    for cltc_ver in $cltc_rawls ; do
577      if  expr "$cltc_ver" : $cltc_verPat >/dev/null 2>&1 ; then
578        cltc_filter="$cltc_filter $cltc_ver"
579      fi
580    done
581
582    # echo "Filtered ls: $cltc_filter"
583
584    cltc_cnt=`echo $cltc_filter | wc -w | sed -e 's/ //g'`
585  else
586    cltc_cnt=0
587  fi
588
589  echo $cltc_cnt
590}
591
592# Function to compare the versions in a pair of URLs for equality. The criteria
593# is that the major and minor versions match. In theory, the release should
594# not matter. Probably should be a parameter.
595# usage: compareURLVersions <url1> <url2>
596
597compareURLVersions ()
598{
599  url1_major=`extractMajorFromURL $1`
600  url1_minor=`extractMinorFromURL $1`
601  url2_major=`extractMajorFromURL $2`
602  url2_minor=`extractMinorFromURL $2`
603
604  if test $url1_major = $url2_major &&
605     test $url1_minor = $url2_minor ; then
606    echo "yes"
607  else
608    echo "no"
609  fi
610}
611
Note: See TracBrowser for help on using the repository browser.