source: trunk/coin-functions @ 1797

Last change on this file since 1797 was 1797, checked in by stefan, 11 years ago

fixes to deal with changed organization of data projects

File size: 16.8 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 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    if expr "$bstb_URL" : '.*/Data/.*' >/dev/null 2>&1 ; then
399      bstb_projPat='.*'$bstb_proj'/.*'
400      # echo "Pattern: $bstb_projPat"
401      for bstb_ver in $bstb_filter ; do
402        if  expr "$bstb_ver" : $bstb_verPat >/dev/null 2>&1 ; then
403          # echo "  url: $bstb_listURL/$bstb_ver"
404          bstb_svnls2="`svn list $bstb_listURL/$bstb_ver`"
405          # echo "  result: $bstb_svnls2"
406          if expr "$bstb_svnls2" : $bstb_projPat >/dev/null 2>&1 ; then
407            bstb_best=$bstb_ver
408            # echo "  best: $bstb_best"
409            break
410          fi
411        fi
412      done
413      bstb_bestURL=$bstb_listURL/$bstb_best$bstb_proj
414    else
415      bstb_bestURL=`echo $bstb_filter | sed -n -e 's|\([^/]*/\).*$|\1|p'`
416      bstb_bestURL=$bstb_listURL/$bstb_bestURL
417    fi
418
419  fi
420
421  echo $bstb_bestURL
422}
423
424# Return the URL of the most recent release matching the parameters. Returns
425# null if no suitable release exists.
426# A value of -1 for major or minor version is interpreted as `highest number'
427# A value of -1 for major version means that minor version is ignored.
428# usage: releaseURL=`bestRelease <URL> <major> <minor>`
429
430bestRelease ()
431{ bstb_URL=$1
432  bstb_majVer=$2
433  bstb_minVer=$3
434
435  # Construct a URL to send to the repository to list the releases.
436
437  bstb_baseURL=`extractBaseURL $bstb_URL`
438  bstb_proj=`extractProjFromURL $bstb_URL`
439
440  case "$bstb_URL" in
441    */Data/* )
442        bstb_listURL=$bstb_baseURL/Data/$bstb_proj/releases
443        ;;
444    */ThirdParty/* )
445        bstb_listURL=$bstb_baseURL/BuildTools/ThirdParty/$bstb_proj/releases
446        ;;
447    * )
448        bstb_listURL=$bstb_baseURL/$bstb_proj/releases
449        ;;
450  esac
451
452  bstb_rawls=`svn list $bstb_listURL | sort -nr -t. -k1,1 -k2,2 -k3,3`
453
454  # echo "Raw ls: $bstb_rawls"
455
456  # Filter the list of releases to remove any that do not match the
457  # requested major and minor version.
458
459  if expr "$bstb_URL" : '.*/CppAD/.*' >/dev/null 2>&1 ; then
460    isCppAD=yes
461  else
462    isCppAD=no
463  fi
464
465  if test "$bstb_majVer" = "-1" ; then
466    bstb_verPat='[0-9][0-9.]*/'
467  else
468    bstb_verPat=$bstb_majVer
469    if test $isCppAD = no &&
470       test "$bstb_minVer" != "-1" ; then
471      bstb_verPat="${bstb_verPat}\.$bstb_minVer"
472    fi
473    bstb_verPat="${bstb_verPat}"'\.[0-9][0-9]*/'
474  fi
475
476  # echo "Version pattern: $bstb_verPat"
477  bstb_filter=
478  for bstb_ver in $bstb_rawls ; do
479    if  expr "$bstb_ver" : $bstb_verPat >/dev/null 2>&1 ; then
480      bstb_filter="$bstb_filter $bstb_ver"
481    fi
482  done
483
484  # echo "Filtered ls: $bstb_filter"
485
486  # If there are any candidates left ...
487
488  bstb_bestURL=
489  if test -n "$bstb_filter" ; then
490
491    # If we're dealing with Data, we have to work a bit harder to find our
492    # project. See if any of the filtered candidates contain the correct
493    # project.
494
495    if expr "$bstb_URL" : '.*/Data/.*' >/dev/null 2>&1 ; then
496      bstb_projPat='.*'$bstb_proj'/.*'
497      # echo "Pattern: $bstb_projPat"
498      for bstb_ver in $bstb_filter ; do
499        if  expr "$bstb_ver" : $bstb_verPat >/dev/null 2>&1 ; then
500          # echo "  url: $bstb_listURL/$bstb_ver"
501          bstb_svnls2="`svn list $bstb_listURL/$bstb_ver`"
502          # echo "  result: $bstb_svnls2"
503          if expr "$bstb_svnls2" : $bstb_projPat >/dev/null 2>&1 ; then
504            bstb_best=$bstb_ver
505            # echo "  best: $bstb_best"
506            break
507          fi
508        fi
509      done
510      bstb_bestURL=$bstb_listURL/$bstb_best$bstb_proj
511    else
512      bstb_bestURL=`echo $bstb_filter | sed -n -e 's|\([^/]*/\).*$|\1|p'`
513      bstb_bestURL=$bstb_listURL/$bstb_bestURL
514    fi
515
516  fi
517
518  echo $bstb_bestURL
519}
520
521# Count the total number of stable branches for the project for the specified
522# major version number (libtool age). A major version number of -1 means all
523# stable branches (libtool current; see next function). Returns 0 if handed
524# a trunk url, or if the url is Data or BuildTools itself.
525# usage: calcLibtoolAge <svnURL> <major>
526
527calcLibtoolAge ()
528{ cltc_URL=$1
529  cltc_majVer=$2
530
531  # Construct a URL to send to the repository to list the stable branches.
532
533  cltc_baseURL=`extractBaseURL $cltc_URL`
534  cltc_proj=`extractProjFromURL $cltc_URL`
535
536  case "$cltc_URL" in
537    */Data/* )
538        cltc_listURL=
539        ;;
540    */ThirdParty/* )
541        cltc_listURL=$cltc_baseURL/BuildTools/ThirdParty/$cltc_proj/stable
542        ;;
543    */BuildTools/* )
544        cltc_listURL=
545        ;;
546    * )
547        cltc_listURL=$cltc_baseURL/$cltc_proj/stable
548        ;;
549  esac
550
551  # Run an ls and filter for standard stable branches (M.m or YYYYMMDD)
552
553  if test -n "$cltc_listURL" ; then
554    cltc_rawls=`svn list $cltc_listURL | sed -n -e '/[0-9][0-9.]/p'`
555
556    # echo "Raw ls: $cltc_rawls"
557
558    # Filter the list of stable branches to remove any that do not match the
559    # requested major version. -1 means `any major version', hence no filter.
560
561    if test "$cltc_majVer" != "-1" ; then
562      if expr "$cltc_URL" : '.*/CppAD/.*' >/dev/null 2>&1 ; then
563        cltc_verPat=$cltc_majVer
564      else
565        cltc_verPat=$cltc_majVer'\.[0-9][0-9]*'
566      fi
567    else
568      cltc_verPat='[0-9][0-9.]*'
569    fi
570    cltc_filter=
571    for cltc_ver in $cltc_rawls ; do
572      if  expr "$cltc_ver" : $cltc_verPat >/dev/null 2>&1 ; then
573        cltc_filter="$cltc_filter $cltc_ver"
574      fi
575    done
576
577    # echo "Filtered ls: $cltc_filter"
578
579    cltc_cnt=`echo $cltc_filter | wc -w | sed -e 's/ //g'`
580  else
581    cltc_cnt=0
582  fi
583
584  echo $cltc_cnt
585}
586
587# Function to compare the versions in a pair of URLs for equality. The criteria
588# is that the major and minor versions match. In theory, the release should
589# not matter. Probably should be a parameter.
590# usage: compareURLVersions <url1> <url2>
591
592compareURLVersions ()
593{
594  url1_major=`extractMajorFromURL $1`
595  url1_minor=`extractMinorFromURL $1`
596  url2_major=`extractMajorFromURL $2`
597  url2_minor=`extractMinorFromURL $2`
598
599  if test $url1_major = $url2_major &&
600     test $url1_minor = $url2_minor ; then
601    echo "yes"
602  else
603    echo "no"
604  fi
605}
606
Note: See TracBrowser for help on using the repository browser.