Initial add of defaria.com
[clearscm.git] / defaria.com / Computers / code / bin / clearcase / ctmerge
1 #!/bin/bash
2 ################################################################################
3 #
4 # File:         ctmerge
5 # Description:  Merges from one branch to another. If the merge is successful
6 #               then a build is performed. If that is also successful then the
7 #               merged elements are checked in and optionally labeled. A cleanup
8 #               of .contrib files is also performed (only if the merge and build
9 #               succeed). After this email is set to SITE_ADMIN_EMAIL (default).
10 # Author:       Andrew@DeFaria.com
11 # Created:      Wed Jun 11 13:22:11 PDT 2003
12 # Language:     Bash Shell
13 # Modifications:
14 #
15 # (c) Copyright 2003, Andrew@DeFaria.com, all rights reserved
16 #
17 ################################################################################
18 # Set me to command name
19 me=$(basename $0)
20
21 # Source /etc/site_parms
22 if [ -f /etc/site_parms ]; then
23   . /etc/site_parms
24 else
25   echo "$me: WARNING: /etc/site_parms does not exist!"
26 fi
27
28 # Set adm_base
29 adm_base="$SITE_TOOLS_PATH/adm"
30
31 # Set adm_fpath
32 adm_fpath=${adm_fpath:-$adm_base/functions}
33
34 # Source functions
35 . $adm_fpath/common
36
37 # Commands used
38 ssmtp=/usr/sbin/ssmtp
39
40 # Set a logfile for the merge
41 logfile=/tmp/$me.$$.log
42
43 # File for merge commands
44 merge_cmd=/tmp/$me.$$.cmd
45
46 # File for exclusions
47 exclusions=/tmp/$me.$$.exclude
48
49 # How many elements merged
50 declare -i nbr_merges=0
51
52 # How many exclusions were found
53 declare -i nbr_exclusions=0
54
55 # Element exclusion list
56 excluded_elements="\
57 "
58
59 # Result of merging, building, etc. Codes are:
60 #
61 # 0:    Success! Everything worked.
62 # 1:    Errors occured during merging
63 # 2:    Not all merges could be performed automatically
64 # 3:    No merging required
65 # 4:    Build failed
66 # 5:    Unable to checkin elements
67 # 6:    Problems applying label
68 declare -i result_code=0
69
70 function usage {
71   if [ ! -z "$1" ]; then
72     error "$1\n"
73   fi
74   display "Usage: $me: -view <view path> -b|ranch <from_branch>"
75   display "\t\t[-to <email_address>] [-cc <email_address>]"
76   display "\t\t[-nocheckin] [-l|abel <label>] [-nocleanup]"
77   display "\t\t[-v|erbose] [-d|ebug] [-u|sage]"
78   display
79   display "Where:"
80   display "\t-view:\t\tPath to view to perform the merge to (Required)"
81   display "\t-branch:\tName of branch to merge the LATEST from (Required)"
82   display "\t-to:\t\tEmail address where to mail the build log"
83   display "\t\t\t(default $SITE_ADMIN_EMAIL)"
84   display "\t-cc:\t\tEmail address where to cc the build log"
85   display "\t\t\t(default NONE)"
86   display "\t-nocheckin:\tDo not check in merged elements after"
87   display "\t\t\tsuccessful merge  and build (default check in)"
88   display "\t-label:\t\tLabel to apply after successful build. Note that"
89   display "\t\t\tthe current date (format _DD_MM_YYYY) will be appended"
90   display "\t\t\tto this label (default no label applied)"
91   display "\t-nocleanup:\tDo not clean up contrib files after successful"
92   display "\t\t\tbuild (default cleanup)"
93   display "\t-verbose:\tTurn on verbose mode"
94   display "\t-debug:\t\tTurn on debug mode"
95   display "\t-usage:\t\tDisplay usage"
96   exit 1
97 } # usage
98
99 function log {
100   msg="$1"
101
102   display "$1" >> $logfile
103   verbose "$1"
104 } # log
105
106 function merge_directories {
107   # First merge directories
108   log "Finding directories that need merging..."
109
110   # Convert $merge_cmd to Window path for cleartool
111   cmd=$(cygpath -w $merge_cmd)
112
113   cleartool findmerge                                           \
114     .                                                           \
115     -type d                                                     \
116     -reserved                                                   \
117     -comment "BUGS200003035: Merge from $branch -> $viewtag"    \
118     -fversion .../$branch/LATEST                                \
119     -log $cmd                                                   \
120     -print                                                      >> $logfile 2>&1
121
122   # The merging of directories could, in theory, unearth directories
123   # inside those directories thus causing further directory merging.
124   # Here we keep merging directories until there are no more to merge.
125   while [ -f $merge_cmd -a -s $merge_cmd ]; do
126     # Remove any comments from the merge command. Comments are inserted
127     # as warnings is directory merges were needed and not performed.
128     grep -ve ^# $merge_cmd > $merge_cmd.2
129     mv $merge_cmd.2 $merge_cmd
130
131     # Restore execute permissions to $merge_cmd
132     chmod +x $merge_cmd
133
134     log "Performing directory merges..."
135     let nbr_merges=nbr_merges+$(wc -l $merge_cmd | awk '{print $1}')
136     $merge_cmd                                                  >> $logfile 2>&1
137     rm -f $merge_cmd
138
139     # Check for errors. If there was a reserved checkout on a directory and
140     # we do not detect this error we will loop here because the merge will
141     # not be performed yet it needs to be merged
142     check_error
143
144     if [ $result_code -ne 0 ]; then
145       rm -f $merge_cmd
146       return
147     fi
148
149     log "Looking for further directory merges..."               >> $logfile
150
151     cleartool findmerge                                         \
152       .                                                         \
153       -type d                                                   \
154       -reserved                                                 \
155       -comment "BUGS200003035: Merge from $branch -> $viewtag"  \
156       -fversion .../$branch/LATEST                              \
157       -log $cmd                                                 \
158       -print                                                    >> $logfile 2>&1 
159   done
160
161   # Clean up
162   rm -f $merge_cmd
163 } # merge_directories
164
165 function merge_elements {
166   log "Performing element merges..."
167
168   # Convert $merge_cmd to Window path for cleartool
169   cmd=$(cygpath -w $merge_cmd)
170
171   cleartool findmerge                                           \
172     neopon                                                      \
173     Hardware                                                    \
174     EMS                                                         \
175     -type f                                                     \
176     -reserved                                                   \
177     -comment "BUGS200003035: Merge from $branch -> $viewtag"    \
178     -fversion .../$branch/LATEST                                \
179     -abort                                                      \
180     -log $cmd                                                   \
181     -print                                                      >> $logfile 2>&1 
182
183   # Exclude certain elements...
184   rm -f $exclusions
185   touch $exclusions
186   for element in $excluded_elements; do 
187     grep -q $element $merge_cmd
188
189     if [ $? -eq 0 ]; then
190       log "Excluded element $element found - removing element from merge list..."
191       grep $element $merge_cmd >> $exclusions
192       grep -v $element $merge_cmd > $merge_cmd.2
193       mv $merge_cmd.2 $merge_cmd
194     fi
195   done
196
197   let nbr_merges=nbr_merges+$(wc -l $merge_cmd | awk '{print $1}')
198   let nbr_exclusions=$(wc -l $exclusions | awk '{print $1}')
199
200   if [ -f $merge_cmd -a -s $merge_cmd ]; then
201     # Restore execute permissions to merge.cmd
202     chmod +x $merge_cmd
203     $merge_cmd                                          >> $logfile 2>&1
204   fi
205
206   # Clean up
207   rm -f $exclusions
208   rm -f $merge_cmd
209 } # merge_elements
210
211 function send_email {
212   to="$1"
213   cc="$2"
214   subject="$3"
215
216   # Compose message
217   if [ -z "$cc" ]; then
218     display "From: ccadmin\nTo: $to\nSubject: $subject\n" > /tmp/msg.$$
219   else
220     display "From: ccadmin\nTo: $to\ncc: $cc\nSubject: $subject\n" > /tmp/msg.$$
221   fi
222
223   # Mail it
224   cat /tmp/msg.$$ $logfile | $ssmtp -t
225
226   if [ $? -eq 0 ]; then
227     rm -f /tmp/msg.$$
228   fi
229 } # send_email
230
231 function check_error {
232   # Check for cleartool errors
233   errors=$(grep -c "cleartool: Error" $logfile)
234
235   if [ $errors -ne 0 ]; then
236     result_code=1
237     log "Errors occurred during merging"
238   fi
239
240   # Check how many merges failed:
241   errors=$(grep -c -e "*** Aborting..." $logfile)
242
243   if [ $errors -ne 0 ]; then
244     result_code=2
245     log "\nUnable to merge all elements automatically. $errors merges failed"
246     log "The following element(s) require manual merge:\n\n"
247
248     declare -i i=0
249
250     # Report individual files that could not be automatically merged
251     grep -e "Needs Merge" -e "\*\*\* Aborting\.\.\." $logfile | 
252       tr '\\' '/' | while read line; do 
253       if [[ $line != *Aborting\.\.\. ]]; then
254         file=$(echo $line | cut -f2 -d\")
255       else
256         ((i++))
257         log "$i) $file"
258       fi
259     done
260   else
261     if [ $nbr_exclusions -ne 0 ]; then
262       if [ $nbr_exclusions -eq 1 ]; then
263         log "$nbr_exclusions element excluded merge"
264       else
265         log "$nbr_exclusions elements excluded from merge"
266       fi
267     fi
268     if [ $nbr_merges -eq 0 ]; then
269       log "No merging required"
270       result_code=3
271     elif [ $nbr_merges -eq 1 ]; then
272       log "$nbr_merges element merged succesfully"
273     else    
274       log "$nbr_merges elements merged succesfully"
275     fi
276   fi
277 } # check_error
278
279 function report_results {
280   log "\nEnd of merge of Branch: $branch -> View: $viewtag @ $(date)"
281   log "Logfile: $(hostname):$logfile"
282
283   # Parse result_code
284   case $result_code in
285     0)
286       subject="Successful merge"
287     ;;
288
289     1)
290       subject="Errors merging"
291     ;;
292
293     2)
294       subject="Unable to automatically merge"
295     ;;
296
297     3)
298       subject="No elements required merging"
299     ;;
300
301     4)
302       subject="Build failed after successfully merging"
303     ;;
304
305     5)
306       subject="Unable to checkin element after merging"
307     ;;
308
309     6)
310       subject="Unable to apply label to elements after merge"
311     ;;
312
313     *)
314       subject="Unknown result code while merging"
315     ;;
316   esac
317
318   subject="$subject from Branch: $branch -> View: $viewtag"
319   send_email $to "$cc" "$subject"
320
321   exit $result_code
322 } # report_results
323
324 # Get parameters
325 checkin="yes"
326 label=""
327 cleanup="yes"
328 while [ $# -ge 1 ]; do                                                          
329   case "$1" in                                                                  
330       -u|-usage)
331         usage
332       ;;
333
334       -v|-verbose)
335         verbose=yes
336       ;;
337
338       -view)
339         if [ $# -le 1 ]; then
340           usage "View path is mmissing"
341         else
342           shift
343           view="$1"
344         fi
345       ;;
346
347       -d|-debug)
348         debug=yes
349       ;;                                                                        
350
351       -b|-branch)
352         if [ $# -le 1 ]; then
353           usage "Branch missing"
354         else
355           shift
356           branch="$1"
357         fi
358       ;;
359
360       -to)
361         if [ $# -le 1 ]; then
362           usage "To address missing"
363         else
364           shift
365           to="$1"
366         fi
367       ;;
368
369       -cc)
370         if [ $# -le 1 ]; then
371           usage "CC address missing"
372         else
373           shift;
374           cc="$1"
375         fi
376       ;;
377
378       -nocheckin)
379         checkin="no"
380       ;;
381
382       -l|-label)
383         if [ $# -le 1 ]; then
384           usage "Label missing"
385         else
386           shift
387           label="$(echo $1 | tr [:lower:] [:upper:])_$(date +%d_%m_%Y)"
388         fi
389       ;;
390
391       -nocleanup)
392         cleanup="no"
393         ;;
394
395       *)
396         usage "Unknown option encountered: \"$1\"!"
397       ;;
398   esac
399   shift
400 done
401
402 # Default to to $SITE_ADMIN_EMAIL
403 to=${to:-$SITE_ADMIN_EMAIL}
404
405 # Check for required parameters
406 if [ "$view" = "" ]; then
407   usage "View not specified"
408 elif [ "$branch" = "" ]; then
409   usage "Branch name not specified"
410 fi
411
412 # Go to the view/vob
413 if [ ! -d "$view" ]; then
414   # View path doesn't seem to exist. If this is a dynamic view then perhaps
415   # it's not started. Attempt to start it and see if it comes into existance
416   cleartool startview $(basename "$view") > /dev/null 2>&1
417
418   if [ $? -ne 0 ]; then
419     usage "View specified, $(basename $view), does not appear to be a valid view"
420   fi
421
422   if [ ! -d "$view" ]; then
423     usage "View path specified, $view, does not exist"
424   fi
425 fi
426
427 cd $view/salira
428 viewtag=$(cleartool pwv -short)
429
430 # Clear the logfile
431 rm -f $logfile
432
433 # Start merging
434 log "Start merge of Branch: $branch -> View: $viewtag @ $(date)"
435 merge_directories
436
437 if [ $result_code -ne 0 ]; then
438   log "Unable to merge directories"
439   log "Further merging halted"
440   exit $result_code
441 fi
442
443 merge_elements
444 check_error
445
446 if [ $result_code -ne 0 ]; then 
447   if [ $result_code -eq 3 ]; then
448     log "Build not performed"
449   else
450     log "Merging failed - build not performed"
451   fi
452   report_results
453 else
454   log "Merge successful - building..."
455 fi
456
457 # Now build the view
458 $SITE_TOOLS_PATH/bin/build_view $viewtag
459
460 if [ $? -ne 0 ]; then
461   result_code=4
462   log "Build failed!"
463   report_results
464 fi
465     
466 log "Build successful"
467
468 # Perform checkins
469 if [ $checkin = "yes" ]; then
470   # Check in merges, if any
471   log "Checking in merges..."
472   cleartool lscheckout -cview -me -all -short | tr '\\' '/' | while read element; do
473     log "Checking in element $element"
474     cleartool checkin -nc $element >> $logfile 2>&1
475     status=$?
476
477     if [ $status -ne 0 ]; then
478       result_code=5
479       log "Unable to checkin $element (Status: $status)"
480       report_results
481     fi
482   done
483   log "All merges checked in"
484 fi
485
486 # Apply dated label
487 if [ ! -z "$label" ]; then
488   log "Applying locked, dated label $label..."
489   $SITE_TOOLS_PATH/bin/label -label $label -dated -lock \
490     . -recurse salira/neopon -recurse salira/EMS -recurse salira/Hardware
491     
492   if [ $? -eq 0 ]; then
493     log "Applied labels successfully"
494   else
495     result_code=6
496     log "Problems applying label"
497   fi
498 fi
499
500 # Cleanup contrib files
501 if [ $cleanup = "yes" ]; then
502   # Cleanup contrib files...
503   log "Cleaning up contrib files..."
504   find . -name "*.contrib*" -exec rm -f {} \;
505   log "Cleaned up contrib files"
506 fi
507
508 report_results