hgforest.sh revision 536:8e36a0fabf58
1231437Sluigi#!/bin/sh
2252869Sdelphij
3231437Sluigi#
4231437Sluigi# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
5231437Sluigi# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6231437Sluigi#
7231437Sluigi# This code is free software; you can redistribute it and/or modify it
8231437Sluigi# under the terms of the GNU General Public License version 2 only, as
9231437Sluigi# published by the Free Software Foundation.
10231437Sluigi#
11231437Sluigi# This code is distributed in the hope that it will be useful, but WITHOUT
12231437Sluigi# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13231437Sluigi# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14231437Sluigi# version 2 for more details (a copy is included in the LICENSE file that
15231437Sluigi# accompanied this code).
16231437Sluigi#
17231437Sluigi# You should have received a copy of the GNU General Public License version
18231437Sluigi# 2 along with this work; if not, write to the Free Software Foundation,
19231437Sluigi# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20231437Sluigi#
21231437Sluigi# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22231437Sluigi# or visit www.oracle.com if you need additional information or have any
23231437Sluigi# questions.
24231437Sluigi#
25231437Sluigi
26231437Sluigi# Shell script for a fast parallel forest command
27231437Sluigicommand="$1"
28231437Sluigipull_extra_base="$2"
29231437Sluigi
30231437Sluigi# Python always buffers stdout significantly, thus we will not see any output from hg clone jdk,
31231437Sluigi# until a lot of time has passed! By passing -u to python, we get incremental updates
32231437Sluigi# on stdout. Much nicer.
33231437Sluigiwhichhg="`which hg`"
34231437Sluigi
35231437Sluigiif [ "${whichhg}" = "" ] ; then
36231437Sluigi  echo Cannot find hg!
37231437Sluigi  exit 1
38231437Sluigifi
39231437Sluigi
40231437Sluigiif [ "" = "$command" ] ; then
41231511Sbz  echo No command to hg supplied!
42231511Sbz  exit 1
43231511Sbzfi
44231437Sluigi
45231437Sluigihas_hash_bang="`head -n 1 "${whichhg}" | cut -b 1-2`"
46257187Sdelphijpython=""
47257187Sdelphijbpython=""
48257187Sdelphij
49257187Sdelphijif [ "#!" = "$has_hash_bang" ] ; then
50257187Sdelphij   python="`head -n 1 ${whichhg} | cut -b 3-`"
51257187Sdelphij   bpython="`basename "$python"`"
52257187Sdelphijfi
53257187Sdelphij
54257187Sdelphijif [ "python" = "$bpython" -a -x "$python" ] ; then
55257187Sdelphij  hg="${python} -u ${whichhg}"
56257187Sdelphijelse
57257187Sdelphij  echo Cannot find python from hg launcher. Running plain hg, which probably has buffered stdout.
58257187Sdelphij  hg="hg"
59257187Sdelphijfi
60257187Sdelphij
61257187Sdelphij# Clean out the temporary directory that stores the pid files.
62257187Sdelphijtmp=/tmp/forest.$$
63257187Sdelphijrm -f -r ${tmp}
64257187Sdelphijmkdir -p ${tmp}
65257187Sdelphij
66257187Sdelphijsafe_interrupt () {
67257187Sdelphij  if [ -d ${tmp} ]; then 
68257187Sdelphij    if [ "`ls ${tmp}`" != "" ]; then 
69257187Sdelphij      echo "Waiting for processes ( `cat ${tmp}/* | tr '\n' ' '`) to terminate nicely!"
70257187Sdelphij      sleep 1
71257187Sdelphij      # Pipe stderr to dev/null to silence kill, that complains when trying to kill
72257187Sdelphij      # a subprocess that has already exited.
73257187Sdelphij      kill -TERM `cat ${tmp}/* | tr '\n' ' '` 2> /dev/null
74257187Sdelphij      wait 
75257187Sdelphij      echo Interrupt complete! 
76257187Sdelphij    fi 
77257187Sdelphij  fi
78257187Sdelphij  rm -f -r ${tmp}
79257187Sdelphij  exit 1
80257187Sdelphij}
81231437Sluigi
82257187Sdelphijnice_exit () {
83257187Sdelphij  if [ -d ${tmp} ]; then 
84257187Sdelphij    if [ "`ls ${tmp}`" != "" ]; then 
85257187Sdelphij      wait 
86257187Sdelphij    fi 
87257187Sdelphij  fi
88257187Sdelphij  rm -f -r ${tmp}
89257187Sdelphij}
90257187Sdelphij
91257187Sdelphijtrap 'safe_interrupt' INT QUIT
92257187Sdelphijtrap 'nice_exit' EXIT
93257187Sdelphij 
94257187Sdelphij# Only look in specific locations for possible forests (avoids long searches)
95257187Sdelphijpull_default=""
96257187Sdelphijrepos=""
97257187Sdelphijrepos_extra=""
98257187Sdelphijif [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
99257187Sdelphij  subrepos="corba jaxp jaxws langtools jdk hotspot"
100257187Sdelphij  if [ -f .hg/hgrc ] ; then
101257187Sdelphij    pull_default=`hg paths default`
102257187Sdelphij    if [ "${pull_default}" = "" ] ; then
103257187Sdelphij      echo "ERROR: Need initial clone with 'hg paths default' defined"
104257187Sdelphij      exit 1
105257187Sdelphij    fi
106257187Sdelphij  fi
107257187Sdelphij  if [ "${pull_default}" = "" ] ; then
108257187Sdelphij    echo "ERROR: Need initial repository to use this script"
109257187Sdelphij    exit 1
110257187Sdelphij  fi
111257187Sdelphij  for i in ${subrepos} ; do
112257187Sdelphij    if [ ! -f ${i}/.hg/hgrc ] ; then
113257187Sdelphij      repos="${repos} ${i}"
114257187Sdelphij    fi
115257187Sdelphij  done
116257187Sdelphij  if [ "${pull_extra_base}" != "" ] ; then
117257187Sdelphij    subrepos_extra="jdk/src/closed jdk/make/closed jdk/test/closed hotspot/make/closed hotspot/src/closed hotspot/test/closed deploy install sponsors pubs"
118257187Sdelphij    pull_default_tail=`echo ${pull_default} | sed -e 's@^.*://[^/]*/\(.*\)@\1@'`
119231437Sluigi    pull_extra="${pull_extra_base}/${pull_default_tail}"
120231437Sluigi    for i in ${subrepos_extra} ; do
121231437Sluigi      if [ ! -f ${i}/.hg/hgrc ] ; then
122231437Sluigi        repos_extra="${repos_extra} ${i}"
123231437Sluigi      fi
124231437Sluigi    done
125231437Sluigi  fi
126231437Sluigi  at_a_time=2
127231437Sluigi  # Any repos to deal with?
128231437Sluigi  if [ "${repos}" = "" -a "${repos_extra}" = "" ] ; then
129231437Sluigi    exit
130231437Sluigi  fi
131231437Sluigielse
132231437Sluigi  hgdirs=`ls -d ./.hg ./*/.hg ./*/*/.hg ./*/*/*/.hg ./*/*/*/*/.hg 2>/dev/null`
133231437Sluigi  # Derive repository names from the .hg directory locations
134231437Sluigi  for i in ${hgdirs} ; do
135231437Sluigi    repos="${repos} `echo ${i} | sed -e 's@/.hg$@@'`"
136231437Sluigi  done
137231437Sluigi  for i in ${repos} ; do
138231437Sluigi    if [ -h ${i}/.hg/store/lock -o -f ${i}/.hg/store/lock ] ; then
139231437Sluigi      locked="${i} ${locked}"
140231437Sluigi    fi
141231437Sluigi  done
142231437Sluigi  at_a_time=8
143231437Sluigi  # Any repos to deal with?
144231437Sluigi  if [ "${repos}" = "" ] ; then
145231437Sluigi    echo "No repositories to process."
146231437Sluigi    exit
147231437Sluigi  fi
148231437Sluigi  if [ "${locked}" != "" ] ; then
149231437Sluigi    echo "These repositories are locked: ${locked}"
150231437Sluigi    exit
151231437Sluigi  fi
152231437Sluigifi
153231437Sluigi
154231437Sluigi# Echo out what repositories we do a command on.
155231437Sluigiecho "# Repositories: ${repos} ${repos_extra}"
156231437Sluigiecho
157231437Sluigi
158231437Sluigi# Run the supplied command on all repos in parallel.
159231437Sluigin=0
160231437Sluigifor i in ${repos} ${repos_extra} ; do
161231437Sluigi  n=`expr ${n} '+' 1`
162231437Sluigi  repopidfile=`echo ${i} | sed -e 's@./@@' -e 's@/@_@g'`
163231437Sluigi  reponame=`echo ${i} | sed -e :a -e 's/^.\{1,20\}$/ &/;ta'`
164231437Sluigi  pull_base="${pull_default}"
165231437Sluigi  for j in $repos_extra ; do
166231437Sluigi      if [ "$i" = "$j" ] ; then
167231879Sluigi          pull_base="${pull_extra}"
168231879Sluigi      fi
169247880Sdelphij  done
170252869Sdelphij  (
171247880Sdelphij    (
172231437Sluigi      if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
173231879Sluigi        pull_newrepo="`echo ${pull_base}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`"
174231879Sluigi        echo ${hg} clone ${pull_newrepo} ${i}
175231879Sluigi        ${hg} clone ${pull_newrepo} ${i} &
176231879Sluigi      else
177231879Sluigi        echo "cd ${i} && ${hg} $*"
178231879Sluigi        cd ${i} && ${hg} "$@" &
179231879Sluigi      fi 
180231437Sluigi      echo $! > ${tmp}/${repopidfile}.pid
181231437Sluigi    ) 2>&1 | sed -e "s@^@${reponame}:   @") &
182231437Sluigi  
183231437Sluigi  if [ `expr ${n} '%' ${at_a_time}` -eq 0 ] ; then
184231437Sluigi    sleep 2
185246128Ssbz    echo Waiting 5 secs before spawning next background command.
186246128Ssbz    sleep 3
187231437Sluigi  fi
188231437Sluigidone
189231437Sluigi# Wait for all hg commands to complete
190231437Sluigiwait
191231437Sluigi
192231437Sluigi# Terminate with exit 0 all the time (hard to know when to say "failed")
193231437Sluigiexit 0
194231437Sluigi
195231437Sluigi