1#! /bin/sh
2#
3# BEGIN LICENSE BLOCK
4# Version: CMPL 1.1
5#
6# The contents of this file are subject to the Cisco-style Mozilla Public
7# License Version 1.1 (the "License"); you may not use this file except
8# in compliance with the License.  You may obtain a copy of the License
9# at www.eclipse-clp.org/license.
10# 
11# Software distributed under the License is distributed on an "AS IS"
12# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
13# the License for the specific language governing rights and limitations
14# under the License. 
15# 
16# The Original Code is  The ECLiPSe Constraint Logic Programming System. 
17# The Initial Developer of the Original Code is  Cisco Systems, Inc. 
18# Portions created by the Initial Developer are
19# Copyright (C) 2000-2006 Cisco Systems, Inc.  All Rights Reserved.
20# 
21# Contributor(s): IC-Parc, Imperial College London
22# 
23# END LICENSE BLOCK
24#
25# IC-Parc, $Id: BUILD_ROTD,v 1.18 2015/05/05 14:47:13 jschimpf Exp $
26#
27# Build ECLiPSe Release-Of-The-Day.
28#
29
30#
31# Directory structure used:
32#
33# .../<rotd_dir>/		Top-level directory
34#	rotd-<name>/		Release of the day <name>
35#	    build/		Initial build of checked-out sources
36#	    archives/		Packed distribution archives
37#	    logs/		Log files
38#	    results/		Test result files
39#	    milestones/		Files marking successfully completed stages
40#	    <arch>/		Architecture-specific stuff
41#		install/	Installation from archive
42#		test/		Test of installation
43#
44
45#
46# Operational plan:
47#
48# Check out sources
49# Build from these sources each specified architecture
50# Build documentation
51# Generate distribution archives for each architecture
52# For each architecture
53#	Install distribution archive
54#	Check out tests
55#	Run tests
56# Update stable archives and symlinks
57#
58
59#
60# Tags ("milestones") to mark successful completion of stages:
61#
62# checked_out_sources
63# checked_out_tests
64# built_<arch>
65# built_documentation
66# built_archives
67# installed_(all|<arch>)_(standard|runtime)
68# tested_(all|<arch>)_(standard|runtime)_(standalone|java)_(<machine>|<class>)
69# incremented_build_number
70# committed_build_number
71# packed_source
72# updated_symlinks
73# copied_to_ftp_<machine>
74#
75# Note that we don't milestone cleaning up, since we probably want to re-do
76# that anyway.
77#
78# XXX - TODO: add dependencies, so that if, for instance, an architecture is
79# built, then the archives will get re-built, any tests for that achitecture
80# will be re-done, etc.
81#
82# XXX - Note that cleaning up might not work properly: the machines chosen
83# for testing might be different to last time, in which case the old
84# directories will be left lying around.
85#
86# XXX - Note that if the previous attempt cleaned up, certain directories
87# might be missing that we need this time, but that we don't re-create
88# because their creation worked fine last time (e.g. the test template
89# directory).  --- We handle the test template directory issue by no longer
90# deleting it when cleaning up.  Note that re-creating it if such is
91# necessary is undesirable since we may not get the same version out of the
92# repository.
93#
94# To prematurely abort a running build, create a file 'abort' in the
95# build's toplevel directory. This will have a similar effect to
96# milestones, i.e. all subsequent stages will be skipped.
97#
98
99#set -x
100
101usage="\
102Usage: $0 [options] [architectures]
103Options:
104	--patch <tag>
105		Build a patch version using the specified tag (rather than a
106		rotd using the current version on the main branch).
107
108	--date <date>
109		Build a version using sources from the given date, rather
110		than the current time.
111
112	--last-sucessful
113		Re-build the version tagged last_successful_<tag> or the
114		last successful main branch.  You cannot give a --date or
115		--increment-buildnum option at the same time.
116
117	--clean-up
118		After building, testing, etc., delete anything that probably
119		won't be needed again.  (default)
120	--no-clean-up
121		Don't delete anything.
122
123	--increment-buildnum
124		If all build and tests successful, increment the build number
125		in the repository.
126	--no-increment-buildnum
127		Do not increment the build number.  (default)
128
129	--install-archives
130		If an architecture successfully builds, tests, etc., copy
131		the corresponding archive files to the main archive
132		directory.  (default)
133	--no-install-archives
134		Don't copy any archive files to the main archive directory.
135
136	--jeclipse-tests
137		If an architecture built a \"jeclipse\" executable, run the
138		tests using that as well.  (default)
139	--no-jeclipse-tests
140		Don't run any tests using \"jeclipse\".
141
142	--cvsroot <path>
143		The location of the ECLiPSe CVS repository.
144
145	--umask <value>
146		Umask to use.  (default 022)
147
148	--nice <value>
149		Run remote jobs with the specified nice value.
150
151	--rotd-dir <path>
152		The location where ROTDs are installed.
153
154	--local-rotd-dir <path>
155		Where the ROTD directory appears on the local machine,
156		if different from the above.  This is primarily intended
157		for when this script is running under Windows (using
158		Cygwin or the like) and the filesystem is not arranged the
159		same as on the Unix machines.  In this case the directory
160		specification should be of the form \"<drive>:/<path>\",
161		where <drive> is the Windows drive letter.
162
163	--rotd-name <name>
164		The name to use for the rotd (rather than constructing
165		it from the date).
166
167	--build-script <script>
168		The BUILD script to use.
169
170	--resume
171		Resume/retry partially completed/successful build.  Use
172		with care if it's more than just tests that failed.
173
174Other parameters must be specified in the site_info file.
175"
176
177for param_name in ARCH JAVA_HOME JRE_HOME ECLIPSETOOLS ECLIPSETHIRDPARTY; do
178    eval param_val="\$$param_name"
179    if [ -z "$param_val" ]; then 
180	echo "$0: Please set environment variable $param_name" 1>&2
181	exit 1
182    fi
183done
184
185SCRIPT_DIR=`dirname $0`
186
187# Read site-specific parameters, like directory and machine names
188. $SCRIPT_DIR/site_info
189
190# Make sure the following parameters are defined in the site_info file:
191required_site_params="
192	ARCHITECTURES \
193	ROTD_DIR \
194	ARCHIVE_DESTS \
195	ECLIPSEGROUP \
196	DISK_MACHINE \
197	CVS_MACHINE \
198	CVSDIR \
199	CVS_RSH \
200	DOC_MACHINE \
201	FIND_MACHINE \
202	PACK_MACHINE \
203"
204
205for param_name in $required_site_params; do
206    eval param_val="\$$param_name"
207    if [ -z "$param_val" ]; then 
208	echo "$0: Please set parameter $param_name in $SCRIPT_DIR/site_info" 1>&2
209	exit 1
210    fi
211done
212
213if [ "$ARCH" = i386_nt -o "$ARCH" = x86_64_nt ] ; then
214    LOCAL_ROTD_DIR=R:
215else
216    LOCAL_ROTD_DIR=$ROTD_DIR
217fi
218
219# Default is world readable
220UMASK=002
221
222# Default is not to nice remote jobs
223NICE=
224
225# Default is not to build from a patch branch
226BRANCH_TAG=
227PATCH_OPTIONS=
228
229# Default is to build with the current date
230DATE_NOW=`date "+%Y-%m-%d %H:%M"`
231DATE_TAG=$DATE_NOW
232DATE_OPTIONS=
233
234clean_up=yes
235increment_buildnum=no
236commit_buildnum=no
237install_archives=yes
238jeclipse_tests=yes
239resume_build=no
240last_successful=no
241
242while [ $# -gt 0 ]; do
243    case "$1" in
244
245    --patch)
246	BRANCH_TAG=$2
247	shift ;;
248
249    --date)
250	DATE_TAG="$2"
251	ROTD_NAME=${ROTD_NAME:-`date -d "$DATE_TAG" +%Y-%m-%d`}
252	shift ;;
253
254    --last-successful)
255	last_successful=yes ;;
256
257    --clean-up)
258	clean_up=yes ;;
259    --no-clean-up)
260	clean_up=no ;;
261
262    --increment-buildnum)
263	increment_buildnum=yes ;;
264    --no-increment-buildnum)
265	increment_buildnum=no ;;
266
267    --install-archives)
268	install_archives=yes ;;
269    --no-install-archives)
270	install_archives=no ;;
271
272    --jeclipse-tests)
273	jeclipse_tests=yes ;;
274    --no-jeclipse-tests)
275	jeclipse_tests=no ;;
276
277    --cvsroot)
278	CVSDIR=$2 ; shift ;;
279
280    --umask)
281	UMASK="$2" ; shift ;;
282
283    --nice)
284	NICE="--nice $2" ; shift ;;
285
286    --rotd-dir)
287	ROTD_DIR=$2 ; shift ;;
288
289    --local-rotd-dir)
290	LOCAL_ROTD_DIR=$2 ; shift ;;
291
292    --rotd-name)
293	ROTD_NAME=$2 ; shift ;;
294
295    --build-script)
296	BUILD_SCRIPT="$2" ; shift ;;
297
298    --resume)
299	resume_build=yes ;;
300
301    --)
302	shift; break ;;
303    -*)
304	echo "$0: unrecognised option: \`$1'" 1>&2
305	echo "$usage" 1>&2
306	exit 1 ;;
307    *)
308	break ;;
309    esac
310    shift
311done
312
313# Architectures to build for
314if [ $# -gt 0 ] ; then
315    ARCHITECTURES="$*"
316fi
317
318ROTD_NAME=${ROTD_NAME:-`date -d "$DATE_TAG" +%Y-%m-%d`}
319
320
321# The kinds of tests to run
322test_embeddings="standalone"
323if [ "$jeclipse_tests" = "yes" ] ; then
324    test_embeddings="$test_embeddings java"
325fi
326
327if [ -z "$CVSDIR_TESTS" ] ; then
328    CVSDIR_TESTS=$CVSDIR
329fi
330
331# Make sure permissions are set appropriately
332umask $UMASK
333
334
335PREFIX=$ROTD_DIR
336LOCAL_PREFIX=$LOCAL_ROTD_DIR
337
338if [ -n "$BRANCH_TAG" ] ; then
339    ROTD_SUBDIR=patch-$ROTD_NAME
340    STABLE_DIR=patch
341    LAST_SUCCESSFUL_BUILD_TAG=last_successful_$BRANCH_TAG
342else
343    ROTD_SUBDIR=rotd-$ROTD_NAME
344    STABLE_DIR=dev
345    LAST_SUCCESSFUL_BUILD_TAG=last_successful_main_branch
346fi
347
348if [ "$last_successful" = no ] ; then
349    # use BRANCH_TAG (empty for main) together with DATE_TAG
350    PATCH_TAG=$BRANCH_TAG
351    if [ -n "$PATCH_TAG" ] ; then
352	PATCH_OPTIONS="-r \"$PATCH_TAG\""
353    fi
354    DATE_OPTIONS="-D \"$DATE_TAG\""
355elif [ -z "$DATE_OPTIONS" -a "$increment_buildnum" = no ] ; then
356    # use non-branch tag LAST_SUCCESSFUL_BUILD_TAG, ignore DATE_TAG
357    PATCH_TAG=$LAST_SUCCESSFUL_BUILD_TAG
358    PATCH_OPTIONS="-r \"$PATCH_TAG\""
359else
360    echo "$0: incompatible options" 1>&2
361    exit 1
362fi
363
364BUILD_DIR=$ROTD_SUBDIR/build
365BUILD_SCRIPT=${BUILD_SCRIPT:-$LOCAL_PREFIX/$BUILD_DIR/BUILD}
366TMP_ARCHIVE_DIR=$ROTD_SUBDIR/archive
367TEST_TEMPLATE_DIR=$ROTD_SUBDIR/test_template
368LOG_DIR=$ROTD_SUBDIR/logs
369RESULT_DIR=$ROTD_SUBDIR/results
370MILESTONE_DIR=$ROTD_SUBDIR/milestones
371MASTER_LOG_FILE=$LOCAL_PREFIX/$ROTD_SUBDIR/master.log
372SSH_LOG_FILE=$LOCAL_PREFIX/$ROTD_SUBDIR/ssh.log.$ROTD_NAME
373ABORT_FLAG=$LOCAL_PREFIX/$ROTD_SUBDIR/abort
374
375
376SUMMARY="
377ROTD Build Summary
378------------------
379
380CVS tags used:    ${PATCH_OPTIONS:-(main branch)}  $DATE_OPTIONS
381CVS dir (source): $CVSDIR
382CVS dir (tests):  $CVSDIR_TESTS
383ROTD directory:   $PREFIX/$ROTD_SUBDIR
384Master logfile:	  $MASTER_LOG_FILE
385"
386if [ "$install_archives" = "yes" ] ; then
387    SUMMARY="${SUMMARY}\
388Archive destinations: $ARCHIVE_DESTS
389"
390else
391    SUMMARY="${SUMMARY}\
392Archive dir:      (not archived)
393"
394fi
395
396if [ "$resume_build" = "yes" ] ; then
397    if [ -d "$LOCAL_PREFIX/$ROTD_SUBDIR" ] ; then
398	SUMMARY="${SUMMARY}\
399Resuming/retrying previous build
400"
401	# Save the old logs...
402	n=1
403	old_log_dir="$LOCAL_PREFIX/$ROTD_SUBDIR/old_logs.$n"
404	while [ -e "$old_log_dir" ] ; do
405	    n=`expr $n + 1`
406	    old_log_dir="$LOCAL_PREFIX/$ROTD_SUBDIR/old_logs.$n"
407	done
408	mkdir -p "$old_log_dir"
409	mv "$LOCAL_PREFIX/$LOG_DIR" "$old_log_dir"
410	mv "$MASTER_LOG_FILE" "$old_log_dir"
411	mv "$SSH_LOG_FILE" "$old_log_dir"
412    else
413	echo "$SUMMARY"
414	echo "ROTD installation directory $LOCAL_PREFIX/$ROTD_SUBDIR does not exist."
415	echo "Unable to resume build."
416	exit 1
417    fi
418else
419    if [ -d "$LOCAL_PREFIX/$ROTD_SUBDIR" ] ; then
420	echo "$SUMMARY"
421	echo "ROTD installation directory $LOCAL_PREFIX/$ROTD_SUBDIR exists."
422	echo "Please delete it or specify an alternate name and try again."
423	exit 1
424    fi
425    df -kP "$LOCAL_PREFIX" | (
426	read line
427	read fs total used avail rest
428	if [ "$avail" -lt 2000000 ] ; then
429	    echo "$SUMMARY"
430	    echo "Not starting build due to insufficient disk space on build filesystem."
431	    echo "Please free some space and try again."
432	    exit 1
433	fi
434    ) || exit 1
435fi
436
437
438### Miscellaneous shell functions ###
439
440# Checks whether something is already in a "list" variable.
441member() {  # element, list
442    member="$1"
443    shift
444    for x in $* ; do
445	if [ "$member" = "$x" ] ; then
446	    return 0
447	fi
448    done
449    false
450}
451
452
453# Duplicate a directory tree.
454duplicate_directory() {	# source directory, destination directory
455    source_dir=$1
456    dest_dir=$2
457    remote_commands "$DISK_MACHINE" "$PREFIX" "
458    	mkdir -p $dest_dir &&
459	cd $source_dir &&
460	tar cf - . | (
461	    cd $PREFIX/$dest_dir &&
462	    tar xf -
463	)
464    "
465}
466
467# Duplicate a directory tree to multiple locations.
468duplicate_directory2() { # source directory, list of destination directories
469    source_dir=$1
470    shift
471    remote_commands "$DISK_MACHINE" "$PREFIX" "
472	tmp_file=/tmp/eclipse_build_tmp.\$\$
473	trap 'rm -f \$tmp_file' 1 2 3 13 15
474    	mkdir -p $* &&
475	cd $source_dir &&
476	tar cf \$tmp_file . &&
477	for d in $* x ; do
478	    [ \"\$d\" = x ] && break
479	    cd $PREFIX/\$d &&
480	    tar xf \$tmp_file \
481	    || break   # Exit the loop early if something failed.
482	done && [ \"\$d\" = x ] &&
483	rm -f \$tmp_file
484    "
485}
486
487
488# Locking facilities for managing parallel processes.
489
490LOCK_DIR=`pwd`/lock_dir
491HAVE_LOCK=no
492
493get_lock() {
494    if [ "$HAVE_LOCK" != "yes" ] ; then
495	while ! mkdir $LOCK_DIR ; do
496	    sleep 1
497	done
498	touch $LOCK_DIR/owned_by_pid_$$
499	HAVE_LOCK=yes
500    fi
501}
502
503release_lock() {
504    if [ "$HAVE_LOCK" = "yes" ] ; then
505	rm -rf $LOCK_DIR
506	HAVE_LOCK=no
507    fi
508}
509
510trap 'release_lock ; exit 1' 1 2 3 13 15
511
512
513# Remote command execution.
514
515# We don't use rsh because it seems to be broken when run on Windows (can't
516# reliably get stdin, stdout & stderr to work properly).  Also, for any (?)
517# version of rsh we can't get the exit status of the remote command without
518# doing a lot of jiggery-pokery.  So we use ssh instead.
519
520SSH_OPTIONS="-A"
521#SSH_OPTIONS="-x"
522#SSH_OPTIONS="-x -o 'BatchMode yes'"
523#SSH_OPTIONS="-x -o \"BatchMode yes\""
524#SSH_OPTIONS="-x -o \'BatchMode yes\'"
525# Don't yet know why I can't get the quoting right on the extra args above.
526# Should specify batch mode since otherwise it can hang indefinitely,
527# waiting for you to confirm logging in to a machine it hasn't seen before.
528# Since ssh is actually only called from one place now, we just specify the
529# options there, which works.
530
531# Usage: remote_commands <machine> <directory> <commands> [<failure count>]
532
533remote_command_number=1
534remote_commands() {
535
536	eval machine_name=\"'$MACHINE_NAME_'$1\"
537	if [ "$machine_name" = "" ] ; then
538	    machine_name="$1"
539	fi
540	eval user=\"'$MACHINE_USER_'$1\"
541	if [ "$user" = "" ] ; then
542	    user_flags=""
543	else
544	    user_flags="-l $user"
545	fi
546
547	# XXX - should change this to avoid temporary files.
548	# (Or at least to clean them up afterwards.)
549	# (But they're so useful for diagnosing what went wrong...)
550	# Note we have to do all this locking rubbish when doing things in
551	# parallel to avoid race conditions...
552	suffix=$$.$remote_command_number
553	get_lock
554	while [ -f input.$suffix ] ; do
555	    remote_command_number=`expr $remote_command_number + 1`
556	    suffix=$$.$remote_command_number
557	done
558	cat > input.$suffix <<END
559	# to be executed on $machine_name
560	echo \$SHELL | grep bash >/dev/null && source ~/.bashrc
561	umask $UMASK
562
563	timeout=6
564	while [ ! -d "$2" -a \$timeout -gt 0 ] ; do
565	    echo "$machine_name: $2 not present, waiting ..."
566	    sleep 5
567	    timeout=\`expr \$timeout - 1\`
568	done
569	cd "$2" || exit 1
570	$3
571END
572	release_lock
573
574	echo `date '+%Y-%m-%d %T'` $remote_command_number \
575		Commencing ssh to $machine_name >> $SSH_LOG_FILE
576	ssh -A -x -o "BatchMode yes" $user_flags "$machine_name" "bash -s" < input.$suffix > output.$suffix 2>&1
577	ssh_result=$?
578	cat output.$suffix
579	rm -f input.$suffix output.$suffix
580	if [ "$ssh_result" -eq 255 ] ; then
581	    echo `date '+%Y-%m-%d %T'` $remote_command_number \
582		    Failed ssh to $machine_name >> $SSH_LOG_FILE
583	    try_number=${4:-1}
584	    echo -n "ssh failed (try $try_number).  "
585	    if [ $try_number -ge 3 ] ; then
586		echo "Giving up."
587		echo `date '+%Y-%m-%d %T'` $remote_command_number \
588			Giving up on ssh to $machine_name >> $SSH_LOG_FILE
589		return $ssh_result
590	    else
591		echo "Trying again."
592		remote_commands "$1" "$2" "$3" `expr $try_number + 1`
593	    fi
594	else
595	    echo `date '+%Y-%m-%d %T'` $remote_command_number \
596		    Completed ssh to $machine_name >> $SSH_LOG_FILE
597	    return $ssh_result
598	fi
599}
600
601
602# Check whether a particular milestone has been successfully completed
603# already.
604milestone_already_achieved() {	# milestone name
605    if [ -e "$LOCAL_PREFIX/$MILESTONE_DIR/$1" ] ; then
606    	return 0
607    elif [ -e "$ABORT_FLAG" ] ; then
608	echo "$ABORT_FLAG found, aborting prematurely"
609    	return 0
610    else
611	return 1
612    fi
613}
614
615# Mark a milestone as successfully completed
616mark_milestone_achieved() {	# milestone name
617    touch "$LOCAL_PREFIX/$MILESTONE_DIR/$1"
618}
619
620
621# Checks that an appropriate machine has been specified for building each
622# architecture.
623check_arch_build_machines() {	# list of architectures
624    check_result=0
625    for arch in $* ; do
626	eval machine=\"'$MACHINE_'$arch\"
627	if [ "$machine" = "" ] ; then
628	    echo "*** Don't know which machine to use for building $arch version."
629	    check_result=1
630	fi
631    done
632
633    [ "$check_result" = 0 ]
634}
635
636# Checks that appropriate machine(s) have been specified for testing each
637# architecture, and for aliases, chooses one machine from each class.
638check_arch_test_machines() {	# list of architectures
639    check_result=0
640    for arch in $* ; do
641	eval machines=\"'$TEST_MACHINES_'$arch\"
642	if [ "$machines" = "" ] ; then
643	    echo "*** Don't know which machine(s) to use for testing $arch version."
644	    check_result=1
645	    continue
646	fi
647
648	real_machines=
649	for m in $machines ; do
650	    # If it's an alias, select one of the machines.
651	    eval choices=\"'$MACHINE_CLASS_ALIAS_'$m\"
652	    if [ "$choices" != "" ] ; then
653		for machine in $choices ; do
654		    if [ "`rsh $machine cplexers -count`" -eq 0 ] ; then
655			break
656		    fi
657		done
658	    else
659		machine=$m
660	    fi
661	    # Record the "class" of the machine (which could be just the
662	    # name of the machine itself).
663	    eval 'CLASS_'$machine=\"$m\"
664	    real_machines="$real_machines $machine"
665	done
666
667	eval 'TEST_MACHINES_'$arch=\"$real_machines\"
668    done
669
670    [ "$check_result" = 0 ]
671}
672
673
674# Check out the ECLiPSe source, ready for building.
675check_out_sources() {	# no arguments
676    mkdir -p "$LOCAL_PREFIX/$BUILD_DIR"
677    mkdir -p "$LOCAL_PREFIX/$LOG_DIR"
678    mkdir -p "$LOCAL_PREFIX/$RESULT_DIR"
679    mkdir -p "$LOCAL_PREFIX/$MILESTONE_DIR"
680
681    CVS_LOGFILE="$PREFIX/$LOG_DIR/log.cvs"
682
683    if milestone_already_achieved checked_out_sources ; then
684	echo "Milestone: Skipping checkout of sources"
685    else
686	remote_commands "$CVS_MACHINE" "$PREFIX/$BUILD_DIR" "
687	    echo \"Checking out sources from CVS.\" | tee -a $CVS_LOGFILE
688	    echo \"See $CVS_LOGFILE for details.\"
689
690	    [ -n \"$PATCH_OPTIONS\" ] \
691		&& echo \"Using version from repository with tag $PATCH_TAG\" \
692		| tee -a $CVS_LOGFILE
693	    [ -n '$DATE_OPTIONS' ] \
694		&& echo \"Using version from repository with date $DATE_TAG\" \
695		| tee -a $CVS_LOGFILE
696
697	    # current directory assumed to be $PREFIX
698	    (
699		cd .. &&
700		cvs -q -d \"$CVSDIR\" checkout -d \"`basename "$BUILD_DIR"`\" \
701		    $PATCH_OPTIONS $DATE_OPTIONS Eclipse
702	    ) >> $CVS_LOGFILE 2>&1 &&
703
704	    echo \"Done.\" | tee -a $CVS_LOGFILE \
705	    || {
706		echo \"CVS checkout failed.\" | tee -a $CVS_LOGFILE
707		false
708	    }
709	" && mark_milestone_achieved checked_out_sources
710    fi
711}
712
713# Build ECLiPSe on the specified architecture.
714build_architecture() {	# architecture
715    arch=$1
716    eval machine='$MACHINE_'$arch
717
718    BUILD_LOGFILE="$PREFIX/$LOG_DIR/log.$arch.build"
719    LOCAL_BUILD_LOGFILE="$LOCAL_PREFIX/$LOG_DIR/log.$arch.build"
720
721    case "$arch" in
722	i386_nt)
723	    CONFIG_HOST="--host=i386-mingw32msvc" ;;
724	x86_64_nt)
725	    CONFIG_HOST="--host=x86_64-pc-mingw32" ;;
726	i386_linux)
727	    CONFIG_HOST="--build=i586-pc-linux-gnu" ;;
728	*)
729	    CONFIG_HOST= ;;
730    esac
731
732    if milestone_already_achieved built_$arch ; then
733	echo "Milestone: Skipping build of $arch"
734    else
735	remote_commands "$machine" "$PREFIX/$BUILD_DIR" "
736	    echo \"Building $arch version on $machine.\" \
737		| tee -a $BUILD_LOGFILE
738	    echo \"See $BUILD_LOGFILE for details.\"
739	    # In case we're cross-compiling
740	    ARCH=\"$arch\"
741	    export ARCH
742
743	    (
744                uname -a
745		CONFIG_SITE=config.$arch ./configure $CONFIG_HOST
746		make -f Makefile.$arch
747	    ) >> $BUILD_LOGFILE 2>&1 &&
748
749	    echo \"Done.\" | tee -a $BUILD_LOGFILE
750	" &&
751
752	mark_milestone_achieved built_$arch \
753	|| {
754	    echo "Build failed." | tee -a $LOCAL_BUILD_LOGFILE
755	    false
756	}
757    fi
758}
759
760# Build the documentation.
761build_documentation() {	# no arguments
762    DOC_LOGFILE="$PREFIX/$LOG_DIR/log.docs"
763
764    remote_commands "$DOC_MACHINE" "$PREFIX/$BUILD_DIR" "
765	echo \"Building documentation on $DOC_MACHINE.\" | tee $DOC_LOGFILE
766	echo \"See $DOC_LOGFILE for details.\"
767
768	make -f Makefile.\$ARCH install_documents >> $DOC_LOGFILE 2>&1 &&
769
770	echo \"Done.\" | tee -a $DOC_LOGFILE \
771	|| {
772	    echo \"Build failed.\" | tee -a $DOC_LOGFILE
773	    false
774	}
775    "
776}
777
778# Create the distribution archives for the specified architectures.
779build_archives() {	# list of achitectures
780    PACK_LOGFILE="$PREFIX/$LOG_DIR/log.pack"
781
782    remote_commands "$PACK_MACHINE" "$PREFIX/$BUILD_DIR" "
783    	echo \"Building distribution archives on $PACK_MACHINE.\" \
784	    | tee $PACK_LOGFILE
785	echo \"See $PACK_LOGFILE for details.\"
786
787        echo \"Packing ECLiPSe v=$ECLIPSE_VERSION bn=$BUILD_NUMER. \"
788	./PACK --version-num \"$ECLIPSE_VERSION\" --build-num \"$BUILD_NUMBER\" \
789	       --dest-dir \"$PREFIX/$TMP_ARCHIVE_DIR\" $* < /dev/null \
790	       >> $PACK_LOGFILE 2>&1 &&
791
792	# this should be in the PACK script itself:
793	for arch in $* x ; do
794	    [ \"\$arch\" = x ] && break
795
796	    cd $PREFIX/$TMP_ARCHIVE_DIR/\$arch &&
797	    ln -s ../common/* . &&
798
799	    # Apache http server displays contents of README file,
800	    # but also hides the file.  That's why we create both
801	    # README and Readme ...
802	    if [ \"\$arch\" = i386_nt -o \"\$arch\" = x86_64_nt ] ; then
803		# Change Windoze installer permission
804		chmod ug+w,ugo+rx ECLiPSe*.exe
805
806		# Don't include the UNPACK script
807		rm -f UNPACK
808		ln -s ../common/README_WIN.TXT README &&
809		ln -s ../common/README_WIN.TXT Readme.txt
810	    else
811		ln -s ../common/README_UNIX README &&
812		ln -s ../common/README_UNIX Readme.txt
813	    fi \
814	    || break	# Exit the loop early if something failed.
815	done && [ \"\$arch\" = x ] &&
816
817	echo \"Done.\" | tee -a $PACK_LOGFILE \
818	|| {
819	    echo \"Pack failed.\" | tee -a $PACK_LOGFILE
820	    false
821	}
822    "
823}
824
825clean_build_archs() {	# list of architectures
826    if [ "$clean_up" = "yes" ] ; then
827	remote_commands "$FIND_MACHINE" "$PREFIX/$BUILD_DIR" "
828	    for arch in $* ; do
829		# Delete all directories specific to this architecture in
830		# the build directory.
831		# XXX - should change this to not delete any CVS-controlled
832		# file.
833		find $PREFIX/$BUILD_DIR -name \"\$arch\" -depth \
834			-exec rm -rf {} \;
835	    done
836	"
837    fi
838}
839
840
841# NUM_INSTALLS		Number of installs
842# INSTALL_<n>_archs	Architectures for install n
843# INSTALL_<n>_name	"Name" for install n
844# INSTALL_<n>_package	Package for install n
845# INSTALL_<n>_type	Install type for install n (solo / all)
846# INSTALL_<n>_keep	Whether to keep install n when everything's finished
847# 			(default is to keep combined installs)
848# INSTALL_all_<package>	Which install number corresponds to the installation
849# 			of the given package for all architectures together
850
851# Generate a set of installation combinations, placing their details in the
852# INSTALL_* variables.
853generate_install_combinations() {	# list of architectures
854    # Install each architecture independently, plus all together
855    n=0
856    for install_name in $* all ; do
857	if [ "$install_name" = all ] ; then
858	    archs="$*"
859	else
860	    archs="$install_name"
861	fi
862
863	for package_type in standard runtime ; do
864	    n=`expr $n + 1`
865
866	    eval INSTALL_${n}_archs=\"$archs\"
867	    eval INSTALL_${n}_name=\"$install_name\"
868	    eval INSTALL_${n}_package=\"$package_type\"
869	    if [ "$install_name" = all ] ; then
870		eval INSTALL_${n}_type=all
871		eval INSTALL_${n}_keep=0
872		eval INSTALL_all_${package_type}=$n
873	    else
874		eval INSTALL_${n}_type=solo
875		eval INSTALL_${n}_keep=1
876	    fi
877	done
878    done
879    NUM_INSTALLS=$n
880}
881
882# Set a number of variables based on the appropriate settings for the given
883# installation.
884set_install_params() {	# installation number
885    eval archs=\"'${INSTALL_'$1'_archs}'\"
886    eval install_name=\"'${INSTALL_'$1'_name}'\"
887    eval package_type=\"'${INSTALL_'$1'_package}'\"
888    eval install_type=\"'${INSTALL_'$1'_type}'\"
889    install_dir="$ROTD_SUBDIR/$install_name/install.$package_type"
890    install_logfile="$LOG_DIR/log.$install_name.install.$package_type"
891    install_milestone_key="${install_name}_${package_type}"
892}
893
894# Specify that the given installation should be kept (e.g. due to test
895# failure).
896set_keep_install() {	# installation number
897    eval INSTALL_${1}_keep=0
898}
899
900# Query whether the given installation should be kept, or whether it can be
901# deleted.
902keep_install() {	# installation number
903    eval [ \"'${INSTALL_'$1'_keep}'\" = 0 ]
904}
905
906# Install the archives for a given installation.
907install_archives() {	# installation number
908    set_install_params $1
909
910    INSTALL_LOGFILE=$PREFIX/$install_logfile
911    LOCAL_INSTALL_LOGFILE=$LOCAL_PREFIX/$install_logfile
912
913    # We should really check here for missing installation directory for
914    # tests we're actually going to run...
915#    if [ -d "$LOCAL_PREFIX/$install_dir" ] && milestone_already_achieved installed_$install_milestone_key ; then
916    if milestone_already_achieved installed_$install_milestone_key ; then
917	echo "Milestone: Skipping install of $install_milestone_key"
918    else
919	remote_commands "$DISK_MACHINE" "$PREFIX" "
920	    echo \"Installing ($package_type) archives for $install_name in\" \
921		    | tee -a $INSTALL_LOGFILE
922	    echo \"$PREFIX/$install_dir\" | tee -a $INSTALL_LOGFILE
923
924	    (
925		mkdir -p $PREFIX/$install_dir &&
926
927		# First copy the architecture-independent stuff.  Note we
928		# don't bother installing it properly; we leave that for
929		# when the first architecture gets installed.
930
931		# Copy the common archives.
932		if [ \"$package_type\" = runtime ] ; then
933		    # For the runtime version, install just the bare minimum
934		    cp $PREFIX/$TMP_ARCHIVE_DIR/common/UNPACK $PREFIX/$install_dir
935		else
936		    # For the standard version, install everything except
937		    # the source
938		    cp $PREFIX/$TMP_ARCHIVE_DIR/common/* $PREFIX/$install_dir &&
939		    rm -f $PREFIX/$install_dir/eclipse_source.tgz
940		fi &&
941
942		# Now copy and install each architecture.
943		for arch in $archs x ; do
944		    [ \"\$arch\" = x ] && break
945
946		    # Copy the architecture-specific files, inlcuding
947                    # the private solvers needed for the tests
948		    if [ \"$package_type\" = runtime ] ; then
949			# For the runtime version, install just the bare minimum
950			cp $PREFIX/$TMP_ARCHIVE_DIR/\$arch/eclipse_rt.tgz \
951			    $PREFIX/$TMP_ARCHIVE_DIR/\$arch/if_*.tgz \
952			    $PREFIX/$TMP_ARCHIVE_DIR/private/\$arch/if_*.tgz \
953			    $PREFIX/$install_dir \
954			|| true	# Ignore failure if no if_*.tgz files exist.
955		    else
956			cp $PREFIX/$TMP_ARCHIVE_DIR/common/* \
957			     $PREFIX/$TMP_ARCHIVE_DIR/\$arch/* \
958 			     $PREFIX/$TMP_ARCHIVE_DIR/private/\$arch/if_*.tgz \
959			     $PREFIX/$install_dir 
960                        # Ignore cp failure if no if_*.tgz files exist
961			rm -f $PREFIX/$install_dir/eclipse_rt.tgz
962		    fi &&
963
964		    # Install the archives.
965		    cd \"$PREFIX/$install_dir\" &&
966		    # Avoid permission problems if files are not user-writable
967		    chmod -R u+w . &&
968		    ./UNPACK &&
969		    rm -f *.tgz \
970		    || break	# Exit the loop early if something failed.
971		done && [ \"\$arch\" = x ] &&
972
973		# Extract additional files needed for the tests
974		tar xfpz $PREFIX/$TMP_ARCHIVE_DIR/private/common/eclipse_private.tgz \
975			lib/t_all.eco lib/time_log.eco &&
976
977		# Extract additional files needed for the runtime tests
978		# If we have the i386_nt architecture, we prefer it
979		# because it has one extra file
980		if [ \"$package_type\" = runtime ] ; then
981		    for arch in $archs ; do
982			if [ \"\$arch\" = i386_nt -o \"\$arch\" = x86_64_nt ] ; then
983			    tar xfpz $PREFIX/$TMP_ARCHIVE_DIR/\$arch/eclipse_basic.tgz \
984				    ecl_inst.js lib/test_util.eco lib/mip.eco &&
985			    break
986			fi
987			# If the loop terminates normally, make sure it
988			# looks like a failure.
989			false
990		    done \
991		    || if [ \"\$arch\" != i386_nt -a \"\$arch\" != x86_64_nt ] ; then
992			tar xfpz $PREFIX/$TMP_ARCHIVE_DIR/\$arch/eclipse_basic.tgz \
993			    lib/test_util.eco lib/mip.eco
994		    fi
995		fi
996	    ) >> $INSTALL_LOGFILE 2>&1
997	" &&
998
999	# Now run the bits that need to be done on the architecture machine.
1000	# Note that there's no point running ecl_inst for i386_nt now ---
1001	# we need to run it just before each test or it may point to the wrong
1002	# installation.
1003	(
1004	    install_result=0
1005	    for arch in $archs ; do
1006		[ "$arch" = i386_nt -o "$arch" = x86_64_nt ] && continue	# Skip i386_nt.
1007
1008		eval machine=\"'$MACHINE_'$arch\"
1009
1010		echo "Installing for machine $machine and arch $arch " | tee -a $LOCAL_INSTALL_LOGFILE
1011
1012		eval jre=\"'$JRE_HOME_'$arch\"
1013		remote_commands "$machine" "$PREFIX/$install_dir" "
1014                     # In case we are cross-building (e.g. 32 on 64 bit)
1015	             ARCH=\"$arch\"
1016	             export ARCH
1017                     eval JRE_HOME=\"$jre\"
1018                     export JRE_HOME
1019		    ./RUNME < /dev/null >> $INSTALL_LOGFILE 2>&1
1020		" || install_result=1
1021	    done
1022	    [ "$install_result" = 0 ]
1023	) &&
1024
1025	mark_milestone_achieved installed_$install_milestone_key &&
1026
1027	echo "Done." | tee -a $LOCAL_INSTALL_LOGFILE \
1028	|| {
1029	    echo "Install failed." | tee -a $LOCAL_INSTALL_LOGFILE
1030	    false
1031	}
1032    fi
1033}
1034
1035# Installs the archives for all generated installation combinations, and
1036# constructs a list of the successful ones in the variable
1037# `SUCCESSFUL_INSTALLATIONS'.
1038install_all_archives() {
1039    [ "$NUM_INSTALLS" -ge 1 ] || return 1
1040
1041    install_all_result=0
1042    SUCCESSFUL_INSTALLATIONS=
1043    n=1
1044    while [ "$n" -le "$NUM_INSTALLS" ] ; do
1045    	install_archives $n &&
1046	SUCCESSFUL_INSTALLATIONS="$SUCCESSFUL_INSTALLATIONS $n" \
1047	|| install_all_result=1
1048    	n=`expr $n + 1`
1049    done
1050
1051    [ "$install_all_result" = 0 ]
1052}
1053
1054
1055# NUM_TESTS		Number of tests
1056# TEST_<n>_install	Installation number for test n
1057# TEST_<n>_arch		Architecture for test n
1058# TEST_<n>_machine	Machine for test n
1059# TEST_<n>_package	Package for test n (should be same as for installation)
1060# TEST_<n>_embedding	Embedding for test n
1061# TEST_<n>_successful	Whether test n succeeded or not
1062# TEST_<n>_keep		Whether to keep test n when everything's finished
1063# TESTS_<machine>_<phase>   List of test numbers to run on given machine
1064#			    in given test phase (see run_all_tests)
1065# TEST_MACHINES		List of machines on which some tests are to be run
1066
1067# TEST_RESULT_<type>_<package>_<embedding>_<machine>
1068# 			Result of test which matches the given parameters
1069
1070# Generate a set of test combinations, placing their details in the TEST_*
1071# variables.
1072generate_test_combinations() {	# list of installations
1073    TEST_MACHINES=
1074
1075    n=0
1076    for install_num in $* ; do
1077    	set_install_params $install_num
1078
1079	for arch in $archs ; do
1080	    if [ "$install_name" = all ] ; then
1081		if [ "$arch" = i386_nt -o "$arch" = x86_64_nt ] ; then
1082		    phase=1
1083		else
1084		    phase=2
1085		fi
1086	    else
1087		if [ "$arch" = i386_nt -o "$arch" = x86_64_nt ] ; then
1088		    phase=2
1089		else
1090		    phase=1
1091		fi
1092	    fi
1093
1094	    eval machines=\"'$TEST_MACHINES_'$arch\"
1095
1096	    for machine in $machines ; do
1097		member "$machine" "$TEST_MACHINES" \
1098		    || TEST_MACHINES="$TEST_MACHINES $machine"
1099		eval ARCH_$machine=$arch
1100
1101		for test_embedding in $test_embeddings ; do
1102		    # Skip the jeclipse tests if we can't find jeclipse.
1103		    if [ "$test_embedding" = "java" ] &&
1104			    ! supports_java $machine $arch
1105		    then
1106			echo "Java not supported for $machine/$arch - skipping jeclipse tests."
1107			continue
1108		    fi
1109
1110		    n=`expr $n + 1`
1111
1112		    eval TEST_${n}_install=\"$install_num\"
1113		    eval TEST_${n}_arch=\"$arch\"
1114		    eval TEST_${n}_machine=\"$machine\"
1115		    eval TEST_${n}_package=\"$package_type\"
1116		    eval TEST_${n}_embedding=\"$test_embedding\"
1117		    eval TEST_${n}_keep=1
1118		    eval TESTS_${machine}_${phase}=\"'$TESTS_'$machine'_'$phase $n\"
1119		done
1120	    done
1121	done
1122    done
1123    NUM_TESTS=$n
1124}
1125
1126# Set a number of variables based on the appropriate settings for the given
1127# test.
1128set_test_params() {	# test number
1129    eval install_num=\"'${TEST_'$1'_install}'\"
1130    set_install_params $install_num
1131    eval arch=\"'${TEST_'$1'_arch}'\"
1132    eval machine=\"'${TEST_'$1'_machine}'\"
1133    eval package_type=\"'${TEST_'$1'_package}'\"
1134    eval test_embedding=\"'${TEST_'$1'_embedding}'\"
1135    eval test_successful=\"'${TEST_'$1'_successful}'\"
1136    eval class=\"'${CLASS_'$machine'}'\"
1137    test_dir="$ROTD_SUBDIR/$install_name/test.$package_type.$test_embedding.$machine"
1138    test_result_file="$RESULT_DIR/result.$install_name.test.$package_type.$test_embedding.$class"
1139    test_logfile="$LOG_DIR/log.$install_name.test.$package_type.$test_embedding.$machine"
1140    eval test_milestone_key=\"${install_milestone_key}_${test_embedding}_${class}\"
1141    if [ "$package_type" = runtime ] ; then
1142	test_flags="--test-flags runtime"
1143    else
1144	test_flags=
1145    fi
1146    if [ "$test_embedding" = java ] ; then
1147    	test_shell=jeclipse
1148	test_flags="$test_flags --test-flags embeddedjava"
1149    else
1150    	test_shell=eclipse
1151    fi
1152    if ! supports_java $machine $arch ; then
1153	test_flags="$test_flags --test-flags no_java"
1154    fi
1155}
1156
1157# Specify that the given test should be kept (e.g. because it failed).
1158set_keep_test() {	# test number
1159    eval TEST_${1}_keep=0
1160}
1161
1162# Query whether the given test should be kept, or whether it can be
1163# deleted.
1164keep_test() {	# test number
1165    eval [ \"'${TEST_'${1}'_keep}'\" = 0 ]
1166}
1167
1168# Remove duplicates from the TEST_MACHINES variable.
1169# Not used any more.
1170filter_test_machines() {
1171    TEST_MACHINES=`
1172    	for machine in $TEST_MACHINES ; do
1173	    echo $machine
1174	done | sort -u
1175    `
1176}
1177
1178
1179# Check out the tests to the given subdirectory.
1180check_out_tests() {	# subdirectory (of [LOCAL_]PREFIX)
1181    test_dir_=$1
1182    CVS_LOGFILE="$PREFIX/$LOG_DIR/log.cvs"
1183
1184    # Shouldn't worry about missing test template directory unless we're
1185    # going to run tests which don't have a test directory present...
1186    if [ -d "$LOCAL_PREFIX/$test_dir_" ] && milestone_already_achieved checked_out_tests ; then
1187	echo "Milestone: Skipping checkout of tests"
1188    else
1189	remote_commands "$CVS_MACHINE" "$PREFIX/$ROTD_SUBDIR" "
1190	    echo \"Checking out the tests to $test_dir_.\" \
1191		    | tee -a $CVS_LOGFILE
1192	    [ -n \"$PATCH_OPTIONS\" ] &&
1193		echo \"Using version from repository with tag $PATCH_TAG\" \
1194		    | tee -a $CVS_LOGFILE
1195	    [ -n '$DATE_OPTIONS' ] &&
1196		echo \"Using version from repository with date $DATE_TAG\" \
1197		    | tee -a $CVS_LOGFILE
1198	    echo \"See $CVS_LOGFILE for details.\"
1199
1200	    # Careful with the permissions.
1201	    (
1202		mkdir -p \"$PREFIX/$test_dir_\" &&
1203		chmod o-rwx \"$PREFIX/$test_dir_\" &&
1204		chgrp $ECLIPSEGROUP \"$PREFIX/$test_dir_\" &&
1205		cd \"`dirname "$PREFIX/$test_dir_"`\" &&
1206		cvs -q -d \"$CVSDIR_TESTS\" checkout -d \"`basename "$test_dir_"`\" \
1207			$PATCH_OPTIONS $DATE_OPTIONS Tests
1208	    ) >> $CVS_LOGFILE 2>&1 &&
1209
1210	    echo \"Done.\" | tee -a $CVS_LOGFILE \
1211	    || {
1212		echo \"Test checkout failed.\" | tee -a $CVS_LOGFILE
1213		false
1214	    }
1215	" && mark_milestone_achieved checked_out_tests
1216    fi
1217}
1218
1219# Checks out all the test directory for all tests.
1220check_out_all_tests() {
1221    test_dirs=
1222
1223    n=1
1224    while [ "$n" -le "$NUM_TESTS" ] ; do
1225	set_test_params $n
1226	if [ -d "$LOCAL_PREFIX/$test_dir" ] || milestone_already_achieved tested_$test_milestone_key ; then
1227	    echo "Milestone: Skipping copy of tests for $test_milestone_key"
1228	else
1229	    test_dirs="$test_dirs $test_dir"
1230	fi
1231	n=`expr $n + 1`
1232    done
1233
1234    if [ "$test_dirs" != "" ] ; then
1235	duplicate_directory2 $TEST_TEMPLATE_DIR $test_dirs
1236    fi
1237}
1238
1239
1240# Really awful hack to make the remote ROTD_DIR_xxx path acceptable
1241# to a remote (cygwin-)rsync on a windows machine.
1242
1243rsync_path() {
1244    echo $1 | sed "s/^[a-zA-Z]:\/cygwin\//\//"
1245}
1246
1247
1248# Copy relevant parts (needed for tests) to a remote machine
1249# In: $machine $arch
1250# Out: $remote_prefix $is_remote_machine
1251
1252rsync_out() {		# ($machine, $arch -> $is_remote_machine, $remote_prefix)
1253    eval rsync_machine_name=\"'$MACHINE_NAME_'$machine\"
1254    if [ "$rsync_machine_name" = "" ] ; then
1255	rsync_machine_name="$machine"
1256    fi
1257    eval is_remote_machine=\"'$REMOTE_MACHINE_'$machine\"
1258    if [ -n "$is_remote_machine" ] ; then
1259	echo `date '+%Y-%m-%d %T'` "Commencing rsync to $rsync_machine_name" >> $SSH_LOG_FILE
1260	eval remote_prefix=\"'$ROTD_DIR_'$machine\"
1261	rsync_prefix=`rsync_path $remote_prefix`
1262	(
1263	    cd "$PREFIX"
1264	    remote_commands "$DISK_MACHINE" "$PREFIX" "
1265		rsync -aRu --rsh=ssh --timeout=600 \
1266			--exclude 'aux.*' --exclude '*::*' \
1267			--include 'test.*.$machine/' \
1268			--exclude 'test.*/' \
1269			$ROTD_SUBDIR/all $ROTD_SUBDIR/$arch \
1270			$rsync_machine_name:$rsync_prefix
1271	    " &&
1272	    remote_commands "$machine" "$remote_prefix/$ROTD_SUBDIR" "
1273		mkdir -p logs
1274	    " && echo `date '+%Y-%m-%d %T'` "Completed rsync to $rsync_machine_name" >> $SSH_LOG_FILE
1275	) || {
1276	    echo "Failed to rsync to $rsync_machine_name" 
1277	    echo `date '+%Y-%m-%d %T'` "Failed rsync to $rsync_machine_name" >> $SSH_LOG_FILE
1278	    false
1279	}
1280    else
1281	remote_prefix="$PREFIX"
1282    fi
1283}
1284
1285# Copy things back from remote machine after tests have been run
1286# In: $machine
1287
1288rsync_in() {	# ($machine)
1289    eval rsync_machine_name=\"'$MACHINE_NAME_'$machine\"
1290    if [ "$rsync_machine_name" = "" ] ; then
1291	rsync_machine_name="$machine"
1292    fi
1293    eval is_remote_machine=\"'$REMOTE_MACHINE_'$machine\"
1294    if [ -n "$is_remote_machine" ] ; then
1295	echo `date '+%Y-%m-%d %T'` "Commencing rsync from $rsync_machine_name" >> $SSH_LOG_FILE
1296	eval remote_prefix=\"'$ROTD_DIR_'$machine\"
1297	rsync_prefix=`rsync_path $remote_prefix`
1298	remote_commands "$DISK_MACHINE" "$PREFIX" "
1299	    rsync -rl --rsh=ssh --timeout=300 --ignore-existing $rsync_machine_name:$rsync_prefix/$ROTD_SUBDIR $PREFIX
1300	" &&
1301	echo `date '+%Y-%m-%d %T'` "Completed rsync from $rsync_machine_name" >> $SSH_LOG_FILE ||
1302	{
1303	    echo "Failed to rsync back from $rsync_machine_name"
1304	    echo `date '+%Y-%m-%d %T'` "Failed rsync from $rsync_machine_name" >> $SSH_LOG_FILE
1305	    false
1306	}
1307    fi
1308}
1309
1310
1311# Run the tests for i386_nt
1312# Allow for non-shared filesystem
1313
1314run_test_win_nt() {
1315    # When testing the java embedding on i386_nt/x86_64_nt, we have to use 
1316    # the java command with all its options, since attempts to use 
1317    # jeclipse.bat did not work.
1318
1319    rsync_out || return 1	# ($machine, $arch -> $remote_prefix)
1320
1321    standalone_binary="$remote_prefix/$install_dir/lib/$arch/eclipse"
1322
1323    remote_commands "$machine" "$remote_prefix/$test_dir" "
1324	ARCH="$arch"
1325	export ARCH
1326
1327	# Use the version of cscript (32/64bit) that corresponds
1328	# to the architecture we want to test. We assume that this
1329	# shell script is always executed by a 32-bit bash!
1330	CSCRIPT=\"\$SYSTEMROOT/Sysnative/cscript.exe\"
1331	if [ ! -f \"\$CSCRIPT\" -o $arch = i386_nt ] ; then
1332	    CSCRIPT=cscript
1333	fi
1334
1335	# Make sure the registry settings are appropriate for this test.
1336	# This destroys the registry settings on the local machine, but
1337	# is necessary for the tests to work.
1338	#cd \"$remote_prefix/$install_dir\" &&
1339	\"\$CSCRIPT\" $remote_prefix/$install_dir/ecl_inst.js $ECLIPSE_VERSION \
1340		>> $remote_prefix/$test_logfile 2>&1 &&
1341	if [ \"$test_embedding\" = \"java\" ] ; then
1342	    # Run eclipse to get the JRE location
1343	    JRE_DIR_WIN=\`\"$standalone_binary\" -e \"getenv(\\\"JRE_HOME\\\", WinPath), write(WinPath)\" | tr '\\\\\\\\' /\`
1344
1345	    PATH=\"\`cygpath -p -u $remote_prefix/$install_dir\`/lib/$arch:\$PATH\"
1346	    export PATH
1347
1348	    # Use javaw rather than java in order to avoid silly \"DOS boxes\"
1349	    # popping up on the screen while the tests are running.
1350	    # -Xss flag is used to increase the default stack size
1351	    \"$remote_prefix/$test_dir/test_eclipse\" \
1352		--test-dir \"$remote_prefix/$test_dir\" \
1353		$test_flags \
1354		\"\$JRE_DIR_WIN/bin/javaw\" \
1355		    -Xss3000k -Declipse.directory=\"$remote_prefix/$install_dir\" \
1356		    -classpath \"$remote_prefix/$install_dir/lib/eclipse.jar;\$JRE_DIR_WIN/rt.jar\" \
1357		    com.parctechnologies.eclipse.JEclipse
1358	else
1359	    \"$remote_prefix/$test_dir/test_eclipse\" \
1360		--test-dir \"$remote_prefix/$test_dir\" \
1361		$test_flags \
1362		\"$standalone_binary\" -D \"$remote_prefix/$install_dir\"
1363	fi >> $remote_prefix/$test_logfile 2>&1
1364    "
1365    this_test_result=$?
1366
1367    rsync_in	# ($machine)
1368
1369    return $this_test_result
1370}
1371
1372# Run the tests on a remote Unix machine.
1373run_test_unix() {
1374    rsync_out   # ($machine, $arch -> $is_remote_machine, $remote_prefix)
1375    eval jre=\"'$JRE_HOME_'$arch\"
1376    if [ -n "$is_remote_machine" ] ; then
1377	remote_commands "$machine" "$remote_prefix" "
1378	    cd $install_dir &&
1379	    rm -f lib/$arch/SITE_PARAMS &&
1380            ARCH=$arch &&
1381            export ARCH &&
1382            eval JRE_HOME=\"$jre\" &&
1383            export JRE_HOME &&
1384	    ./RUNME < /dev/null >> \"$remote_prefix/$test_logfile\" 2>&1
1385	"
1386    fi
1387    remote_commands "$machine" "$remote_prefix" "
1388	timeout=6
1389	while [ ! -d "$test_dir" -a \$timeout -gt 0 ] ; do
1390	    echo \"\$machine: $test_dir not present, waiting ...\"
1391	    sleep 5
1392	    timeout=\`expr \$timeout - 1\`
1393	done
1394        cd $test_dir &&
1395        \"$remote_prefix/$test_dir/test_eclipse\" \
1396                --test-dir \"$remote_prefix/$test_dir\" \
1397                $test_flags \
1398                \"$remote_prefix/$install_dir/bin/$arch/$test_shell\" \
1399                >> $remote_prefix/$test_logfile 2>&1
1400    "
1401    this_test_result=$?
1402    rsync_in    # ($machine)
1403    return $this_test_result
1404}
1405
1406
1407# Run the given test.
1408run_test() {	# test number
1409    test_num=$1
1410
1411    set_test_params $test_num
1412
1413    #duplicate_directory $TEST_TEMPLATE_DIR $test_dir
1414
1415    TEST_LOGFILE=$PREFIX/$test_logfile
1416    LOCAL_TEST_LOGFILE=$LOCAL_PREFIX/$test_logfile
1417
1418    if [ -e "$ABORT_FLAG" ] ; then
1419	echo "$ABORT_FLAG found, aborting prematurely"
1420	false
1421    elif [ -e $LOCAL_PREFIX/$test_result_file ] && milestone_already_achieved tested_$test_milestone_key ; then
1422	echo "Milestone: Skipping testing for $test_milestone_key"
1423    else
1424	echo "Running test $test_num ($install_type/$package_type/$test_embedding) on $machine." | tee -a $LOCAL_TEST_LOGFILE
1425
1426	if [ "$arch" = i386_nt  -o "$arch" = x86_64_nt ] ; then
1427	    run_test_win_nt
1428	else
1429	    run_test_unix
1430	fi
1431	run_test_result=$?
1432
1433	{
1434	    echo TEST_RESULT_${install_type}_${package_type}_${test_embedding}_${machine}=$run_test_result
1435	    echo TEST_${test_num}_successful=$run_test_result 
1436	} > $LOCAL_PREFIX/$test_result_file
1437
1438	if [ "$run_test_result" = 0 ] ; then
1439	    mark_milestone_achieved tested_$test_milestone_key
1440	    echo "Test $test_num ($install_type/$package_type/$test_embedding) on $machine successful." | tee -a $LOCAL_TEST_LOGFILE
1441	else
1442	    echo "Test $test_num ($install_type/$package_type/$test_embedding) on $machine failed." | tee -a $LOCAL_TEST_LOGFILE
1443	    false
1444	fi
1445    fi
1446}
1447
1448# Run all the tests on the given machine.
1449test_machine() {	# machine, phase
1450    eval tests=\"'$TESTS_'$1'_'$2\"
1451    test_machine_result=0
1452    for test_num in $tests ; do
1453	run_test $test_num || test_machine_result=1
1454    done
1455    if [ "$test_machine_result" = 0 ] ; then
1456	echo "Testing machine $1 (phase $2) completed: success."
1457    else
1458	echo "Testing machine $1 (phase $2) completed: failure."
1459	false
1460    fi
1461}
1462
1463# Run all the tests, with the tests on different machines done in parallel.
1464run_all_tests() {
1465    # filter_test_machines
1466
1467    run_all_tests_result=0
1468
1469    # We run the tests in two phases, to avoid i386_nt machines accessing
1470    # the "all" installations at the same time as the other architectures.
1471    # This is because that seems to trigger NFS returning incorrect
1472    # timestamps for files, resulting in some libraries being re-loaded,
1473    # which causes intermittent variations in test output.
1474
1475    # The first phase consists of running the "all" i386_nt tests in
1476    # parallel with the "solo" tests for other architectures; the second
1477    # phase reverses this arrangement.  (See also
1478    # generate_test_combinations.)
1479
1480    for phase in 1 2 ; do
1481	# Fork off a process for each machine.
1482	process_list=
1483	for machine in $TEST_MACHINES ; do
1484	    test_machine $machine $phase &
1485	    process_list="$process_list $!"
1486	done
1487
1488	# Wait for all the forked off processes to terminate, noting if there
1489	# were any failures.
1490	for process in $process_list ; do
1491	    wait $process || run_all_tests_result=1
1492	done
1493    done
1494
1495    # Read the results for individual tests that were written out by the
1496    # parallel subprocesses.
1497    n=1
1498    while [ $n -le $NUM_TESTS ] ; do
1499	set_test_params $n
1500	. $LOCAL_PREFIX/$test_result_file \
1501	|| eval TEST_RESULT_${install_type}_${package_type}_${test_embedding}_${machine}='?'
1502
1503	if eval [ \"'$TEST_RESULT_'${install_type}_${package_type}_${test_embedding}_${machine}\" != 0 ] ; then
1504	    # Something went wrong, so make sure we keep the test and
1505	    # corresponding installation.
1506	    set_keep_test $n
1507	    set_keep_install $install_num
1508	fi
1509
1510	n=`expr $n + 1`
1511    done
1512
1513    [ "$run_all_tests_result" = 0 ]
1514}
1515
1516
1517# Print the results of the tests in a nice table.
1518print_test_results() {
1519    echo
1520    echo "                           solo  all solo  all solo  all solo  all"
1521    echo "                            std  std  run  run  std  std  run  run"
1522    echo "    Machine          Arch  none none none none java java java java"
1523    echo "    -------          ----  ---- ---- ---- ---- ---- ---- ---- ----"
1524
1525    for machine in $TEST_MACHINES ; do
1526	eval arch=\"'${ARCH_'$machine'}'\"
1527    	printf "%11s  %12s " $machine $arch
1528
1529	for test_embedding in $test_embeddings ; do
1530	    for package_type in standard runtime ; do
1531		for install_type in solo all ; do
1532		    eval res='$TEST_RESULT_'${install_type}_${package_type}_${test_embedding}_${machine}
1533		    [ "$res" = 0 ] && res=yes
1534		    [ "$res" = 1 ] && res=no
1535		    [ "$res" = "" ] && res="-"
1536		    printf "%5s" "$res"
1537		done
1538	    done
1539	done
1540	echo
1541    done
1542}
1543
1544print_failed_test_logs() {
1545    n=1
1546    while [ $n -le $NUM_TESTS ] ; do
1547	set_test_params $n
1548
1549	if eval [ \"'$TEST_RESULT_'${install_type}_${package_type}_${test_embedding}_${machine}\" != 0 ] ; then
1550	    # Something went wrong, so print the test log
1551	    echo
1552	    cat $LOCAL_PREFIX/$test_logfile
1553	    echo See $test_dir for details.
1554	fi
1555
1556	n=`expr $n + 1`
1557    done
1558}
1559
1560# Check if anything has changed since the last successful build
1561anything_changed() {
1562    DIFF_LOGFILE="$PREFIX/$LOG_DIR/log.diff"
1563    remote_commands "$CVS_MACHINE" "$PREFIX/$BUILD_DIR" "
1564	echo \"Checking whether anything has changed since the last build.\"
1565        echo \"Differences written to $DIFF_LOGFILE.\"
1566	# get diffs and filter out any lines beginning with ? (non-cvs files)
1567	cvs -q -d \"$CVSDIR\" diff --brief -r $LAST_SUCCESSFUL_BUILD_TAG \
1568		2>&1 | grep -v \"^? \" >> $DIFF_LOGFILE
1569	if [ -s $DIFF_LOGFILE ] ; then
1570	    echo \"Something has changed.\" | tee -a $CVS_LOGFILE
1571	    true
1572	else
1573	    echo \"Nothing has changed.\" | tee -a $CVS_LOGFILE
1574	    false
1575	fi
1576    "
1577}
1578
1579# Choose a working machine and installation combination for the ECLiPSe just
1580# built.
1581choose_working_eclipse() {
1582    # Find an eclipse that is *vaguely working* ---- except we make sure we
1583    # don't pick a Windows machine because the paths would be wrong.
1584    for arch in $built_archs ; do
1585        if [ "$arch" = i386_nt -o "$arch" = x86_64_nt ] ; then
1586            continue
1587        fi
1588        eval machine=\"'$MACHINE_'$arch\"
1589        remote_commands "$machine" "$PREFIX/$BUILD_DIR" "
1590            TEST_STRING=\"Working\" &&
1591            ECL_RESULT=\`./bin/$arch/eclipse -e \"writeln(\$TEST_STRING)\"\` &&
1592            [ \"\$ECL_RESULT\" = \"\$TEST_STRING\" ]
1593        " &&
1594            return
1595    done
1596    return 1
1597}
1598
1599# Increment the build number.
1600increment_build_number() {
1601
1602    # These settings will also be used later in commit_build_number
1603    VERSION_LOGFILE=$PREFIX/$LOG_DIR/log.version
1604    LOCAL_VERSION_LOGFILE=$LOCAL_PREFIX/$LOG_DIR/log.version
1605    # In release 6.0, the version.pl file moved to Kernel/lib
1606    if [ -d "$LOCAL_PREFIX/$BUILD_DIR/Kernel" ] ; then
1607	VERSION_FILE="Kernel/lib/version.pl"
1608    else
1609	VERSION_FILE="sepia/lib/version.pl"
1610    fi
1611
1612    if milestone_already_achieved incremented_build_number ; then
1613	echo "Milestone: Skipping incrementing build number"
1614    else
1615	LOCAL_VERSION_FILE="$LOCAL_PREFIX/$BUILD_DIR/$VERSION_FILE"
1616	OLD_BUILD=`grep sepia_build < "$LOCAL_VERSION_FILE" | tr -cd 0123456789` &&
1617	NEW_BUILD=`expr $OLD_BUILD + 1` &&
1618	sed "s/sepia_build(.*)/sepia_build($NEW_BUILD)/" "$LOCAL_VERSION_FILE" \
1619			> "$LOCAL_VERSION_FILE.new" &&
1620	mv "$LOCAL_VERSION_FILE.new" "$LOCAL_VERSION_FILE" &&
1621	chmod a+r,ug+w "$LOCAL_VERSION_FILE" &&
1622	mark_milestone_achieved incremented_build_number
1623    fi
1624
1625}
1626
1627
1628# CVS-commit the build number.
1629commit_build_number() {
1630
1631    if milestone_already_achieved committed_build_number ; then
1632	echo "Milestone: Skipping commit build number"
1633    else
1634	echo "Committing build number." | tee $VERSION_LOGFILE
1635	echo "See $VERSION_LOGFILE for details."
1636
1637	# Check in the updated version.pl
1638	# file, making sure we update to the head of the appropriate branch
1639	# first (since the main branch versions are checked out with a sticky
1640	# date, which prevents commits).
1641	remote_commands "$CVS_MACHINE" "$PREFIX/$BUILD_DIR" "
1642	    {
1643		cvs -d \"$CVSDIR\" update -A $PATCH_OPTIONS \
1644			\"$VERSION_FILE\" &&
1645		cvs -d \"$CVSDIR\" commit -m \"Successfully built $ECLIPSE_VERSION #$BUILD_NUMBER\" \
1646			\"$VERSION_FILE\"
1647	    } >> $VERSION_LOGFILE 2>&1
1648	" &&
1649
1650	mark_milestone_achieved committed_build_number &&
1651
1652	echo "Build number committed successfully." \
1653	    | tee -a $LOCAL_VERSION_LOGFILE \
1654	|| {
1655	    echo "Couldn't commit build number." \
1656		| tee -a $LOCAL_VERSION_LOGFILE
1657	    false
1658	}
1659    fi
1660}
1661
1662# CVS-tag the repository
1663update_lastsucc_tags() {
1664
1665    if milestone_already_achieved updated_lastsucc_tags ; then
1666	echo "Milestone: Skipping update last_successful tags"
1667    else
1668	echo "Updating last_successful tags." | tee $VERSION_LOGFILE
1669	echo "See $VERSION_LOGFILE for details."
1670
1671	# Update the last successful build
1672	# tag to point to the version just built (tagging version.pl after the
1673	# increment so it won't register as changed next time).
1674	# Note that we have to remove the tag from everything in the repository
1675	# rather than just forcing an update to the current versions, in case
1676	# files have been removed since they were tagged (otherwise they remain
1677	# tagged indefinitely).
1678	remote_commands "$CVS_MACHINE" "$PREFIX/$BUILD_DIR" "
1679	    {
1680		{ cvs -d \"$CVSDIR\" rtag -a -d $LAST_SUCCESSFUL_BUILD_TAG Eclipse ||
1681		  echo \"Sources rtag -d returned\" \$? \"(ignoring)\"
1682		} &&
1683		cvs -d \"$CVSDIR\" tag -F $LAST_SUCCESSFUL_BUILD_TAG &&
1684		echo \"Sources done.\"
1685	    } >> $VERSION_LOGFILE 2>&1
1686	" &&
1687	remote_commands "$CVS_MACHINE" "$PREFIX/$TEST_TEMPLATE_DIR" "
1688	    {
1689		cvs -d \"$CVSDIR_TESTS\" rtag -a -d $LAST_SUCCESSFUL_BUILD_TAG Tests &&
1690		cvs -d \"$CVSDIR_TESTS\" tag -F $LAST_SUCCESSFUL_BUILD_TAG &&
1691		echo \"Tests done.\"
1692	    } >> $VERSION_LOGFILE 2>&1
1693	" &&
1694
1695	mark_milestone_achieved updated_lastsucc_tags &&
1696
1697	echo "Tags updated successfully." \
1698	    | tee -a $LOCAL_VERSION_LOGFILE \
1699	|| {
1700	    echo "Couldn't update last_successful tags." \
1701		| tee -a $LOCAL_VERSION_LOGFILE
1702	    false
1703	}
1704    fi
1705}
1706
1707# Update the ROTD symlinks to point to the version we just built and tested.
1708update_symlinks() {
1709    if milestone_already_achieved updated_symlinks ; then
1710	echo "Milestone: Skipping updating symlinks"
1711    else
1712	# Update the symlinks for the standard version.
1713	[ -n "$INSTALL_all_standard" ] &&
1714	set_install_params $INSTALL_all_standard &&
1715	remote_commands "$DISK_MACHINE" "$PREFIX/$ROTD_SUBDIR" "
1716	    umask $UMASK
1717
1718	    rm -f $PREFIX/$STABLE_DIR &&
1719	    ln -s $install_dir $PREFIX/$STABLE_DIR
1720	" &&
1721
1722	# Update the symlinks for the runtime version.
1723	[ -n "$INSTALL_all_runtime" ] &&
1724	set_install_params $INSTALL_all_runtime &&
1725	remote_commands "$DISK_MACHINE" "$PREFIX/$ROTD_SUBDIR" "
1726	    umask $UMASK
1727
1728	    rm -f $PREFIX/$STABLE_DIR-runtime &&
1729	    ln -s $install_dir $PREFIX/$STABLE_DIR-runtime
1730	" &&
1731
1732	mark_milestone_achieved updated_symlinks
1733    fi
1734}
1735
1736
1737# Make a tarball of the successfully built and tested source. 
1738# We cvs-export the version we just tagged with LAST_SUCCESSFUL_BUILD_TAG,
1739# tar it up, and add it to the archives.
1740
1741pack_source_archive() {
1742    if milestone_already_achieved packed_source ; then
1743	echo "Milestone: Skipping packing of source"
1744    else
1745	clean_source_dir=Eclipse_${ECLIPSE_VERSION}_${BUILD_NUMBER}
1746	source_archive=archive/src/eclipse_src.tgz
1747	PACK_SRC_LOGFILE="$PREFIX/$LOG_DIR/log.pack.source"
1748
1749	remote_commands "$CVS_MACHINE" "$PREFIX/$ROTD_SUBDIR" "
1750	    echo \"Packing source archive on $PACK_MACHINE.\" \
1751		| tee $PACK_SRC_LOGFILE
1752	    echo \"See $PACK_SRC_LOGFILE for details.\"
1753	    {
1754		cvs -q -d \"$CVSDIR\" export -d $clean_source_dir \
1755		    -r $LAST_SUCCESSFUL_BUILD_TAG Eclipse &&
1756		mkdir -p `dirname $source_archive` &&
1757		tar cfz $source_archive $clean_source_dir &&
1758		chmod a+r,ug+w $source_archive &&
1759		rm -rf $clean_source_dir
1760	    } >> $PACK_SRC_LOGFILE 2>&1 &&
1761
1762	    echo \"Done.\" | tee -a $PACK_SRC_LOGFILE \
1763	    || {
1764		echo \"Pack source failed.\" | tee -a $PACK_SRC_LOGFILE
1765		false
1766	    }
1767	" &&
1768
1769	mark_milestone_achieved packed_source
1770    fi
1771}
1772
1773
1774# Copy the new archives to the appropriate location on the FTP site.
1775# Note that it copies everything (except the private subdirectory)
1776# on the assumption that the files should only be installed if
1777# everything succeeded.
1778# Archive directory management:
1779# - Before creating FTP directory for the new version, delete any directory
1780#   for the same version of ECLiPSe which contains a .superseded file but
1781#   not a .keep file.
1782# - Create a .superseded file in any directory for this version which did
1783#   not have one previously.
1784# - Copy the new archives over.
1785
1786copy_to_ftps() {
1787    # requires: ECLIPSE_VERSION BUILD_NUMBER ARCHIVE_DESTS
1788
1789    PUBLISH_LOGFILE=$PREFIX/$LOG_DIR/log.publish
1790    if [ -n "$ARCHIVE_DESTS" ] ; then
1791	all_ftps_ok=0
1792	for archive_dest in $ARCHIVE_DESTS ; do
1793	    FTP_MACHINE=`echo $archive_dest|sed 's/:.*//'`
1794	    BASE_ARCHIVE_DIR=`echo $archive_dest|sed 's/.*://'`
1795	    copy_to_ftp || all_ftps_ok=1
1796	done 
1797	return $all_ftps_ok
1798    elif [ -n "$FTP_MACHINE" && -n "$BASE_ARCHIVE_DIR" ] ; then
1799	# backward compatibility only
1800   	copy_to_ftp
1801    else
1802	false
1803    fi
1804}
1805
1806
1807copy_files_to_ftp() {	# $1=files $2=ftp_dir 
1808
1809    echo Copying "$1" to "$FTP_MACHINE:$2" >>$PUBLISH_LOGFILE
1810
1811    # Copy everything across (from DISK_MACHINE to FTP_MACHINE)
1812    eval ftp_machine_name=\"'$MACHINE_NAME_'$FTP_MACHINE\" &&
1813    if [ "$ftp_machine_name" = "" ] ; then
1814	ftp_machine_name="$FTP_MACHINE"
1815    fi &&
1816    eval ftp_user=\"'$MACHINE_USER_'$FTP_MACHINE\" &&
1817    if [ "$ftp_user" = "" ] ; then
1818	ftp_user_flags=""
1819    else
1820	ftp_user_flags="-l $ftp_user"
1821    fi &&
1822    remote_commands "$DISK_MACHINE" "$PREFIX/$TMP_ARCHIVE_DIR" "
1823	umask $UMASK
1824
1825	#rsync -aR --rsh=ssh $1 $ftp_machine_name:$2
1826	tar cf - --exclude=private $1 | \
1827	    ssh $ftp_user_flags $ftp_machine_name \
1828		    \"cd $2 ; tar xfp -\"
1829    " &&
1830
1831    # Make final adjustments
1832    remote_commands "$FTP_MACHINE" "$BASE_ARCHIVE_DIR" "
1833	chmod o+rx $2
1834    "
1835}
1836
1837
1838copy_to_ftp() {
1839    # requires: ECLIPSE_VERSION BUILD_NUMBER FTP_MACHINE BASE_ARCHIVE_DIR
1840
1841    [ "$install_archives" = yes ] || return 0
1842
1843    ARCHIVE_DIR=$BASE_ARCHIVE_DIR/${ECLIPSE_VERSION}_$BUILD_NUMBER
1844    NEW_ARCHIVE_DIR=$ARCHIVE_DIR.tmp
1845
1846    echo "ECLiPSe version" $ECLIPSE_VERSION "; build number" $BUILD_NUMBER
1847
1848    if milestone_already_achieved copied_to_ftp_$FTP_MACHINE ; then
1849	echo "Milestone: Skipping copying to FTP $FTP_MACHINE"
1850
1851    elif [ "$last_successful" = yes ] ; then
1852	# make a list of the missing architectures on FTP_MACHINE
1853	
1854	command="
1855		[ -d \"$ARCHIVE_DIR\" ] &&
1856		for d in $ARCHITECTURES ; do
1857		    if [ ! -d \"$ARCHIVE_DIR/\$d\" ]; then echo \$d; fi
1858		done
1859	    "
1860	MISSING_ARCHS=`remote_commands "$FTP_MACHINE" "$BASE_ARCHIVE_DIR" "$command"` &&
1861	echo missing $MISSING_ARCHS &&
1862	# normalise (strip blank space) for the comparisons below
1863	MISSING_ARCHS=`echo $MISSING_ARCHS` &&
1864	ARCHITECTURES=`echo $ARCHITECTURES` &&
1865
1866	if [ "$MISSING_ARCHS" = "" ] ; then
1867	    MSG="Nothing to add to FTP site $FTP_MACHINE!" &&
1868	    echo "$MSG" >> $MASTER_LOG_FILE &&
1869	    SUMMARY="${SUMMARY}
1870$MSG"
1871	else
1872	    MSG="Adding these architectures to FTP site $FTP_MACHINE:
1873$MISSING_ARCHS" &&
1874	    echo "$MSG" >> $MASTER_LOG_FILE &&
1875	    SUMMARY="${SUMMARY}
1876$MSG" &&
1877	    copy_files_to_ftp "$MISSING_ARCHS" "$ARCHIVE_DIR"
1878	fi &&
1879
1880	mark_milestone_achieved copied_to_ftp_$FTP_MACHINE || {
1881	    echo "Copying files to FTP site $FTP_MACHINE failed." >> $MASTER_LOG_FILE 2>&1
1882	    SUMMARY="${SUMMARY}
1883Copying files to FTP site $FTP_MACHINE failed.
1884"
1885	    false
1886	}
1887
1888    else
1889	# Remove superseded versions, mark unmarked version(s) as superseded.
1890	# Be very careful.  We don't want to accidentally blow away the entire
1891	# contents of the FTP directory.  :)
1892	if [ -n "$ECLIPSE_VERSION" ] ; then
1893	    remote_commands "$FTP_MACHINE" "$BASE_ARCHIVE_DIR" "
1894		umask $UMASK
1895
1896		for d in '$ECLIPSE_VERSION'* ; do
1897		    if [ -e ./\$d ] ; then
1898			if [ -e ./\$d/.superseded ] ; then
1899			    if [ ! -e ./\$d/.keep ] ; then
1900				echo Deleting ./\$d
1901				rm -rf ./\$d
1902				#echo Would have deleted ./\$d
1903			    fi
1904			else
1905			    touch ./\$d/.superseded
1906			fi
1907		    fi
1908		done
1909	    "
1910	fi &&
1911
1912	# Prepare a destination directory
1913	remote_commands "$FTP_MACHINE" "$BASE_ARCHIVE_DIR" "
1914	    umask $UMASK
1915
1916	    rm -rf $NEW_ARCHIVE_DIR &&
1917	    mkdir -p $NEW_ARCHIVE_DIR &&
1918	    chmod o-rwx $NEW_ARCHIVE_DIR
1919	" &&
1920
1921	copy_files_to_ftp '*' $NEW_ARCHIVE_DIR &&
1922
1923	remote_commands "$FTP_MACHINE" "$BASE_ARCHIVE_DIR" "
1924	    mv $NEW_ARCHIVE_DIR $ARCHIVE_DIR
1925	" &&
1926
1927	mark_milestone_achieved copied_to_ftp_$FTP_MACHINE \
1928	|| {
1929	    # If something went wrong with the copy, don't delete the old
1930	    # directory(s) next time.
1931	    remote_commands "$DISK_MACHINE" "$BASE_ARCHIVE_DIR" "
1932		for d in '$ECLIPSE_VERSION'* ; do
1933		    rm -f ./\$d/.superseded
1934		done
1935	    "
1936	    echo "Copying files to FTP site $FTP_MACHINE failed." >> $MASTER_LOG_FILE 2>&1
1937	    SUMMARY="${SUMMARY}
1938	Copying files to FTP site $FTP_MACHINE failed.
1939	"
1940	    false
1941	}
1942    fi
1943}
1944
1945# Delete some directories that aren't needed any more.
1946clean_up() {
1947    [ "$clean_up" = "yes" ] || return 0
1948
1949    # Construct a list of directories to delete.
1950    # XXX - Should also delete the build directory if everything worked?
1951    # XXX - Should leave a note saying we've deleted the directories?  :)
1952    # Don't delete the test template directory??
1953#    del_dir_list=$PREFIX/$TEST_TEMPLATE_DIR
1954    del_dir_list=
1955    n=1
1956    while [ "$n" -le "$NUM_INSTALLS" ] ; do
1957	set_install_params $n
1958    	keep_install $n || del_dir_list="$del_dir_list $PREFIX/$install_dir"
1959	n=`expr $n + 1`
1960    done
1961    n=1
1962    while [ "$n" -le "$NUM_TESTS" ] ; do
1963	set_test_params $n
1964    	keep_test $n || del_dir_list="$del_dir_list $PREFIX/$test_dir"
1965	n=`expr $n + 1`
1966    done
1967    remote_commands "$DISK_MACHINE" "$PREFIX/$ROTD_SUBDIR" "
1968	rm -rf $del_dir_list
1969	rm -f $ABORT_FLAG
1970    "
1971}
1972
1973fix_perms() {
1974    # Be careful not to make the test directories world-readable.  The only
1975    # thing we really need to make available to the world is the main
1976    # installation...
1977    remote_commands "$DISK_MACHINE" "$PREFIX/$ROTD_SUBDIR" "
1978	chgrp -R $ECLIPSEGROUP \"$PREFIX/$ROTD_SUBDIR\"
1979	chmod -R g+rwX \"$PREFIX/$ROTD_SUBDIR\"
1980	chmod -R o+rX \"$PREFIX/$ROTD_SUBDIR/all/\"install.*
1981    "
1982}
1983
1984
1985### Start of main script ###
1986
1987# Start with some basic integrity checks.
1988
1989check_arch_build_machines $ARCHITECTURES || exit 1
1990check_arch_test_machines $ARCHITECTURES || exit 1
1991
1992
1993# Check out the sources.
1994tmp_res=$?
1995
1996# The tmp_log / tmp_res hack is to get around the fact that the log file
1997# belongs in a directory which is not allowed to exist yet.
1998
1999tmp_log=`check_out_sources`
2000tmp_res=$?
2001
2002echo "$SUMMARY" > $MASTER_LOG_FILE 2>&1
2003echo "$tmp_log" >> $MASTER_LOG_FILE 2>&1
2004
2005if [ "$tmp_res" -ne 0 ] ; then
2006    echo "CVS checkout failed.  Aborting." >> $MASTER_LOG_FILE 2>&1
2007    echo "$SUMMARY"
2008    echo "CVS checkout failed."
2009    exit 1
2010fi
2011
2012
2013# Variable for recording that everything important (build, install, test)
2014# all worked OK for all architectures/machines/etc..
2015everything_ok=0
2016
2017
2018# Increment the build number in the checked out version.pl file
2019# (only if anything has changed since the last successful build)
2020
2021if anything_changed >> $MASTER_LOG_FILE 2>&1 ; then
2022    something_changed=yes
2023else
2024    something_changed=no
2025fi
2026
2027if [ "$increment_buildnum" = no ] ; then
2028    echo "Increment of build number was not requested." >> $MASTER_LOG_FILE 2>&1
2029    SUMMARY="${SUMMARY}
2030Increment of build number was not requested.
2031"
2032elif [ "$something_changed" = yes ] ; then
2033    if increment_build_number >> $MASTER_LOG_FILE 2>&1 ; then
2034        commit_buildnum=yes
2035    else
2036	echo "Failed to increment build number." >> $MASTER_LOG_FILE 2>&1
2037	SUMMARY="${SUMMARY}
2038Failed to increment build number.
2039"
2040	everything_ok=1
2041    fi
2042else
2043    echo "Skipping increment of build number since nothing has changed." >> $MASTER_LOG_FILE 2>&1
2044    SUMMARY="${SUMMARY}
2045Skipping increment of build number since nothing has changed.
2046"
2047fi
2048
2049
2050# We check out the template test directory now so that it is more likely to
2051# be in sync with the sources we just checked out than if we wait several
2052# hours until it's actually required.
2053check_out_tests $TEST_TEMPLATE_DIR >> $MASTER_LOG_FILE 2>&1
2054
2055
2056# Build the system on the specified architectures.
2057
2058built_archs=
2059SUMMARY="${SUMMARY}
2060Architectures to build:	 "`echo $ARCHITECTURES`"
2061"			# ^^ Formatting hack ^^
2062
2063all_builds_succeeded=0
2064for arch in $ARCHITECTURES ; do
2065    if build_architecture $arch ; then
2066	echo "Build on $arch successful."
2067	built_archs="$built_archs $arch"
2068    else
2069	echo "Build on $arch failed."
2070	all_builds_succeeded=1
2071    fi
2072done >> $MASTER_LOG_FILE 2>&1
2073
2074SUMMARY="${SUMMARY}\
2075Built successfully:	$built_archs
2076"
2077
2078if [ "$all_builds_succeeded" -ne 0 ] ; then
2079    everything_ok=1
2080    SUMMARY="${SUMMARY}
2081Error: building some architectures failed.
2082"
2083fi
2084
2085# Build documentation.
2086
2087if milestone_already_achieved built_documentation ; then
2088    echo "Milestone: Skipping build of documentation" >> $MASTER_LOG_FILE 2>&1
2089else
2090    if build_documentation >> $MASTER_LOG_FILE 2>&1 ; then
2091	mark_milestone_achieved built_documentation
2092	echo "Build of documentation successful." >> $MASTER_LOG_FILE 2>&1
2093    else
2094	echo "Build of documentation failed." >> $MASTER_LOG_FILE 2>&1
2095	echo "$SUMMARY"
2096	echo "Build of documentation failed."
2097	everything_ok=1
2098    fi
2099fi
2100
2101if [ -z "$built_archs" ] ; then
2102    echo "No architectures were built successfully." \
2103	    >> $MASTER_LOG_FILE 2>&1
2104    echo "$SUMMARY"
2105    echo "No architectures were built successfully."
2106    fix_perms >> $MASTER_LOG_FILE 2>&1
2107    exit 1
2108fi
2109
2110# Obtain ECLiPSe Version and build number
2111
2112if ! choose_working_eclipse ; then
2113    echo "Unable to find a working ECLiPSe to get version numbers for packing."\
2114	    >> $MASTER_LOG_FILE 2>&1
2115    echo "$SUMMARY"
2116    echo "Unable to find a working ECLiPSe to get version numbers for packing."
2117    fix_perms >> $MASTER_LOG_FILE 2>&1
2118    exit 1
2119fi
2120
2121ECLIPSE_VERSION=`remote_commands "$machine" "$PREFIX/$ROTD_SUBDIR" "
2122    $PREFIX/$BUILD_DIR/bin/$arch/eclipse -e \"\
2123	get_flag(version, Version),\
2124	writeln(Version)\
2125    \"
2126"`
2127BUILD_NUMBER=`remote_commands "$machine" "$PREFIX/$ROTD_SUBDIR" "
2128    $PREFIX/$BUILD_DIR/bin/$arch/eclipse -e \"\
2129	get_flag(version_as_list, [_Major, _Minor, Build]),\
2130	writeln(Build)\
2131    \"
2132"`
2133
2134#printf(\\\"%d.%d_%d%n\\\", [Major, Minor, Build])\
2135
2136# Build distribution archives.
2137
2138if milestone_already_achieved built_archives ; then
2139    echo "Milestone: Skipping build of archives" >> $MASTER_LOG_FILE 2>&1
2140else
2141    echo "Building distribution archives for: $built_archs." \
2142	    >> $MASTER_LOG_FILE 2>&1
2143
2144    if build_archives $built_archs >> $MASTER_LOG_FILE 2>&1 ; then
2145	mark_milestone_achieved built_archives
2146	echo "Build of distribution archives successful." \
2147		>> $MASTER_LOG_FILE 2>&1
2148    else
2149	echo "$SUMMARY"
2150	echo "Build of distribution archives failed." \
2151	    | tee -a $MASTER_LOG_FILE
2152	# No point continuing
2153	fix_perms >> $MASTER_LOG_FILE 2>&1
2154	exit 1
2155    fi
2156fi
2157
2158
2159# Do some cleaning up.
2160
2161#clean_build_archs $built_archs >> $MASTER_LOG_FILE 2>&1
2162
2163
2164# Install the archives.
2165
2166generate_install_combinations $built_archs >> $MASTER_LOG_FILE 2>&1
2167
2168install_all_archives >> $MASTER_LOG_FILE 2>&1 || everything_ok=1
2169
2170if [ -z "$SUCCESSFUL_INSTALLATIONS" ] ; then
2171    echo "$SUMMARY"
2172    echo "No architectures were installed successfully." \
2173	| tee -a $MASTER_LOG_FILE
2174    fix_perms >> $MASTER_LOG_FILE 2>&1
2175    exit 1
2176fi
2177
2178
2179# Test the archives.
2180
2181generate_test_combinations $SUCCESSFUL_INSTALLATIONS >> $MASTER_LOG_FILE 2>&1
2182
2183# We can't just check out all tests now --- it would be 600 megabytes!
2184# Yes we can, we got lots more scratch space now.
2185check_out_all_tests >> $MASTER_LOG_FILE 2>&1
2186
2187run_all_tests >> $MASTER_LOG_FILE 2>&1 || everything_ok=1
2188
2189SUMMARY="${SUMMARY}\
2190`print_test_results`
2191"
2192
2193
2194# Increment the build number if everything went well and there's been some
2195# change since the last successful build. Also pack corresponding sources.
2196
2197[ "$everything_ok" = 0 ] &&
2198
2199# create a file in the archive directory specifying the version
2200remote_commands "$DISK_MACHINE" "$PREFIX/$TMP_ARCHIVE_DIR" "
2201    touch \"This is ECLiPSe $ECLIPSE_VERSION#$BUILD_NUMBER\"
2202" &&
2203
2204if [ "$commit_buildnum" = no ] ; then
2205    # either no increment requested, or no change
2206    if [ "$last_successful" = yes ] ; then
2207	SUMMARY="${SUMMARY}
2208This is a slave build of ECLiPSe version ${ECLIPSE_VERSION}#${BUILD_NUMBER}
2209"
2210    elif [ "$something_changed" = yes ] ; then
2211	SUMMARY="${SUMMARY}
2212This would have been ECLiPSe version ${ECLIPSE_VERSION}#${BUILD_NUMBER}+1
2213"
2214    else
2215	SUMMARY="${SUMMARY}
2216This is a redundant build of ECLiPSe version ${ECLIPSE_VERSION}#${BUILD_NUMBER}
2217"
2218    fi
2219elif commit_build_number >> $MASTER_LOG_FILE 2>&1 ; then
2220    SUMMARY="${SUMMARY}
2221This is ECLiPSe version ${ECLIPSE_VERSION}#${BUILD_NUMBER}
2222"
2223    have_new_version=yes
2224else
2225    echo "Failed to commit build number." >> $MASTER_LOG_FILE 2>&1
2226    SUMMARY="${SUMMARY}
2227Failed to commit build number.
2228"
2229    false
2230fi || everything_ok=1
2231
2232
2233if [ "$have_new_version" = yes ] ; then
2234    if ! update_lastsucc_tags >> $MASTER_LOG_FILE 2>&1 ; then
2235	everything_ok=1
2236    elif ! pack_source_archive >> $MASTER_LOG_FILE 2>&1 ; then
2237	everything_ok=1
2238    fi
2239fi
2240
2241
2242
2243# Only copy distribution archives to FTP site and make "stable"
2244# symlinks if the build number was incremented --- otherwise the
2245# build number still can't be used to uniquely identify a version.
2246if [ "$everything_ok" = 0 -a "$have_new_version" = yes ] ; then
2247    if ! update_symlinks >> $MASTER_LOG_FILE 2>&1 ; then
2248	echo "Updating symlinks failed." >> $MASTER_LOG_FILE 2>&1
2249	SUMMARY="${SUMMARY}
2250Updating symlinks failed.
2251"
2252	false
2253    fi
2254else
2255    echo "Skipping updating of symlinks." >> $MASTER_LOG_FILE 2>&1
2256    SUMMARY="${SUMMARY}
2257Skipping updating of symlinks.
2258"
2259    true
2260fi || everything_ok=1
2261
2262
2263if [ "$everything_ok" = 0  -a \
2264	\( "$have_new_version" = yes -o "$last_successful" = yes \) ]; then
2265    if copy_to_ftps >> $MASTER_LOG_FILE 2>&1 ; then
2266	true
2267    else
2268	echo "Copying files to FTP site failed." >> $MASTER_LOG_FILE 2>&1
2269	SUMMARY="${SUMMARY}
2270Copying files to FTP site failed.
2271"
2272	false
2273    fi
2274else
2275    echo "Skipping copy to FTP site." >> $MASTER_LOG_FILE 2>&1
2276    SUMMARY="${SUMMARY}
2277Skipping copy to FTP site.
2278"
2279    true
2280fi || everything_ok=1
2281
2282
2283# Clean up any unneeded directories.
2284clean_up >> $MASTER_LOG_FILE 2>&1
2285
2286fix_perms >> $MASTER_LOG_FILE 2>&1
2287
2288
2289echo "$SUMMARY"
2290if [ $everything_ok -eq 0 ] ; then
2291    echo "Build script ran to completion (successful build)."
2292else
2293    echo "Build script ran to completion (unsuccessful build)."
2294fi
2295
2296print_failed_test_logs
2297
2298# If there were any problems, exit with an appropriate code.
2299
2300exit $everything_ok
2301
2302