Merge

Thu, 17 Jul 2014 22:45:46 +0100

author
robm
date
Thu, 17 Jul 2014 22:45:46 +0100
changeset 1151
3f1b7ff6136f
parent 1150
8ea4d201cb35
parent 1149
de457bd243b4
child 1152
2c08ede0f740

Merge

     1.1 --- a/common/bin/hgforest.sh	Thu Jul 17 18:01:58 2014 +0100
     1.2 +++ b/common/bin/hgforest.sh	Thu Jul 17 22:45:46 2014 +0100
     1.3 @@ -1,7 +1,6 @@
     1.4  #!/bin/sh
     1.5 -
     1.6  #
     1.7 -# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
     1.8 +# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
     1.9  # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    1.10  #
    1.11  # This code is free software; you can redistribute it and/or modify it
    1.12 @@ -23,165 +22,375 @@
    1.13  # questions.
    1.14  #
    1.15  
    1.16 -# Shell script for a fast parallel forest command
    1.17 -command="$1"
    1.18 -pull_extra_base="$2"
    1.19 +# Shell script for a fast parallel forest/trees command
    1.20  
    1.21 -if [ "" = "$command" ] ; then
    1.22 -  echo No command to hg supplied!
    1.23 -  exit 1
    1.24 +usage() {
    1.25 +      echo "usage: $0 [-h|--help] [-q|--quiet] [-v|--verbose] [-s|--sequential] [--] <command> [commands...]" > ${status_output}
    1.26 +      echo "Environment variables which modify behaviour:"
    1.27 +      echo "   HGFOREST_QUIET      : (boolean) If 'true' then standard output is redirected to /dev/null"
    1.28 +      echo "   HGFOREST_VERBOSE    : (boolean) If 'true' then Mercurial asked to produce verbose output"
    1.29 +      echo "   HGFOREST_SEQUENTIAL : (boolean) If 'true' then repos are processed sequentially. Disables concurrency"
    1.30 +      echo "   HGFOREST_GLOBALOPTS : (string, must begin with space) Additional Mercurial global options"
    1.31 +      echo "   HGFOREST_REDIRECT   : (file path) Redirect standard output to specified file"
    1.32 +      echo "   HGFOREST_FIFOS      : (boolean) Default behaviour for FIFO detection. Does not override FIFOs disabled"
    1.33 +      echo "   HGFOREST_CONCURRENCY: (positive integer) Number of repos to process concurrently"
    1.34 +      echo "   HGFOREST_DEBUG      : (boolean) If 'true' then temp files are retained"
    1.35 +      exit 1
    1.36 +}
    1.37 +
    1.38 +global_opts="${HGFOREST_GLOBALOPTS:-}"
    1.39 +status_output="${HGFOREST_REDIRECT:-/dev/stdout}"
    1.40 +qflag="${HGFOREST_QUIET:-false}"
    1.41 +vflag="${HGFOREST_VERBOSE:-false}"
    1.42 +sflag="${HGFOREST_SEQUENTIAL:-false}"
    1.43 +while [ $# -gt 0 ]
    1.44 +do
    1.45 +  case $1 in
    1.46 +    -h | --help )
    1.47 +      usage
    1.48 +      ;;
    1.49 +
    1.50 +    -q | --quiet )
    1.51 +      qflag="true"
    1.52 +      ;;
    1.53 +
    1.54 +    -v | --verbose )
    1.55 +      vflag="true"
    1.56 +      ;;
    1.57 +
    1.58 +    -s | --sequential )
    1.59 +      sflag="true"
    1.60 +      ;;
    1.61 +
    1.62 +    '--' ) # no more options
    1.63 +      shift; break
    1.64 +      ;;
    1.65 +
    1.66 +    -*)  # bad option
    1.67 +      usage
    1.68 +      ;;
    1.69 +
    1.70 +     * )  # non option
    1.71 +      break
    1.72 +      ;;
    1.73 +  esac
    1.74 +  shift
    1.75 +done
    1.76 +
    1.77 +# silence standard output?
    1.78 +if [ ${qflag} = "true" ] ; then
    1.79 +  global_opts="${global_opts} -q"
    1.80 +  status_output="/dev/null"
    1.81  fi
    1.82  
    1.83 +# verbose output?
    1.84 +if [ ${vflag} = "true" ] ; then
    1.85 +  global_opts="${global_opts} -v"
    1.86 +fi
    1.87 +
    1.88 +# Make sure we have a command.
    1.89 +if [ $# -lt 1 -o -z "${1:-}" ] ; then
    1.90 +  echo "ERROR: No command to hg supplied!"
    1.91 +  usage
    1.92 +fi
    1.93 +
    1.94 +command="$1"; shift
    1.95 +command_args="${@:-}"
    1.96 +
    1.97  # Clean out the temporary directory that stores the pid files.
    1.98  tmp=/tmp/forest.$$
    1.99  rm -f -r ${tmp}
   1.100  mkdir -p ${tmp}
   1.101  
   1.102 +
   1.103 +if [ "${HGFOREST_DEBUG:-false}" = "true" ] ; then
   1.104 +  echo "DEBUG: temp files are in: ${tmp}"
   1.105 +fi
   1.106 +
   1.107 +# Check if we can use fifos for monitoring sub-process completion.
   1.108 +echo "1" > ${tmp}/read
   1.109 +while_subshell=1
   1.110 +while read line; do
   1.111 +  while_subshell=0
   1.112 +  break;
   1.113 +done < ${tmp}/read
   1.114 +rm ${tmp}/read
   1.115 +
   1.116 +on_windows=`uname -s | egrep -ic -e 'cygwin|msys'`
   1.117 +
   1.118 +if [ ${while_subshell} = "1" -o ${on_windows} = "1" ]; then
   1.119 +  # cygwin has (2014-04-18) broken (single writer only) FIFOs
   1.120 +  # msys has (2014-04-18) no FIFOs.
   1.121 +  # older shells create a sub-shell for redirect to while
   1.122 +  have_fifos="false"
   1.123 +else
   1.124 +  have_fifos="${HGFOREST_FIFOS:-true}"
   1.125 +fi
   1.126 +
   1.127  safe_interrupt () {
   1.128    if [ -d ${tmp} ]; then
   1.129      if [ "`ls ${tmp}/*.pid`" != "" ]; then
   1.130 -      echo "Waiting for processes ( `cat ${tmp}/*.pid | tr '\n' ' '`) to terminate nicely!"
   1.131 +      echo "Waiting for processes ( `cat ${tmp}/.*.pid ${tmp}/*.pid 2> /dev/null | tr '\n' ' '`) to terminate nicely!" > ${status_output}
   1.132        sleep 1
   1.133        # Pipe stderr to dev/null to silence kill, that complains when trying to kill
   1.134        # a subprocess that has already exited.
   1.135        kill -TERM `cat ${tmp}/*.pid | tr '\n' ' '` 2> /dev/null
   1.136        wait
   1.137 -      echo Interrupt complete!
   1.138 +      echo "Interrupt complete!" > ${status_output}
   1.139      fi
   1.140 +    rm -f -r ${tmp}
   1.141    fi
   1.142 -  rm -f -r ${tmp}
   1.143 -  exit 1
   1.144 +  exit 130
   1.145  }
   1.146  
   1.147  nice_exit () {
   1.148    if [ -d ${tmp} ]; then
   1.149 -    if [ "`ls ${tmp}`" != "" ]; then
   1.150 +    if [ "`ls -A ${tmp} 2> /dev/null`" != "" ]; then
   1.151        wait
   1.152      fi
   1.153 +    if [ "${HGFOREST_DEBUG:-false}" != "true" ] ; then
   1.154 +      rm -f -r ${tmp}
   1.155 +    fi
   1.156    fi
   1.157 -  rm -f -r ${tmp}
   1.158  }
   1.159  
   1.160  trap 'safe_interrupt' INT QUIT
   1.161  trap 'nice_exit' EXIT
   1.162  
   1.163 +subrepos="corba jaxp jaxws langtools jdk hotspot nashorn"
   1.164 +subrepos_extra="jdk/src/closed jdk/make/closed jdk/test/closed hotspot/make/closed hotspot/src/closed hotspot/test/closed deploy install sponsors pubs"
   1.165 +
   1.166  # Only look in specific locations for possible forests (avoids long searches)
   1.167  pull_default=""
   1.168  repos=""
   1.169  repos_extra=""
   1.170 -if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
   1.171 -  subrepos="corba jaxp jaxws langtools jdk hotspot nashorn"
   1.172 -  if [ -f .hg/hgrc ] ; then
   1.173 -    pull_default=`hg paths default`
   1.174 -    if [ "${pull_default}" = "" ] ; then
   1.175 -      echo "ERROR: Need initial clone with 'hg paths default' defined"
   1.176 -      exit 1
   1.177 -    fi
   1.178 -  fi
   1.179 -  if [ "${pull_default}" = "" ] ; then
   1.180 -    echo "ERROR: Need initial repository to use this script"
   1.181 +if [ "${command}" = "clone" -o "${command}" = "fclone" -o "${command}" = "tclone" ] ; then
   1.182 +  # we must be a clone
   1.183 +  if [ ! -f .hg/hgrc ] ; then
   1.184 +    echo "ERROR: Need initial repository to use this script" > ${status_output}
   1.185      exit 1
   1.186    fi
   1.187 +
   1.188 +  # the clone must know where it came from (have a default pull path).
   1.189 +  pull_default=`hg paths default`
   1.190 +  if [ "${pull_default}" = "" ] ; then
   1.191 +    echo "ERROR: Need initial clone with 'hg paths default' defined" > ${status_output}
   1.192 +    exit 1
   1.193 +  fi
   1.194 +
   1.195 +  # determine which sub repos need to be cloned.
   1.196    for i in ${subrepos} ; do
   1.197      if [ ! -f ${i}/.hg/hgrc ] ; then
   1.198        repos="${repos} ${i}"
   1.199      fi
   1.200    done
   1.201 -  if [ "${pull_extra_base}" != "" ] ; then
   1.202 -    subrepos_extra="jdk/src/closed jdk/make/closed jdk/test/closed hotspot/make/closed hotspot/src/closed hotspot/test/closed deploy install sponsors pubs"
   1.203 -    pull_default_tail=`echo ${pull_default} | sed -e 's@^.*://[^/]*/\(.*\)@\1@'`
   1.204 -    pull_extra="${pull_extra_base}/${pull_default_tail}"
   1.205 +
   1.206 +  pull_default_tail=`echo ${pull_default} | sed -e 's@^.*://[^/]*/\(.*\)@\1@'`
   1.207 +
   1.208 +  if [ -n "${command_args}" ] ; then
   1.209 +    # if there is an "extra sources" path then reparent "extra" repos to that path
   1.210 +    if [ "x${pull_default}" = "x${pull_default_tail}" ] ; then
   1.211 +      echo "ERROR: Need initial clone from non-local source" > ${status_output}
   1.212 +      exit 1
   1.213 +    fi
   1.214 +    pull_extra="${command_args}/${pull_default_tail}"
   1.215 +
   1.216 +    # determine which extra subrepos need to be cloned.
   1.217      for i in ${subrepos_extra} ; do
   1.218        if [ ! -f ${i}/.hg/hgrc ] ; then
   1.219          repos_extra="${repos_extra} ${i}"
   1.220        fi
   1.221      done
   1.222 +  else
   1.223 +    if [ "x${pull_default}" = "x${pull_default_tail}" ] ; then
   1.224 +      # local source repo. Clone the "extra" subrepos that exist there.
   1.225 +      for i in ${subrepos_extra} ; do
   1.226 +        if [ -f ${pull_default}/${i}/.hg/hgrc -a ! -f ${i}/.hg/hgrc ] ; then
   1.227 +          # sub-repo there in source but not here
   1.228 +          repos_extra="${repos_extra} ${i}"
   1.229 +        fi
   1.230 +      done
   1.231 +    fi
   1.232    fi
   1.233 -  at_a_time=2
   1.234 +
   1.235    # Any repos to deal with?
   1.236    if [ "${repos}" = "" -a "${repos_extra}" = "" ] ; then
   1.237 +    echo "No repositories to process." > ${status_output}
   1.238      exit
   1.239    fi
   1.240 +
   1.241 +  # Repos to process concurrently. Clone does better with low concurrency.
   1.242 +  at_a_time="${HGFOREST_CONCURRENCY:-2}"
   1.243  else
   1.244 -  hgdirs=`ls -d ./.hg ./*/.hg ./*/*/.hg ./*/*/*/.hg ./*/*/*/*/.hg 2>/dev/null`
   1.245 -  # Derive repository names from the .hg directory locations
   1.246 -  for i in ${hgdirs} ; do
   1.247 -    repos="${repos} `echo ${i} | sed -e 's@/.hg$@@'`"
   1.248 +  # Process command for all of the present repos
   1.249 +  for i in . ${subrepos} ${subrepos_extra} ; do
   1.250 +    if [ -d ${i}/.hg ] ; then
   1.251 +      repos="${repos} ${i}"
   1.252 +    fi
   1.253    done
   1.254 +
   1.255 +  # Any repos to deal with?
   1.256 +  if [ "${repos}" = "" ] ; then
   1.257 +    echo "No repositories to process." > ${status_output}
   1.258 +    exit
   1.259 +  fi
   1.260 +
   1.261 +  # any of the repos locked?
   1.262 +  locked=""
   1.263    for i in ${repos} ; do
   1.264      if [ -h ${i}/.hg/store/lock -o -f ${i}/.hg/store/lock ] ; then
   1.265        locked="${i} ${locked}"
   1.266      fi
   1.267    done
   1.268 -  at_a_time=8
   1.269 -  # Any repos to deal with?
   1.270 -  if [ "${repos}" = "" ] ; then
   1.271 -    echo "No repositories to process."
   1.272 -    exit
   1.273 +  if [ "${locked}" != "" ] ; then
   1.274 +    echo "ERROR: These repositories are locked: ${locked}" > ${status_output}
   1.275 +    exit 1
   1.276    fi
   1.277 -  if [ "${locked}" != "" ] ; then
   1.278 -    echo "These repositories are locked: ${locked}"
   1.279 -    exit
   1.280 -  fi
   1.281 +
   1.282 +  # Repos to process concurrently.
   1.283 +  at_a_time="${HGFOREST_CONCURRENCY:-8}"
   1.284  fi
   1.285  
   1.286  # Echo out what repositories we do a command on.
   1.287 -echo "# Repositories: ${repos} ${repos_extra}"
   1.288 -echo
   1.289 +echo "# Repositories: ${repos} ${repos_extra}" > ${status_output}
   1.290  
   1.291 -# Run the supplied command on all repos in parallel.
   1.292 -n=0
   1.293 -for i in ${repos} ${repos_extra} ; do
   1.294 -  n=`expr ${n} '+' 1`
   1.295 -  repopidfile=`echo ${i} | sed -e 's@./@@' -e 's@/@_@g'`
   1.296 -  reponame=`echo ${i} | sed -e :a -e 's/^.\{1,20\}$/ &/;ta'`
   1.297 -  pull_base="${pull_default}"
   1.298 -  for j in $repos_extra ; do
   1.299 -      if [ "$i" = "$j" ] ; then
   1.300 -          pull_base="${pull_extra}"
   1.301 -      fi
   1.302 -  done
   1.303 +if [ "${command}" = "serve" ] ; then
   1.304 +  # "serve" is run for all the repos as one command.
   1.305    (
   1.306      (
   1.307 -      if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
   1.308 -        pull_newrepo="`echo ${pull_base}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`"
   1.309 -        echo hg clone ${pull_newrepo} ${i}
   1.310 -        path="`dirname ${i}`"
   1.311 -        if [ "${path}" != "." ] ; then
   1.312 -          times=0
   1.313 -          while [ ! -d "${path}" ]   ## nested repo, ensure containing dir exists
   1.314 -          do
   1.315 -            times=`expr ${times} '+' 1`
   1.316 -            if [ `expr ${times} '%' 10` -eq 0 ] ; then
   1.317 -              echo ${path} still not created, waiting...
   1.318 +      cwd=`pwd`
   1.319 +      serving=`basename ${cwd}`
   1.320 +      (
   1.321 +        echo "[web]"
   1.322 +        echo "description = ${serving}"
   1.323 +        echo "allow_push = *"
   1.324 +        echo "push_ssl = False"
   1.325 +
   1.326 +        echo "[paths]"
   1.327 +        for i in ${repos} ; do
   1.328 +          if [ "${i}" != "." ] ; then
   1.329 +            echo "/${serving}/${i} = ${i}"
   1.330 +          else
   1.331 +            echo "/${serving} = ${cwd}"
   1.332 +          fi
   1.333 +        done
   1.334 +      ) > ${tmp}/serve.web-conf
   1.335 +
   1.336 +      echo "serving root repo ${serving}" > ${status_output}
   1.337 +
   1.338 +      echo "hg${global_opts} serve" > ${status_output}
   1.339 +      (PYTHONUNBUFFERED=true hg${global_opts} serve -A ${status_output} -E ${status_output} --pid-file ${tmp}/serve.pid --web-conf ${tmp}/serve.web-conf; echo "$?" > ${tmp}/serve.pid.rc ) 2>&1 &
   1.340 +    ) 2>&1 | sed -e "s@^@serve:   @" > ${status_output}
   1.341 +  ) &
   1.342 +else
   1.343 +  # Run the supplied command on all repos in parallel.
   1.344 +
   1.345 +  # n is the number of subprocess started or which might still be running.
   1.346 +  n=0
   1.347 +  if [ ${have_fifos} = "true" ]; then
   1.348 +    # if we have fifos use them to detect command completion.
   1.349 +    mkfifo ${tmp}/fifo
   1.350 +    exec 3<>${tmp}/fifo
   1.351 +  fi
   1.352 +
   1.353 +  # iterate over all of the subrepos.
   1.354 +  for i in ${repos} ${repos_extra} ; do
   1.355 +    n=`expr ${n} '+' 1`
   1.356 +    repopidfile=`echo ${i} | sed -e 's@./@@' -e 's@/@_@g'`
   1.357 +    reponame=`echo ${i} | sed -e :a -e 's/^.\{1,20\}$/ &/;ta'`
   1.358 +    pull_base="${pull_default}"
   1.359 +
   1.360 +    # regular repo or "extra" repo?
   1.361 +    for j in ${repos_extra} ; do
   1.362 +      if [ "${i}" = "${j}" ] ; then
   1.363 +        # it's an "extra"
   1.364 +        pull_base="${pull_extra}"
   1.365 +      fi
   1.366 +    done
   1.367 +
   1.368 +    # remove trailing slash
   1.369 +    pull_base="`echo ${pull_base} | sed -e 's@[/]*$@@'`"
   1.370 +
   1.371 +    # execute the command on the subrepo
   1.372 +    (
   1.373 +      (
   1.374 +        if [ "${command}" = "clone" -o "${command}" = "fclone" -o "${command}" = "tclone" ] ; then
   1.375 +          # some form of clone
   1.376 +          clone_newrepo="${pull_base}/${i}"
   1.377 +          parent_path="`dirname ${i}`"
   1.378 +          if [ "${parent_path}" != "." ] ; then
   1.379 +            times=0
   1.380 +            while [ ! -d "${parent_path}" ] ; do  ## nested repo, ensure containing dir exists
   1.381 +              if [ "${sflag}" = "true" ] ; then
   1.382 +                # Missing parent is fatal during sequential operation.
   1.383 +                echo "ERROR: Missing parent path: ${parent_path}" > ${status_output}
   1.384 +                exit 1
   1.385 +              fi
   1.386 +              times=`expr ${times} '+' 1`
   1.387 +              if [ `expr ${times} '%' 10` -eq 0 ] ; then
   1.388 +                echo "${parent_path} still not created, waiting..." > ${status_output}
   1.389 +              fi
   1.390 +              sleep 5
   1.391 +            done
   1.392 +          fi
   1.393 +          # run the clone command.
   1.394 +          echo "hg${global_opts} clone ${clone_newrepo} ${i}" > ${status_output}
   1.395 +          (PYTHONUNBUFFERED=true hg${global_opts} clone ${clone_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 &
   1.396 +        else
   1.397 +          # run the command.
   1.398 +          echo "cd ${i} && hg${global_opts} ${command} ${command_args}" > ${status_output}
   1.399 +          cd ${i} && (PYTHONUNBUFFERED=true hg${global_opts} ${command} ${command_args}; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 &
   1.400 +        fi
   1.401 +
   1.402 +        echo $! > ${tmp}/${repopidfile}.pid
   1.403 +      ) 2>&1 | sed -e "s@^@${reponame}:   @" > ${status_output}
   1.404 +      # tell the fifo waiter that this subprocess is done.
   1.405 +      if [ ${have_fifos} = "true" ]; then
   1.406 +        echo "${i}" >&3
   1.407 +      fi
   1.408 +    ) &
   1.409 +
   1.410 +    if [ "${sflag}" = "true" ] ; then
   1.411 +      # complete this task before starting another.
   1.412 +      wait
   1.413 +    else
   1.414 +      if [ "${have_fifos}" = "true" ]; then
   1.415 +        # check on count of running subprocesses and possibly wait for completion
   1.416 +        if [ ${n} -ge ${at_a_time} ] ; then
   1.417 +          # read will block until there are completed subprocesses
   1.418 +          while read repo_done; do
   1.419 +            n=`expr ${n} '-' 1`
   1.420 +            if [ ${n} -lt ${at_a_time} ] ; then
   1.421 +              # we should start more subprocesses
   1.422 +              break;
   1.423              fi
   1.424 -            sleep 5
   1.425 -          done
   1.426 +          done <&3
   1.427          fi
   1.428 -        (PYTHONUNBUFFERED=true hg clone ${pull_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc )&
   1.429        else
   1.430 -        echo "cd ${i} && hg $*"
   1.431 -        cd ${i} && (PYTHONUNBUFFERED=true hg "$@"; echo "$?" > ${tmp}/${repopidfile}.pid.rc )&
   1.432 +        # Compare completions to starts
   1.433 +        completed="`(ls -a1 ${tmp}/*.pid.rc 2> /dev/null | wc -l) || echo 0`"
   1.434 +        while [ `expr ${n} '-' ${completed}` -ge ${at_a_time} ] ; do
   1.435 +          # sleep a short time to give time for something to complete
   1.436 +          sleep 1
   1.437 +          completed="`(ls -a1 ${tmp}/*.pid.rc 2> /dev/null | wc -l) || echo 0`"
   1.438 +        done
   1.439        fi
   1.440 -      echo $! > ${tmp}/${repopidfile}.pid
   1.441 -    ) 2>&1 | sed -e "s@^@${reponame}:   @") &
   1.442 +    fi
   1.443 +  done
   1.444 +fi
   1.445  
   1.446 -  if [ `expr ${n} '%' ${at_a_time}` -eq 0 ] ; then
   1.447 -    sleep 2
   1.448 -    echo Waiting 5 secs before spawning next background command.
   1.449 -    sleep 3
   1.450 -  fi
   1.451 -done
   1.452 -# Wait for all hg commands to complete
   1.453 +# Wait for all subprocesses to complete
   1.454  wait
   1.455  
   1.456  # Terminate with exit 0 only if all subprocesses were successful
   1.457  ec=0
   1.458  if [ -d ${tmp} ]; then
   1.459 -  for rc in ${tmp}/*.pid.rc ; do
   1.460 +  rcfiles="`(ls -a ${tmp}/*.pid.rc 2> /dev/null) || echo ''`"
   1.461 +  for rc in ${rcfiles} ; do
   1.462      exit_code=`cat ${rc} | tr -d ' \n\r'`
   1.463      if [ "${exit_code}" != "0" ] ; then
   1.464 -      echo "WARNING: ${rc} exited abnormally."
   1.465 +      repo="`echo ${rc} | sed -e 's@^'${tmp}'@@' -e 's@/*\([^/]*\)\.pid\.rc$@\1@' -e 's@_@/@g'`"
   1.466 +      echo "WARNING: ${repo} exited abnormally (${exit_code})" > ${status_output}
   1.467        ec=1
   1.468      fi
   1.469    done
     2.1 --- a/get_source.sh	Thu Jul 17 18:01:58 2014 +0100
     2.2 +++ b/get_source.sh	Thu Jul 17 22:45:46 2014 +0100
     2.3 @@ -1,7 +1,7 @@
     2.4  #!/bin/sh
     2.5  
     2.6  #
     2.7 -# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
     2.8 +# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
     2.9  # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    2.10  #
    2.11  # This code is free software; you can redistribute it and/or modify it
    2.12 @@ -25,9 +25,76 @@
    2.13  # questions.
    2.14  #
    2.15  
    2.16 -# Get clones of all nested repositories
    2.17 -sh ./common/bin/hgforest.sh clone "$@" || exit 1
    2.18 +to_stderr() {
    2.19 +    echo "$@" >&2
    2.20 +}
    2.21 +
    2.22 +error() {
    2.23 +    to_stderr "ERROR: $1"
    2.24 +    exit ${2:-126}
    2.25 +}
    2.26 +
    2.27 +warning() {
    2.28 +    to_stderr "WARNING: $1"
    2.29 +}
    2.30 +
    2.31 +version_field() {
    2.32 +  # rev is typically omitted for minor and major releases
    2.33 +  field=`echo ${1}.0 | cut -f ${2} -d .`
    2.34 +  if expr 1 + $field >/dev/null 2> /dev/null; then
    2.35 +    echo $field
    2.36 +  else
    2.37 +    echo -1
    2.38 +  fi
    2.39 +}
    2.40 +
    2.41 +# Version check
    2.42 +
    2.43 +# required
    2.44 +reqdmajor=1
    2.45 +reqdminor=4
    2.46 +reqdrev=0
    2.47 +
    2.48 +# requested
    2.49 +rqstmajor=2
    2.50 +rqstminor=6
    2.51 +rqstrev=3
    2.52 +
    2.53 +
    2.54 +# installed
    2.55 +hgwhere="`command -v hg`"
    2.56 +if [ "x$hgwhere" = "x" ]; then
    2.57 +  error "Could not locate Mercurial command"
    2.58 +fi
    2.59 +
    2.60 +hgversion="`hg --version 2> /dev/null | sed -n -e 's@^Mercurial Distributed SCM (version \([^+]*\).*)\$@\1@p'`"
    2.61 +if [ "x${hgversion}" = "x" ] ; then
    2.62 +  error "Could not determine Mercurial version of $hgwhere"
    2.63 +fi
    2.64 +
    2.65 +hgmajor="`version_field $hgversion 1`"
    2.66 +hgminor="`version_field $hgversion 2`"
    2.67 +hgrev="`version_field $hgversion 3`"
    2.68 +
    2.69 +if [ $hgmajor -eq -1 -o $hgminor -eq -1 -o $hgrev -eq -1 ] ; then
    2.70 +  error "Could not determine Mercurial version of $hgwhere from \"$hgversion\""
    2.71 +fi
    2.72 +
    2.73 +
    2.74 +# Require
    2.75 +if [ $hgmajor -lt $reqdmajor -o \( $hgmajor -eq $reqdmajor -a $hgminor -lt $reqdminor \) -o \( $hgmajor -eq $reqdmajor -a $hgminor -eq $reqdminor -a $hgrev -lt $reqdrev \) ] ; then
    2.76 +  error "Mercurial version $reqdmajor.$reqdminor.$reqdrev or later is required. $hgwhere is version $hgversion"
    2.77 +fi
    2.78 +
    2.79 +
    2.80 +# Request
    2.81 +if [ $hgmajor -lt $rqstmajor -o \( $hgmajor -eq $rqstmajor -a $hgminor -lt $rqstminor \) -o \( $hgmajor -eq $rqstmajor -a $hgminor -eq $rqstminor -a $hgrev -lt $rqstrev \) ] ; then
    2.82 +  warning "Mercurial version $rqstmajor.$rqstminor.$rqstrev or later is recommended. $hgwhere is version $hgversion"
    2.83 +fi
    2.84 +
    2.85 +
    2.86 +# Get clones of all absent nested repositories (harmless if already exist)
    2.87 +sh ./common/bin/hgforest.sh clone "$@" || exit $?
    2.88  
    2.89  # Update all existing repositories to the latest sources
    2.90  sh ./common/bin/hgforest.sh pull -u
    2.91 -

mercurial