1#!/usr/bin/env bash
2# Remote testing of Automake tarballs made easy.
3# This script requires Bash 4.x or later.
4
5# Copyright (C) 2013-2021 Free Software Foundation, Inc.
6
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2, or (at your option)
10# any later version.
11
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16
17# You should have received a copy of the GNU General Public License
18# along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
20# TODO: some documentation would be nice ...
21
22set -u
23me=${0##*/}
24
25fatal () { echo "$me: $*" >&2; exit 1; }
26
27cmd='
28  test_script=$HOME/.am-test/run
29  if test -f "$test_script" && test -x "$test_script"; then
30    "$test_script" "$@"
31  else
32    nice -n19 ./configure && nice -n19 make -j10 check
33  fi
34'
35
36remote=
37interactive=1
38maybe_sleep=:
39while test $# -gt 0; do
40  case $1 in
41   -b|--batch) interactive=0;;
42   -c|--command) cmd=${2-}; shift;;
43    # Useful to avoid spurious errors due to skewed clocks between
44    # the system where the tarball is built and the target system.
45   -S|--sleep) maybe_sleep="sleep ${2-}"; shift;;
46   -*) fatal "'$1': invalid option";;
47    *) remote=$1; shift; break;;
48  esac
49  shift
50done
51[[ -n $remote ]] || fatal "no remote given"
52
53if ((interactive)); then
54  do_on_error='{
55    AM_TESTSUITE_FAILED=yes
56    export AM_TESTSUITE_FAILED
57    # We should not modify the environment with which the failed
58    # tests have run, hence do not read ".profile", ".bashrc", and
59    # company.
60    exec bash --noprofile --norc -i
61  }'
62else
63  do_on_error='exit $?'
64fi
65
66tarball=$(echo automake*.tar.xz)
67
68case $tarball in
69  *' '*) fatal "too many automake tarballs: $tarball";;
70esac
71
72test -f $tarball || fatal "no automake tarball found"
73
74distdir=${tarball%%.tar.xz}
75
76env='PATH=$HOME/bin:$PATH'
77if test -t 1; then
78  env+=" TERM='$TERM' AM_COLOR_TESTS=always"
79fi
80
81# This is tempting:
82#   $ ssh "command" arg-1 ... arg-2
83# but doesn't work as expected.  So we need the following hack
84# to propagate the command line arguments to the remote shell.
85quoted_args=--
86while (($# > 0)); do
87  case $1 in
88    *\'*) quoted_args+=" "$(printf '%s\n' "$1" | sed "s/'/'\\''/g");;
89       *) quoted_args+=" '$1'";;
90  esac
91  shift
92done
93
94set -e
95set -x
96
97scp $tarball $remote:tmp/
98
99$maybe_sleep
100
101# Multiple '-t' to force tty allocation.
102ssh -t -t $remote "
103  set -x; set -e; set -u;
104  set $quoted_args
105  cd tmp
106  if test -e $distdir; then
107    # Use 'perl', not only 'rm -rf', to correctly handle read-only
108    # files or directory.  Fall back to 'rm' if something goes awry.
109    perl -e 'use File::Path qw/rmtree/; rmtree(\"$distdir\")' \
110      || rm -rf $distdir || exit 1
111    test ! -e $distdir
112  fi
113  export $env
114  "'
115  am_extra_acdir=$HOME/.am-test/extra-aclocal
116  am_extra_bindir=$HOME/.am-test/extra-bin
117  am_extra_setup=$HOME/.am-test/extra-setup.sh
118  if test -d "$am_extra_acdir"; then
119    export ACLOCAL_PATH=$am_extra_acdir${ACLOCAL_PATH+":$ACLOCAL_PATH"}
120  fi
121  if test -d "$am_extra_bindir"; then
122    export PATH=$am_extra_bindir:$PATH
123  fi
124  '"
125  xz -dc $tarball | tar xf -
126  cd $distdir
127  if test -f \"\$am_extra_setup\"; then
128    . \"\$am_extra_setup\"
129  fi
130  ($cmd) || $do_on_error
131"
132