blob: 0c3cf042281e899443081bd23884eb67ade451df [file] [log] [blame]
#!/usr/bin/env bash
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Files are relative to this script directory.
SELF="${BASH_SOURCE[0]}"
cd "$( dirname "${BASH_SOURCE[0]}" )"
COMPOSE_FILE=./infrastructure/docker/build/docker-compose.yml
# Check for dependencies
if ! which docker >/dev/null 2>&1; then
echo "Error: docker is required for a docker build." >&2
exit 1
fi
# If the user defined COMPOSE, use that as the path for docker-compose.
if [ ! -z "$COMPOSE" ]; then
COMPOSECMD=( "$COMPOSE" )
else
COMPOSECMD=()
fi
# Check to see if docker-compose is already installed and use it directly, if possible.
if [ ${#COMPOSECMD[@]} -eq 0 ]; then
if which docker-compose >/dev/null 2>&1; then
COMPOSECMD=( docker-compose )
fi
fi
# If it's unavailable, go get the image and run docker-compose inside a container.
# This is considerably slower, but allows for building on hosts without docker-compose.
if [ ${#COMPOSECMD[@]} -eq 0 ]; then
# Pin the version of docker-compose.
IMAGE="docker/compose:1.11.2"
# We need to either mount the docker socket or export the docker host into the container.
# This allows the container to manage "sibling" containers via docker.
if [ -z "$DOCKER_HOST" ]; then
DOCKER_HOST="/var/run/docker.sock"
fi
if [ -S "$DOCKER_HOST" ]; then
DOCKER_ADDR=(-v "$DOCKER_HOST:$DOCKER_HOST" -e DOCKER_HOST)
else
DOCKER_ADDR=(-e DOCKER_HOST -e DOCKER_TLS_VERIFY -e DOCKER_CERT_PATH)
fi
# We mount the current directory (the base of the repository) into the same location
# inside the container. There are many places for which this won't work, but "/" is
# a major one.
#
# You're going to want to avoid keeping your repository in a folder named "/usr/bin",
# "/home", "/var" or any other standard paths that will be needed by the docker container.
#
# This is very unlikely to cause trouble for anyone in practice.
if [ "$(pwd)" == "/" ]; then
echo "Error: Cannot compile directly at filesystem root." >&2
exit 1
fi
# Mount the working directory, and the home directory. Mounting $HOME provides container
# access to config files that are kept there.
VOLUMES=(-v "$(pwd):$(pwd)" -v "$HOME:$HOME" -v "$HOME:/root")
# Prepull the image, to avoid spitting out pull progress during other commands.
if ! docker inspect $IMAGE >/dev/null 2>&1; then
docker pull $IMAGE >/dev/null 2>&1
fi
# COMPOSECMD is kept as an array to significantly simplify handling paths that contain
# spaces and other special characters.
COMPOSECMD=(docker run --rm "${DOCKER_ADDR[@]}" $COMPOSE_OPTIONS "${VOLUMES[@]}" -w "$(pwd)" $IMAGE)
fi
# Parse command line arguments
verbose=0
while getopts :lvq? opt; do
case $opt in
\?)
PROJECTS=`$SELF -l | sed "s/^/ - /"`
echo "Usage: $SELF [options] [projects]"
echo " -q Quiet mode. Supresses output."
echo " -v Verbose mode. Lists all build output."
echo " -l List available projects."
echo
echo " If no projects are listed, all projects will be packaged."
echo " Valid projects:"
cat <<< "$PROJECTS"
exit 0
;;
q)
exec >/dev/null 2>&1
;;
v)
verbose=1
;;
l)
"${COMPOSECMD[@]}" -f $COMPOSE_FILE config --services
exit $?
;;
esac
done
shift $((OPTIND-1))
# If no specific packages are listed, run them all.
if (( ! "$#" )); then
set -- `$SELF -l`
fi
# Build each project in turn.
failure=0
badproj=""
while (( "$#" )); do
echo Building $1.
(
if (( "$verbose" == 0 )); then
exec >/dev/null 2>&1
fi
"${COMPOSECMD[@]}" -f $COMPOSE_FILE build $1 || exit 1
"${COMPOSECMD[@]}" -f $COMPOSE_FILE run --rm $1 || exit 1
) || {
# Don't totally bail out, but make note of the failures.
failure=1
badproj="$badproj $1"
}
shift
done
if (( $failure )); then
echo "Failed to build$badproj."
fi
if [[ -d dist ]]; then
echo "Results in 'dist':"
ls -lt dist
else
echo "dist artifact directory not found."
fi
exit $failure