attempting to ignore vendor folders for php
[feisty_meow.git] / scripts / rev_control / version_control.sh
1 #!/bin/bash
2
3 # these are helper functions for doing localized revision control.
4 # this script should be sourced into other scripts that use it.
5
6 source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
7 source "$FEISTY_MEOW_SCRIPTS/tty/terminal_titler.sh"
8
9 # the maximum depth that the recursive functions will try to go below the starting directory.
10 export MAX_DEPTH=5
11
12 #hmmm: re-address this code, since it doesn't make a lot of sense to me right now...
13 # one unpleasantry to take care of first; cygwin barfs aggressively if the TMP directory
14 # is a DOS path, but we need it to be a DOS path for our GFFS testing, so that blows.
15 # to get past this, TMP gets changed below to a hopefully generic and safe place.
16
17 if [[ "$TMP" =~ .:.* ]]; then
18   echo making weirdo temporary directory for DOS path.
19   export TMP=/tmp/rev_control_$USER
20 fi
21 if [ ! -d "$TMP" ]; then
22   mkdir -p $TMP
23 fi
24 if [ ! -d "$TMP" ]; then
25   echo "could not create the temporary directory TMP in: $TMP"
26   echo "this script will not work properly without an existing TMP directory."
27 fi
28
29 this_host=
30 # gets the machine's hostname and stores it in the variable "this_host".
31 function get_our_hostname()
32 {
33   if [ "$OS" == "Windows_NT" ]; then
34     this_host=$(hostname)
35   elif [ ! -z "$(echo $MACHTYPE | grep apple)" ]; then
36     this_host=$(hostname)
37   elif [ ! -z "$(echo $MACHTYPE | grep suse)" ]; then
38     this_host=$(hostname --long)
39   else
40     this_host=$(hostname)
41   fi
42   #echo "hostname is $this_host"
43 }
44
45 # this function sets a variable called "home_system" to "true" if the
46 # machine is considered one of fred's home machines.  if you are not
47 # fred, you may want to change the machine choices.
48 export home_system=
49 function is_home_system()
50 {
51   # load up the name of the host.
52   get_our_hostname
53   # reset the variable that we'll be setting.
54   home_system=
55   if [[ $this_host == *.gruntose.blurgh ]]; then
56     home_system=true
57   fi
58 }
59
60 #hmmm: move to core.
61 # makes sure that the "folder" is a directory and is writable.
62 # remember that bash successful returns are zeroes...
63 function test_writeable()
64 {
65   local folder="$1"; shift
66   if [ ! -d "$folder" -o ! -w "$folder" ]; then return 1; fi
67   return 0
68 }
69
70 # we only want to totally personalize this script if the user is right.
71 function check_user()
72 {
73   if [ "$USER" == "fred" ]; then
74     export SVNUSER=fred_t_hamster@
75     export EXTRA_PROTOCOL=+ssh
76   else
77     export SVNUSER=
78     export EXTRA_PROTOCOL=
79   fi
80 }
81
82 # calculates the right modifier for hostnames / repositories.
83 modifier=
84 function compute_modifier()
85 {
86   modifier=
87   directory="$1"; shift
88   in_or_out="$1"; shift
89   check_user
90   # some project specific overrides.
91   if [[ "$directory" == hoople* ]]; then
92     modifier="svn${EXTRA_PROTOCOL}://${SVNUSER}svn.code.sf.net/p/hoople2/svn/"
93   fi
94   if [[ "$directory" == yeti* ]]; then
95     modifier="svn${EXTRA_PROTOCOL}://${SVNUSER}svn.code.sf.net/p/yeti/svn/"
96   fi
97   # see if we're on one of fred's home machines.
98   is_home_system
99   # special override to pick local servers when at home.
100   if [ "$home_system" == "true" ]; then
101 #what was this section for again?
102     if [ "$in_or_out" == "out" ]; then
103       # need the right home machine for modifier when checking out.
104 #huhhh?      modifier="svn://shaggy/"
105       modifier=
106     else 
107       # no modifier for checkin.
108       modifier=
109     fi
110   fi
111 }
112
113 # selects the method for check-in based on where we are.
114 function do_checkin()
115 {
116   local directory="$1"; shift
117
118   save_terminal_title
119
120   # make a nice echoer since we want to use it inside conditions below.
121   local nicedir="$directory"
122   if [ $nicedir == "." ]; then
123     nicedir=$(\pwd)
124   fi
125   local blatt="echo checking in '$nicedir'..."
126
127   do_update "$directory"
128   if [ $? -ne 0 ]; then
129     echo "repository update failed; this should be fixed before check-in."
130     return 1
131   fi
132   pushd "$directory" &>/dev/null
133   local retval=0  # normally successful.
134   if [ -f ".no-checkin" ]; then
135     echo "skipping check-in due to presence of .no-checkin sentinel file."
136   elif [ -d "CVS" ]; then
137     if test_writeable "CVS"; then
138       $blatt
139       cvs ci .
140       retval=$?
141     fi
142   elif [ -d ".svn" ]; then
143     if test_writeable ".svn"; then
144       $blatt
145       svn ci .
146       retval=$?
147     fi
148   elif [ -d ".git" ]; then
149     if test_writeable ".git"; then
150       $blatt
151       # snag all new files.  not to everyone's liking.
152       git add --all .
153       retval=$?
154       # tell git about all the files and get a check-in comment.
155       git commit .
156       retval+=$?
157       # upload the files to the server so others can see them.
158       git push 2>&1 | grep -v "X11 forwarding request failed"
159       retval+=$?
160     fi
161   else
162     echo no repository in $directory
163     retval=1
164   fi
165   popd &>/dev/null
166
167   restore_terminal_title
168
169   return $retval
170 }
171
172 function do_diff
173 {
174   local directory="$1"; shift
175
176   save_terminal_title
177
178   pushd "$directory" &>/dev/null
179   local retval=0  # normally successful.
180
181   # only update if we see a repository living there.
182   if [ -d ".svn" ]; then
183     svn diff .
184   elif [ -d ".git" ]; then
185     git diff 
186   elif [ -d "CVS" ]; then
187     cvs diff .
188   fi
189
190   popd &>/dev/null
191
192   restore_terminal_title
193
194   return $retval
195 }
196
197 function do_report_new
198 {
199   local directory="$1"; shift
200
201   save_terminal_title
202
203   pushd "$directory" &>/dev/null
204   local retval=0  # normally successful.
205
206   # only update if we see a repository living there.
207   if [ -f ".no-checkin" ]; then
208     echo "skipping reporting due to presence of .no-checkin sentinel file."
209   elif [ -d ".svn" ]; then
210     # this action so far only makes sense and is needed for svn.
211     bash $FEISTY_MEOW_SCRIPTS/rev_control/svnapply.sh \? echo
212     retval=$?
213   elif [ -d ".git" ]; then
214     git status -u
215     retval=$?
216   fi
217
218   popd &>/dev/null
219
220   restore_terminal_title
221
222   return $retval
223 }
224
225 # checks in all the folders in a specified list.
226 function checkin_list()
227 {
228   # make the list of directories unique.
229   local list="$(uniquify $*)"
230
231   save_terminal_title
232
233   # turn repo list back into an array.
234   eval "repository_list=( ${REPOSITORY_LIST[*]} )"
235
236   local outer inner
237
238   for outer in "${repository_list[@]}"; do
239     # check the repository first, since it might be an absolute path.
240     if [[ $outer =~ /.* ]]; then
241       # yep, this path is absolute.  just handle it directly.
242       if [ ! -d "$outer" ]; then continue; fi
243       do_checkin $outer
244       sep 28
245     else
246       for inner in $list; do
247         # add in the directory component to see if we can find the folder.
248         local path="$inner/$outer"
249         if [ ! -d "$path" ]; then continue; fi
250         do_checkin $path
251         sep 28
252       done
253     fi
254   done
255
256   restore_terminal_title
257 }
258
259 # takes out the first few carriage returns that are in the input.
260 function squash_first_few_crs()
261 {
262   i=0
263   while read input_text; do
264     i=$((i+1))
265     if [ $i -le 5 ]; then
266       echo -n "$input_text  "
267     else
268       echo $input_text
269     fi
270   done
271   if [ $i -le 3 ]; then
272     # if we're still squashing eols, make sure we don't leave them hanging.
273     echo
274   fi
275 }
276
277 # selects the checkout method based on where we are (the host the script runs on).
278 function do_update()
279 {
280   directory="$1"; shift
281
282   save_terminal_title
283
284   # make a nice echoer since we want to use it inside conditions below.
285   local nicedir="$directory"
286   if [ $nicedir == "." ]; then
287     nicedir=$(\pwd)
288   fi
289   local blatt="echo retrieving '$nicedir'..."
290
291   local retval=0  # plan on success for now.
292   pushd "$directory" &>/dev/null
293   if [ -d "CVS" ]; then
294     if test_writeable "CVS"; then
295       $blatt
296       cvs update . | squash_first_few_crs
297       retval=${PIPESTATUS[0]}
298     fi
299   elif [ -d ".svn" ]; then
300     if test_writeable ".svn"; then
301       $blatt
302       svn update . | squash_first_few_crs
303       retval=${PIPESTATUS[0]}
304     fi
305   elif [ -d ".git" ]; then
306     if test_writeable ".git"; then
307       $blatt
308       git pull 2>&1 | grep -v "X11 forwarding request failed" | squash_first_few_crs
309       retval=${PIPESTATUS[0]}
310     fi
311   else
312     # this is not an error necessarily; we'll just pretend they planned this.
313     echo no repository in $directory
314   fi
315   popd &>/dev/null
316
317   restore_terminal_title
318
319   return $retval
320 }
321
322 # gets all the updates for a list of folders under revision control.
323 function checkout_list()
324 {
325   local list="$(uniquify $*)"
326
327   save_terminal_title
328
329   # turn repo list back into an array.
330   eval "repository_list=( ${REPOSITORY_LIST[*]} )"
331
332   local outer inner
333
334   for outer in "${repository_list[@]}"; do
335     # check the repository first, since it might be an absolute path.
336     if [[ $outer =~ /.* ]]; then
337       # yep, this path is absolute.  just handle it directly.
338       if [ ! -d "$outer" ]; then continue; fi
339       do_update $outer
340       sep 28
341     else
342       for inner in $list; do
343         # add in the directory component to see if we can find the folder.
344         local path="$inner/$outer"
345         if [ ! -d "$path" ]; then continue; fi
346         do_update $path
347         sep 28
348       done
349     fi
350   done
351
352   restore_terminal_title
353 }
354
355 # provides a list of absolute paths of revision control directories
356 # that are located under the directory passed as the first parameter.
357 function generate_rev_ctrl_filelist()
358 {
359   local dir="$1"; shift
360   pushd "$dir" &>/dev/null
361   local dirhere="$( \cd "$(\dirname "$dir")" && /bin/pwd )"
362   local tempfile=$(mktemp /tmp/zz_checkins.XXXXXX)
363   echo >$tempfile
364   local additional_filter
365   if [ ! -z "NO_CHECKIN_VENDOR" ]; then
366     additional_filter='-a ! -iname "*\/vendor\/*" '
367   fi
368   find $dirhere -follow -maxdepth $MAX_DEPTH -type d -iname ".svn" $additional_filter -exec echo {}/.. ';' >>$tempfile 2>/dev/null
369   find $dirhere -follow -maxdepth $MAX_DEPTH -type d -iname ".git" $additional_filter -exec echo {}/.. ';' >>$tempfile 2>/dev/null
370   # CVS is not well behaved like git and (now) svn, and we seldom use it anymore.
371   popd &>/dev/null
372   local sortfile=$(mktemp /tmp/zz_checkin_sort.XXXXXX)
373   sort <"$tempfile" >"$sortfile"
374   \rm "$tempfile"
375   echo "$sortfile"
376 }
377
378 # iterates across a list of directories contained in a file (first parameter).
379 # on each directory name, it performs the action (second parameter) provided.
380 function perform_revctrl_action_on_file()
381 {
382
383 #hmmm: this doesn't capture any error returns!
384
385   local tempfile="$1"; shift
386   local action="$1"; shift
387
388   save_terminal_title
389
390   while read -u 3 dirname; do
391     if [ -z "$dirname" ]; then continue; fi
392     pushd "$dirname" &>/dev/null
393     echo "[$(pwd)]"
394     $action .
395     sep 28
396     popd &>/dev/null
397   done 3<"$tempfile"
398
399   restore_terminal_title
400
401   rm $tempfile
402 }
403
404